From webhook-mailer at python.org Mon Aug 1 01:06:20 2022 From: webhook-mailer at python.org (terryjreedy) Date: Mon, 01 Aug 2022 05:06:20 -0000 Subject: [Python-checkins] gh-95511: IDLE - fix Shell context menu copy-with-prompts bug (#95512) Message-ID: https://github.com/python/cpython/commit/fc31a13dc1799b8d972c1f4ea49f27090aed7f48 commit: fc31a13dc1799b8d972c1f4ea49f27090aed7f48 branch: main author: Terry Jan Reedy committer: terryjreedy date: 2022-08-01T01:06:13-04:00 summary: gh-95511: IDLE - fix Shell context menu copy-with-prompts bug (#95512) If one selects whole lines, as the sidebar makes easy, do not add an extra line. Only move the end of a selection to the beginning of the next line when not already at the beginning of a line. (Also improve the surrounding code.) files: A Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_sidebar.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index dc506dccfe99a..0e3a50bb63991 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,9 @@ Released on 2022-10-03 ========================= +gh-95511: Fix the Shell context menu copy-with-prompts bug of copying +an extra line when one selects whole lines. + gh-95471: Tweak Edit menu. Move 'Select All' above 'Cut' as it is used with 'Cut' and 'Copy' but not 'Paste'. Add a separator between 'Replace' and 'Go to Line' to help IDLE issue triagers. diff --git a/Lib/idlelib/idle_test/test_sidebar.py b/Lib/idlelib/idle_test/test_sidebar.py index 01fd6a04d0de3..290e037fe727a 100644 --- a/Lib/idlelib/idle_test/test_sidebar.py +++ b/Lib/idlelib/idle_test/test_sidebar.py @@ -733,7 +733,7 @@ def test_copy_with_prompts(self): first_line = get_end_linenumber(text) self.do_input(dedent('''\ if True: - print(1) + print(1) ''')) yield @@ -744,9 +744,10 @@ def test_copy_with_prompts(self): selected_lines_text = text.get('sel.first linestart', 'sel.last') selected_lines = selected_lines_text.split('\n') - # Expect a block of input, a single output line, and a new prompt + selected_lines.pop() # Final '' is a split artifact, not a line. + # Expect a block of input and a single output line. expected_prompts = \ - ['>>>'] + ['...'] * (len(selected_lines) - 3) + [None, '>>>'] + ['>>>'] + ['...'] * (len(selected_lines) - 2) + [None] selected_text_with_prompts = '\n'.join( line if prompt is None else prompt + ' ' + line for prompt, line in zip(expected_prompts, diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 2e54a81a1d38d..3806122962288 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -996,19 +996,17 @@ def copy_with_prompts_callback(self, event=None): and/or last lines is selected. """ text = self.text - - selection_indexes = ( - self.text.index("sel.first linestart"), - self.text.index("sel.last +1line linestart"), - ) - if selection_indexes[0] is None: - # There is no selection, so do nothing. - return - - selected_text = self.text.get(*selection_indexes) + selfirst = text.index('sel.first linestart') + if selfirst is None: # Should not be possible. + return # No selection, do nothing. + sellast = text.index('sel.last') + if sellast[-1] != '0': + sellast = text.index("sel.last+1line linestart") + + selected_text = self.text.get(selfirst, sellast) selection_lineno_range = range( - int(float(selection_indexes[0])), - int(float(selection_indexes[1])) + int(float(selfirst)), + int(float(sellast)) ) prompts = [ self.shell_sidebar.line_prompts.get(lineno) diff --git a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst new file mode 100644 index 0000000000000..803fa5f2a2ab0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst @@ -0,0 +1,2 @@ +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. From webhook-mailer at python.org Mon Aug 1 01:26:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 05:26:05 -0000 Subject: [Python-checkins] gh-95511: IDLE - fix Shell context menu copy-with-prompts bug (GH-95512) Message-ID: https://github.com/python/cpython/commit/4eab100e0dc764a5b85557aa30265066d1fde72e commit: 4eab100e0dc764a5b85557aa30265066d1fde72e branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-07-31T22:25:56-07:00 summary: gh-95511: IDLE - fix Shell context menu copy-with-prompts bug (GH-95512) If one selects whole lines, as the sidebar makes easy, do not add an extra line. Only move the end of a selection to the beginning of the next line when not already at the beginning of a line. (Also improve the surrounding code.) (cherry picked from commit fc31a13dc1799b8d972c1f4ea49f27090aed7f48) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_sidebar.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 3adf982579521..add0d8c6bead2 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,9 @@ Released 2023-04-03? ========================= +gh-95511: Fix the Shell context menu copy-with-prompts bug of copying +an extra line when one selects whole lines. + gh-95471: Tweak Edit menu. Move 'Select All' above 'Cut' as it is used with 'Cut' and 'Copy' but not 'Paste'. Add a separator between 'Replace' and 'Go to Line' to help IDLE issue triagers. diff --git a/Lib/idlelib/idle_test/test_sidebar.py b/Lib/idlelib/idle_test/test_sidebar.py index 01fd6a04d0de3..290e037fe727a 100644 --- a/Lib/idlelib/idle_test/test_sidebar.py +++ b/Lib/idlelib/idle_test/test_sidebar.py @@ -733,7 +733,7 @@ def test_copy_with_prompts(self): first_line = get_end_linenumber(text) self.do_input(dedent('''\ if True: - print(1) + print(1) ''')) yield @@ -744,9 +744,10 @@ def test_copy_with_prompts(self): selected_lines_text = text.get('sel.first linestart', 'sel.last') selected_lines = selected_lines_text.split('\n') - # Expect a block of input, a single output line, and a new prompt + selected_lines.pop() # Final '' is a split artifact, not a line. + # Expect a block of input and a single output line. expected_prompts = \ - ['>>>'] + ['...'] * (len(selected_lines) - 3) + [None, '>>>'] + ['>>>'] + ['...'] * (len(selected_lines) - 2) + [None] selected_text_with_prompts = '\n'.join( line if prompt is None else prompt + ' ' + line for prompt, line in zip(expected_prompts, diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 6c333b0bc3b81..ba33f581ea30f 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1005,19 +1005,17 @@ def copy_with_prompts_callback(self, event=None): and/or last lines is selected. """ text = self.text - - selection_indexes = ( - self.text.index("sel.first linestart"), - self.text.index("sel.last +1line linestart"), - ) - if selection_indexes[0] is None: - # There is no selection, so do nothing. - return - - selected_text = self.text.get(*selection_indexes) + selfirst = text.index('sel.first linestart') + if selfirst is None: # Should not be possible. + return # No selection, do nothing. + sellast = text.index('sel.last') + if sellast[-1] != '0': + sellast = text.index("sel.last+1line linestart") + + selected_text = self.text.get(selfirst, sellast) selection_lineno_range = range( - int(float(selection_indexes[0])), - int(float(selection_indexes[1])) + int(float(selfirst)), + int(float(sellast)) ) prompts = [ self.shell_sidebar.line_prompts.get(lineno) diff --git a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst new file mode 100644 index 0000000000000..803fa5f2a2ab0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst @@ -0,0 +1,2 @@ +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. From webhook-mailer at python.org Mon Aug 1 01:32:45 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 05:32:45 -0000 Subject: [Python-checkins] gh-95511: IDLE - fix Shell context menu copy-with-prompts bug (GH-95512) Message-ID: https://github.com/python/cpython/commit/e4541c474aa5a4e27c5d1078de4508fef018b302 commit: e4541c474aa5a4e27c5d1078de4508fef018b302 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-07-31T22:32:33-07:00 summary: gh-95511: IDLE - fix Shell context menu copy-with-prompts bug (GH-95512) If one selects whole lines, as the sidebar makes easy, do not add an extra line. Only move the end of a selection to the beginning of the next line when not already at the beginning of a line. (Also improve the surrounding code.) (cherry picked from commit fc31a13dc1799b8d972c1f4ea49f27090aed7f48) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_sidebar.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index dc506dccfe99a..0e3a50bb63991 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,9 @@ Released on 2022-10-03 ========================= +gh-95511: Fix the Shell context menu copy-with-prompts bug of copying +an extra line when one selects whole lines. + gh-95471: Tweak Edit menu. Move 'Select All' above 'Cut' as it is used with 'Cut' and 'Copy' but not 'Paste'. Add a separator between 'Replace' and 'Go to Line' to help IDLE issue triagers. diff --git a/Lib/idlelib/idle_test/test_sidebar.py b/Lib/idlelib/idle_test/test_sidebar.py index 01fd6a04d0de3..290e037fe727a 100644 --- a/Lib/idlelib/idle_test/test_sidebar.py +++ b/Lib/idlelib/idle_test/test_sidebar.py @@ -733,7 +733,7 @@ def test_copy_with_prompts(self): first_line = get_end_linenumber(text) self.do_input(dedent('''\ if True: - print(1) + print(1) ''')) yield @@ -744,9 +744,10 @@ def test_copy_with_prompts(self): selected_lines_text = text.get('sel.first linestart', 'sel.last') selected_lines = selected_lines_text.split('\n') - # Expect a block of input, a single output line, and a new prompt + selected_lines.pop() # Final '' is a split artifact, not a line. + # Expect a block of input and a single output line. expected_prompts = \ - ['>>>'] + ['...'] * (len(selected_lines) - 3) + [None, '>>>'] + ['>>>'] + ['...'] * (len(selected_lines) - 2) + [None] selected_text_with_prompts = '\n'.join( line if prompt is None else prompt + ' ' + line for prompt, line in zip(expected_prompts, diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 2e54a81a1d38d..3806122962288 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -996,19 +996,17 @@ def copy_with_prompts_callback(self, event=None): and/or last lines is selected. """ text = self.text - - selection_indexes = ( - self.text.index("sel.first linestart"), - self.text.index("sel.last +1line linestart"), - ) - if selection_indexes[0] is None: - # There is no selection, so do nothing. - return - - selected_text = self.text.get(*selection_indexes) + selfirst = text.index('sel.first linestart') + if selfirst is None: # Should not be possible. + return # No selection, do nothing. + sellast = text.index('sel.last') + if sellast[-1] != '0': + sellast = text.index("sel.last+1line linestart") + + selected_text = self.text.get(selfirst, sellast) selection_lineno_range = range( - int(float(selection_indexes[0])), - int(float(selection_indexes[1])) + int(float(selfirst)), + int(float(sellast)) ) prompts = [ self.shell_sidebar.line_prompts.get(lineno) diff --git a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst new file mode 100644 index 0000000000000..803fa5f2a2ab0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst @@ -0,0 +1,2 @@ +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. From webhook-mailer at python.org Mon Aug 1 05:15:11 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 01 Aug 2022 09:15:11 -0000 Subject: [Python-checkins] gh-95273: Clarify when sqlite_* attributes are added to sqlite3 exceptions (#95523) Message-ID: https://github.com/python/cpython/commit/1e6b63542e4856436c5c12148a6608ef9d148b71 commit: 1e6b63542e4856436c5c12148a6608ef9d148b71 branch: main author: Erlend Egeberg Aasland committer: erlend-aasland date: 2022-08-01T11:15:07+02:00 summary: gh-95273: Clarify when sqlite_* attributes are added to sqlite3 exceptions (#95523) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index a0b5c73d7a4ad..35eb404513b4d 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1320,6 +1320,9 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Use this to catch all errors with one single :keyword:`except` statement. ``Error`` is a subclass of :exc:`Exception`. + If the exception originated from within the SQLite library, + the following two attributes are added to the exception: + .. attribute:: sqlite_errorcode The numeric error code from the From webhook-mailer at python.org Mon Aug 1 05:22:17 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 09:22:17 -0000 Subject: [Python-checkins] gh-95273: Clarify when sqlite_* attributes are added to sqlite3 exceptions (GH-95523) Message-ID: https://github.com/python/cpython/commit/ad2872f5fd4fb145685007eaa03d90ae4505af69 commit: ad2872f5fd4fb145685007eaa03d90ae4505af69 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T02:22:09-07:00 summary: gh-95273: Clarify when sqlite_* attributes are added to sqlite3 exceptions (GH-95523) (cherry picked from commit 1e6b63542e4856436c5c12148a6608ef9d148b71) Co-authored-by: Erlend Egeberg Aasland files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 332e3b0b79a1e..e150baad3ef7f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1310,6 +1310,9 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Use this to catch all errors with one single :keyword:`except` statement. ``Error`` is a subclass of :exc:`Exception`. + If the exception originated from within the SQLite library, + the following two attributes are added to the exception: + .. attribute:: sqlite_errorcode The numeric error code from the From webhook-mailer at python.org Mon Aug 1 06:25:47 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 01 Aug 2022 10:25:47 -0000 Subject: [Python-checkins] gh-77617: Add sqlite3 command-line interface (#95026) Message-ID: https://github.com/python/cpython/commit/bc7c7cd18a4ae015449f95454a762a7276585bb8 commit: bc7c7cd18a4ae015449f95454a762a7276585bb8 branch: main author: Erlend Egeberg Aasland committer: erlend-aasland date: 2022-08-01T12:25:16+02:00 summary: gh-77617: Add sqlite3 command-line interface (#95026) Co-authored-by: Serhiy Storchaka files: A Lib/sqlite3/__main__.py A Lib/test/test_sqlite3/test_cli.py A Misc/NEWS.d/next/Library/2022-07-20-00-23-58.gh-issue-77617.XGaqSQ.rst M Doc/library/sqlite3.rst M Doc/whatsnew/3.12.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 35eb404513b4d..28bd7ce900b53 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1442,6 +1442,26 @@ and you can let the ``sqlite3`` module convert SQLite types to Python types via :ref:`converters `. +.. _sqlite3-cli: + +Command-line interface +^^^^^^^^^^^^^^^^^^^^^^ + +The ``sqlite3`` module can be invoked as a script +in order to provide a simple SQLite shell. +Type ``.quit`` or CTRL-D to exit the shell. + +.. program:: python -m sqlite3 [-h] [-v] [filename] [sql] + +.. option:: -h, --help + Print CLI help. + +.. option:: -v, --version + Print underlying SQLite library version. + +.. versionadded:: 3.12 + + .. _sqlite3-howtos: How-to guides diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 0c53bc0c1111d..67396f8e02280 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -112,6 +112,13 @@ os (Contributed by Kumar Aditya in :gh:`93312`.) +sqlite3 +------- + +* Add a :ref:`command-line interface `. + (Contributed by Erlend E. Aasland in :gh:`77617`.) + + Optimizations ============= diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py new file mode 100644 index 0000000000000..c62fad84e74bb --- /dev/null +++ b/Lib/sqlite3/__main__.py @@ -0,0 +1,97 @@ +import sqlite3 +import sys + +from argparse import ArgumentParser +from code import InteractiveConsole +from textwrap import dedent + + +def execute(c, sql, suppress_errors=True): + try: + for row in c.execute(sql): + print(row) + except sqlite3.Error as e: + tp = type(e).__name__ + try: + print(f"{tp} ({e.sqlite_errorname}): {e}", file=sys.stderr) + except AttributeError: + print(f"{tp}: {e}", file=sys.stderr) + if not suppress_errors: + sys.exit(1) + + +class SqliteInteractiveConsole(InteractiveConsole): + + def __init__(self, connection): + super().__init__() + self._con = connection + self._cur = connection.cursor() + + def runsource(self, source, filename="", symbol="single"): + match source: + case ".version": + print(f"{sqlite3.sqlite_version}") + case ".help": + print("Enter SQL code and press enter.") + case ".quit": + sys.exit(0) + case _: + if not sqlite3.complete_statement(source): + return True + execute(self._cur, source) + return False + + +def main(): + parser = ArgumentParser( + description="Python sqlite3 CLI", + prog="python -m sqlite3", + ) + parser.add_argument( + "filename", type=str, default=":memory:", nargs="?", + help=( + "SQLite database to open (defaults to ':memory:'). " + "A new database is created if the file does not previously exist." + ), + ) + parser.add_argument( + "sql", type=str, nargs="?", + help=( + "An SQL query to execute. " + "Any returned rows are printed to stdout." + ), + ) + parser.add_argument( + "-v", "--version", action="version", + version=f"SQLite version {sqlite3.sqlite_version}", + help="Print underlying SQLite library version", + ) + args = parser.parse_args() + + if args.filename == ":memory:": + db_name = "a transient in-memory database" + else: + db_name = repr(args.filename) + + banner = dedent(f""" + sqlite3 shell, running on SQLite version {sqlite3.sqlite_version} + Connected to {db_name} + + Each command will be run using execute() on the cursor. + Type ".help" for more information; type ".quit" or CTRL-D to quit. + """).strip() + sys.ps1 = "sqlite> " + sys.ps2 = " ... " + + con = sqlite3.connect(args.filename, isolation_level=None) + try: + if args.sql: + execute(con, args.sql, suppress_errors=False) + else: + console = SqliteInteractiveConsole(con) + console.interact(banner, exitmsg="") + finally: + con.close() + + +main() diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py new file mode 100644 index 0000000000000..d374f8ee4fc8d --- /dev/null +++ b/Lib/test/test_sqlite3/test_cli.py @@ -0,0 +1,155 @@ +"""sqlite3 CLI tests.""" + +import sqlite3 as sqlite +import subprocess +import sys +import unittest + +from test.support import SHORT_TIMEOUT, requires_subprocess +from test.support.os_helper import TESTFN, unlink + + + at requires_subprocess() +class CommandLineInterface(unittest.TestCase): + + def _do_test(self, *args, expect_success=True): + with subprocess.Popen( + [sys.executable, "-Xutf8", "-m", "sqlite3", *args], + encoding="utf-8", + bufsize=0, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as proc: + proc.wait() + if expect_success == bool(proc.returncode): + self.fail("".join(proc.stderr)) + stdout = proc.stdout.read() + stderr = proc.stderr.read() + if expect_success: + self.assertEqual(stderr, "") + else: + self.assertEqual(stdout, "") + return stdout, stderr + + def expect_success(self, *args): + out, _ = self._do_test(*args) + return out + + def expect_failure(self, *args): + _, err = self._do_test(*args, expect_success=False) + return err + + def test_cli_help(self): + out = self.expect_success("-h") + self.assertIn("usage: python -m sqlite3", out) + + def test_cli_version(self): + out = self.expect_success("-v") + self.assertIn(sqlite.sqlite_version, out) + + def test_cli_execute_sql(self): + out = self.expect_success(":memory:", "select 1") + self.assertIn("(1,)", out) + + def test_cli_execute_too_much_sql(self): + stderr = self.expect_failure(":memory:", "select 1; select 2") + err = "ProgrammingError: You can only execute one statement at a time" + self.assertIn(err, stderr) + + def test_cli_execute_incomplete_sql(self): + stderr = self.expect_failure(":memory:", "sel") + self.assertIn("OperationalError (SQLITE_ERROR)", stderr) + + def test_cli_on_disk_db(self): + self.addCleanup(unlink, TESTFN) + out = self.expect_success(TESTFN, "create table t(t)") + self.assertEqual(out, "") + out = self.expect_success(TESTFN, "select count(t) from t") + self.assertIn("(0,)", out) + + + at requires_subprocess() +class InteractiveSession(unittest.TestCase): + TIMEOUT = SHORT_TIMEOUT / 10. + MEMORY_DB_MSG = "Connected to a transient in-memory database" + PS1 = "sqlite> " + PS2 = "... " + + def start_cli(self, *args): + return subprocess.Popen( + [sys.executable, "-Xutf8", "-m", "sqlite3", *args], + encoding="utf-8", + bufsize=0, + stdin=subprocess.PIPE, + # Note: the banner is printed to stderr, the prompt to stdout. + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + + def expect_success(self, proc): + proc.wait() + if proc.returncode: + self.fail("".join(proc.stderr)) + + def test_interact(self): + with self.start_cli() as proc: + out, err = proc.communicate(timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS1, out) + self.expect_success(proc) + + def test_interact_quit(self): + with self.start_cli() as proc: + out, err = proc.communicate(input=".quit", timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS1, out) + self.expect_success(proc) + + def test_interact_version(self): + with self.start_cli() as proc: + out, err = proc.communicate(input=".version", timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(sqlite.sqlite_version, out) + self.expect_success(proc) + + def test_interact_valid_sql(self): + with self.start_cli() as proc: + out, err = proc.communicate(input="select 1;", + timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("(1,)", out) + self.expect_success(proc) + + def test_interact_valid_multiline_sql(self): + with self.start_cli() as proc: + out, err = proc.communicate(input="select 1\n;", + timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS2, out) + self.assertIn("(1,)", out) + self.expect_success(proc) + + def test_interact_invalid_sql(self): + with self.start_cli() as proc: + out, err = proc.communicate(input="sel;", timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("OperationalError (SQLITE_ERROR)", err) + self.expect_success(proc) + + def test_interact_on_disk_file(self): + self.addCleanup(unlink, TESTFN) + with self.start_cli(TESTFN) as proc: + out, err = proc.communicate(input="create table t(t);", + timeout=self.TIMEOUT) + self.assertIn(TESTFN, err) + self.assertIn(self.PS1, out) + self.expect_success(proc) + with self.start_cli(TESTFN, "select count(t) from t") as proc: + out = proc.stdout.read() + err = proc.stderr.read() + self.assertIn("(0,)", out) + self.expect_success(proc) + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-07-20-00-23-58.gh-issue-77617.XGaqSQ.rst b/Misc/NEWS.d/next/Library/2022-07-20-00-23-58.gh-issue-77617.XGaqSQ.rst new file mode 100644 index 0000000000000..1cbaa7dfe15ec --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-20-00-23-58.gh-issue-77617.XGaqSQ.rst @@ -0,0 +1,2 @@ +Add :mod:`sqlite3` :ref:`command-line interface `. +Patch by Erlend Aasland. From webhook-mailer at python.org Mon Aug 1 08:26:29 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 01 Aug 2022 12:26:29 -0000 Subject: [Python-checkins] [3.11] gh-95415: Make availability directive consistent (GH-95416) (GH-95438) Message-ID: https://github.com/python/cpython/commit/9af9ea28e756a8a1961b065856c697fc1262ca82 commit: 9af9ea28e756a8a1961b065856c697fc1262ca82 branch: 3.11 author: Christian Heimes committer: tiran date: 2022-08-01T14:26:19+02:00 summary: [3.11] gh-95415: Make availability directive consistent (GH-95416) (GH-95438) Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst M Doc/library/_thread.rst M Doc/library/codecs.rst M Doc/library/crypt.rst M Doc/library/intro.rst M Doc/library/os.rst M Doc/library/pipes.rst M Doc/library/resource.rst M Doc/library/signal.rst M Doc/library/socket.rst M Doc/library/ssl.rst M Doc/library/subprocess.rst M Doc/library/sys.rst M Doc/library/threading.rst M Doc/library/time.rst M Doc/tools/extensions/pyspecific.py M Doc/using/cmdline.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 1e6452b7b826f..ea4aa304bec0f 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -140,7 +140,9 @@ This module defines the following constants and functions: information (4 KiB pages are common; using multiples of 4096 for the stack size is the suggested approach in the absence of more specific information). - .. availability:: Windows, systems with POSIX threads. + .. availability:: Windows, pthreads. + + Unix platforms with POSIX threads support. .. data:: TIMEOUT_MAX diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index d131408175fd1..4a665f2254f8a 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -1530,7 +1530,7 @@ functions can be used directly if desired. This module implements the ANSI codepage (CP_ACP). -.. availability:: Windows only. +.. availability:: Windows. .. versionchanged:: 3.3 Support any error handler. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index efba4236bcbcc..f585bbcbc18b8 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -36,7 +36,7 @@ the :manpage:`crypt(3)` routine in the running system. Therefore, any extensions available on the current implementation will also be available on this module. -.. availability:: Unix. Not available on VxWorks. +.. availability:: Unix, not VxWorks. Hashing Methods --------------- diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 5bb33b9c10cc0..120b174dc3b1e 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -60,3 +60,7 @@ Notes on availability * If not separately noted, all functions that claim "Availability: Unix" are supported on macOS, which builds on a Unix core. +* If an availability note contains both a minimum Kernel version and a minimum + libc version, then both conditions must hold. For example a feature with note + *Availability: Linux >= 3.17 with glibc >= 2.27* requires both Linux 3.17 or + newer and glibc 2.27 or newer. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 43991a3252fe0..de6f27c5d32d1 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -301,7 +301,7 @@ process and user. and ``'surrogateescape'`` error handler. Use :func:`os.getenvb` if you would like to use a different encoding. - .. availability:: most flavors of Unix, Windows. + .. availability:: Unix, Windows. .. function:: getenvb(key, default=None) @@ -316,7 +316,7 @@ process and user. :func:`getenvb` is only available if :data:`supports_bytes_environ` is ``True``. - .. availability:: most flavors of Unix. + .. availability:: Unix. .. versionadded:: 3.2 @@ -706,7 +706,7 @@ process and user. :func:`socket.gethostname` or even ``socket.gethostbyaddr(socket.gethostname())``. - .. availability:: recent flavors of Unix. + .. availability:: Unix. .. versionchanged:: 3.3 Return type changed from a tuple to a tuple-like object @@ -810,7 +810,7 @@ as internal buffering of data. The return value is the amount of bytes copied. This could be less than the amount requested. - .. availability:: Linux kernel >= 4.5 or glibc >= 2.27. + .. availability:: Linux >= 4.5 with glibc >= 2.27. .. versionadded:: 3.8 @@ -1150,7 +1150,7 @@ or `the MSDN `_ on Windo descriptors are :ref:`non-inheritable `. For a (slightly) more portable approach, use the :mod:`pty` module. - .. availability:: some flavors of Unix. + .. availability:: Unix. .. versionchanged:: 3.4 The new file descriptors are now non-inheritable. @@ -1176,7 +1176,7 @@ or `the MSDN `_ on Windo Return a pair of file descriptors ``(r, w)`` usable for reading and writing, respectively. - .. availability:: some flavors of Unix. + .. availability:: Unix. .. versionadded:: 3.3 @@ -1255,9 +1255,9 @@ or `the MSDN `_ on Windo Combine the functionality of :func:`os.readv` and :func:`os.pread`. - .. availability:: Linux 2.6.30 and newer, FreeBSD 6.0 and newer, - OpenBSD 2.7 and newer, AIX 7.1 and newer. Using flags requires - Linux 4.6 or newer. + .. availability:: Linux >= 2.6.30, FreeBSD >= 6.0, OpenBSD >= 2.7, AIX >= 7.1. + + Using flags requires Linux >= 4.6. .. versionadded:: 3.7 @@ -1272,7 +1272,7 @@ or `the MSDN `_ on Windo If no bytes were read, it will return ``-1`` and set errno to :data:`errno.EAGAIN`. - .. availability:: Linux 4.14 and newer. + .. availability:: Linux >= 4.14. .. versionadded:: 3.7 @@ -1286,7 +1286,7 @@ or `the MSDN `_ on Windo Currently, on Linux, this feature is usable only on a file descriptor opened using the :data:`O_DIRECT` flag. - .. availability:: Linux 4.6 and newer. + .. availability:: Linux >= 4.6. .. versionadded:: 3.7 @@ -1325,9 +1325,9 @@ or `the MSDN `_ on Windo Combine the functionality of :func:`os.writev` and :func:`os.pwrite`. - .. availability:: Linux 2.6.30 and newer, FreeBSD 6.0 and newer, - OpenBSD 2.7 and newer, AIX 7.1 and newer. Using flags requires - Linux 4.7 or newer. + .. availability:: Linux >= 2.6.30, FreeBSD >= 6.0, OpenBSD >= 2.7, AIX >= 7.1. + + Using flags requires Linux >= 4.6. .. versionadded:: 3.7 @@ -1337,7 +1337,7 @@ or `the MSDN `_ on Windo Provide a per-write equivalent of the :data:`O_DSYNC` :func:`os.open` flag. This flag effect applies only to the data range written by the system call. - .. availability:: Linux 4.7 and newer. + .. availability:: Linux >= 4.7. .. versionadded:: 3.7 @@ -1347,7 +1347,7 @@ or `the MSDN `_ on Windo Provide a per-write equivalent of the :data:`O_SYNC` :func:`os.open` flag. This flag effect applies only to the data range written by the system call. - .. availability:: Linux 4.7 and newer. + .. availability:: Linux >= 4.7. .. versionadded:: 3.7 @@ -1361,7 +1361,7 @@ or `the MSDN `_ on Windo appended to the end of the file. However, if the *offset* argument is ``-1``, the current file *offset* is updated. - .. availability:: Linux 4.16 and newer. + .. availability:: Linux >= 4.16. .. versionadded:: 3.10 @@ -1481,7 +1481,7 @@ or `the MSDN `_ on Windo make sense to block because there are no writers connected to the write end of the pipe. - .. availability:: Linux kernel >= 2.6.17 and glibc >= 2.5 + .. availability:: Linux >= 2.6.17 with glibc >= 2.5 .. versionadded:: 3.10 @@ -3320,7 +3320,7 @@ features: the file descriptor, and as such multiple files can have the same name without any side effects. - .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. + .. availability:: Linux >= 3.17 with glibc >= 2.27. .. versionadded:: 3.8 @@ -3345,8 +3345,9 @@ features: These flags can be passed to :func:`memfd_create`. - .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. The - ``MFD_HUGE*`` flags are only available since Linux 4.14. + .. availability:: Linux >= 3.17 with glibc >= 2.27 + + The ``MFD_HUGE*`` flags are only available since Linux 4.14. .. versionadded:: 3.8 @@ -3398,7 +3399,7 @@ features: finally: os.close(fd) - .. availability:: Linux 2.6.27 or newer with glibc 2.8 or newer. + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 .. versionadded:: 3.10 @@ -3407,7 +3408,7 @@ features: Read value from an :func:`eventfd` file descriptor and return a 64 bit unsigned int. The function does not verify that *fd* is an :func:`eventfd`. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3416,7 +3417,7 @@ features: Add value to an :func:`eventfd` file descriptor. *value* must be a 64 bit unsigned int. The function does not verify that *fd* is an :func:`eventfd`. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3424,7 +3425,7 @@ features: Set close-on-exec flag for new :func:`eventfd` file descriptor. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3433,7 +3434,7 @@ features: Set :const:`O_NONBLOCK` status flag for new :func:`eventfd` file descriptor. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3442,7 +3443,7 @@ features: Provide semaphore-like semantics for reads from a :func:`eventfd` file descriptor. On read the internal counter is decremented by one. - .. availability:: Linux 2.6.30 or newer with glibc 2.8 or newer. + .. availability:: Linux >= 2.6.30 .. versionadded:: 3.10 @@ -3847,7 +3848,7 @@ written in Python, such as a mail server's external command delivery program. Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. availability:: some flavors of Unix. + .. availability:: Unix. .. function:: kill(pid, sig) @@ -3904,7 +3905,7 @@ written in Python, such as a mail server's external command delivery program. See the :manpage:`pidfd_open(2)` man page for more details. - .. availability:: Linux 5.3+ + .. availability:: Linux >= 5.3 .. versionadded:: 3.9 @@ -4054,7 +4055,9 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: See :func:`posix_spawn` documentation. + .. availability:: POSIX + + See :func:`posix_spawn` documentation. .. function:: register_at_fork(*, before=None, after_in_parent=None, \ @@ -4154,7 +4157,9 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.spawn mode,path,args,env os.spawnl - .. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` + .. availability:: Unix, Windows. + + :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and :func:`spawnve` are not thread-safe on Windows; we advise you to use the :mod:`subprocess` module instead. @@ -4358,7 +4363,7 @@ written in Python, such as a mail server's external command delivery program. This is a Linux-specific *idtype* that indicates that *id* is a file descriptor that refers to a process. - .. availability:: Linux 5.4+ + .. availability:: Linux >= 5.4 .. versionadded:: 3.9 @@ -4500,7 +4505,9 @@ written in Python, such as a mail server's external command delivery program. This option causes child processes to be reported if they have been continued from a job control stop since their status was last reported. - .. availability:: some Unix systems. + .. availability:: Unix. + + Some Unix systems. .. data:: WUNTRACED @@ -4906,7 +4913,7 @@ Random numbers See also the `Linux getrandom() manual page `_. - .. availability:: Linux 3.17 and newer. + .. availability:: Linux >= 3.17. .. versionadded:: 3.6 diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst index 245dd0d252088..471ae0dbc9768 100644 --- a/Doc/library/pipes.rst +++ b/Doc/library/pipes.rst @@ -23,7 +23,7 @@ The :mod:`pipes` module defines a class to abstract the concept of a *pipeline* Because the module uses :program:`/bin/sh` command lines, a POSIX or compatible shell for :func:`os.system` and :func:`os.popen` is required. -.. availability:: Unix. Not available on VxWorks. +.. availability:: Unix, not VxWorks. The :mod:`pipes` module defines the following class: diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 67e9b44fe48c4..7c9c5a0819b0a 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -99,7 +99,7 @@ this module for those platforms. .. audit-event:: resource.prlimit pid,resource,limits resource.prlimit - .. availability:: Linux 2.6.36 or later with glibc 2.13 or later. + .. availability:: Linux >= 2.6.36 with glibc >= 2.13. .. versionadded:: 3.4 @@ -185,7 +185,7 @@ platform. The number of bytes that can be allocated for POSIX message queues. - .. availability:: Linux 2.6.8 or later. + .. availability:: Linux >= 2.6.8. .. versionadded:: 3.4 @@ -194,7 +194,7 @@ platform. The ceiling for the process's nice level (calculated as 20 - rlim_cur). - .. availability:: Linux 2.6.12 or later. + .. availability:: Linux >= 2.6.12. .. versionadded:: 3.4 @@ -203,7 +203,7 @@ platform. The ceiling of the real-time priority. - .. availability:: Linux 2.6.12 or later. + .. availability:: Linux >= 2.6.12. .. versionadded:: 3.4 @@ -213,7 +213,7 @@ platform. The time limit (in microseconds) on CPU time that a process can spend under real-time scheduling without making a blocking syscall. - .. availability:: Linux 2.6.25 or later. + .. availability:: Linux >= 2.6.25. .. versionadded:: 3.4 @@ -222,7 +222,7 @@ platform. The number of signals which the process may queue. - .. availability:: Linux 2.6.8 or later. + .. availability:: Linux >= 2.6.8. .. versionadded:: 3.4 @@ -232,7 +232,7 @@ platform. This limits the amount of network memory, and hence the amount of mbufs, that this user may hold at any time. - .. availability:: FreeBSD 9 or later. + .. availability:: FreeBSD. .. versionadded:: 3.4 @@ -245,7 +245,7 @@ platform. `tuning(7) `__ for a complete description of this sysctl. - .. availability:: FreeBSD 9 or later. + .. availability:: FreeBSD. .. versionadded:: 3.4 @@ -253,7 +253,7 @@ platform. The maximum number of pseudo-terminals created by this user id. - .. availability:: FreeBSD 9 or later. + .. availability:: FreeBSD. .. versionadded:: 3.4 @@ -261,7 +261,7 @@ platform. The maximum number of kqueues this user id is allowed to create. - .. availability:: FreeBSD 11 or later. + .. availability:: FreeBSD >= 11. .. versionadded:: 3.10 diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index d850639d242ab..72b8f03fc16df 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -95,8 +95,10 @@ The signal module defines three enums: :class:`enum.IntEnum` collection the constants :const:`SIG_BLOCK`, :const:`SIG_UNBLOCK` and :const:`SIG_SETMASK`. - Availability: Unix. See the man page :manpage:`sigprocmask(2)` and - :manpage:`pthread_sigmask(3)` for further information. + .. availability:: Unix. + + See the man page :manpage:`sigprocmask(2)` and + :manpage:`pthread_sigmask(3)` for further information. .. versionadded:: 3.5 @@ -205,7 +207,9 @@ The variables defined in the :mod:`signal` module are: Stack fault on coprocessor. The Linux kernel does not raise this signal: it can only be raised in user space. - .. availability:: Linux, on architectures where the signal is available. See + .. availability:: Linux. + + On architectures where the signal is available. See the man page :manpage:`signal(7)` for further information. .. versionadded:: 3.11 @@ -337,8 +341,9 @@ The :mod:`signal` module defines the following functions: delivered. If *time* is zero, no alarm is scheduled, and any scheduled alarm is canceled. If the return value is zero, no alarm is currently scheduled. - .. availability:: Unix. See the man page :manpage:`alarm(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`alarm(2)` for further information. .. function:: getsignal(signalnum) @@ -375,8 +380,9 @@ The :mod:`signal` module defines the following functions: Cause the process to sleep until a signal is received; the appropriate handler will then be called. Returns nothing. - .. availability:: Unix. See the man page :manpage:`signal(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`signal(2)` for further information. See also :func:`sigwait`, :func:`sigwaitinfo`, :func:`sigtimedwait` and :func:`sigpending`. @@ -398,7 +404,7 @@ The :mod:`signal` module defines the following functions: See the :manpage:`pidfd_send_signal(2)` man page for more information. - .. availability:: Linux 5.1+ + .. availability:: Linux >= 5.1 .. versionadded:: 3.9 @@ -421,8 +427,9 @@ The :mod:`signal` module defines the following functions: .. audit-event:: signal.pthread_kill thread_id,signalnum signal.pthread_kill - .. availability:: Unix. See the man page :manpage:`pthread_kill(3)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`pthread_kill(3)` for further information. See also :func:`os.kill`. @@ -454,7 +461,9 @@ The :mod:`signal` module defines the following functions: :data:`SIGKILL` and :data:`SIGSTOP` cannot be blocked. - .. availability:: Unix. See the man page :manpage:`sigprocmask(2)` 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`. @@ -542,8 +551,9 @@ The :mod:`signal` module defines the following functions: calls will be restarted when interrupted by signal *signalnum*, otherwise system calls will be interrupted. Returns nothing. - .. availability:: Unix. See the man page :manpage:`siginterrupt(3)` - for further information. + .. availability:: Unix. + + See the man page :manpage:`siginterrupt(3)` for further information. Note that installing a signal handler with :func:`signal` will reset the restart behaviour to interruptible by implicitly calling @@ -583,8 +593,9 @@ The :mod:`signal` module defines the following functions: thread (i.e., the signals which have been raised while blocked). Return the set of the pending signals. - .. availability:: Unix. See the man page :manpage:`sigpending(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigpending(2)` for further information. See also :func:`pause`, :func:`pthread_sigmask` and :func:`sigwait`. @@ -597,8 +608,9 @@ The :mod:`signal` module defines the following functions: signals specified in the signal set *sigset*. The function accepts the signal (removes it from the pending list of signals), and returns the signal number. - .. availability:: Unix. See the man page :manpage:`sigwait(3)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigwait(3)` for further information. See also :func:`pause`, :func:`pthread_sigmask`, :func:`sigpending`, :func:`sigwaitinfo` and :func:`sigtimedwait`. @@ -622,8 +634,9 @@ The :mod:`signal` module defines the following functions: :attr:`si_errno`, :attr:`si_pid`, :attr:`si_uid`, :attr:`si_status`, :attr:`si_band`. - .. availability:: Unix. See the man page :manpage:`sigwaitinfo(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigwaitinfo(2)` for further information. See also :func:`pause`, :func:`sigwait` and :func:`sigtimedwait`. @@ -641,8 +654,9 @@ The :mod:`signal` module defines the following functions: specifying a timeout. If *timeout* is specified as :const:`0`, a poll is performed. Returns :const:`None` if a timeout occurs. - .. availability:: Unix. See the man page :manpage:`sigtimedwait(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigtimedwait(2)` for further information. See also :func:`pause`, :func:`sigwait` and :func:`sigwaitinfo`. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index f77279cd8812b..f35df364a346f 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -165,7 +165,9 @@ created. Socket addresses are represented as follows: - *feat* and *mask* are unsigned 32bit integers. - .. availability:: Linux 2.6.38, some algorithm types require more recent Kernels. + .. availability:: Linux >= 2.6.38. + + Some algorithm types require more recent Kernels. .. versionadded:: 3.6 @@ -173,7 +175,9 @@ created. Socket addresses are represented as follows: their hosts. The sockets are represented as a ``(CID, port)`` tuple where the context ID or CID and port are integers. - .. availability:: Linux >= 4.8 QEMU >= 2.8 ESX >= 4.0 ESX Workstation >= 6.5. + .. availability:: Linux >= 3.9 + + See :manpage:`vsock(7)` .. versionadded:: 3.7 @@ -221,7 +225,7 @@ created. Socket addresses are represented as follows: ``socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)`` for IPv4 or ``socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE)`` for IPv6. - .. availability:: Linux >= 2.6.20, FreeBSD >= 10.1-RELEASE + .. availability:: Linux >= 2.6.20, FreeBSD >= 10.1 .. versionadded:: 3.9 @@ -1033,7 +1037,7 @@ The :mod:`socket` module also offers various network-related services: both the value of *address_family* and the underlying implementation of :c:func:`inet_pton`. - .. availability:: Unix (maybe not all platforms), Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.4 Windows support added @@ -1053,7 +1057,7 @@ The :mod:`socket` module also offers various network-related services: length for the specified address family, :exc:`ValueError` will be raised. :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. - .. availability:: Unix (maybe not all platforms), Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.4 Windows support added @@ -1079,7 +1083,9 @@ The :mod:`socket` module also offers various network-related services: buffer. Raises :exc:`OverflowError` if *length* is outside the permissible range of values. - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + Most Unix platforms. .. versionadded:: 3.3 @@ -1100,7 +1106,9 @@ The :mod:`socket` module also offers various network-related services: amount of ancillary data that can be received, since additional data may be able to fit into the padding area. - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + most Unix platforms. .. versionadded:: 3.3 @@ -1199,7 +1207,10 @@ The :mod:`socket` module also offers various network-related services: The *fds* parameter is a sequence of file descriptors. Consult :meth:`sendmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. + .. availability:: Unix. + + Unix platforms supporting :meth:`~socket.sendmsg` + and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 @@ -1210,7 +1221,10 @@ The :mod:`socket` module also offers various network-related services: Return ``(msg, list(fds), flags, addr)``. Consult :meth:`recvmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:`~socket.recvmsg` and :const:`SCM_RIGHTS` mechanism. + .. availability:: Unix. + + Unix platforms supporting :meth:`~socket.sendmsg` + and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 @@ -1545,7 +1559,9 @@ to sockets. fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds) - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + Most Unix platforms. .. versionadded:: 3.3 @@ -1587,7 +1603,9 @@ to sockets. >>> [b1, b2, b3] [bytearray(b'Mary'), bytearray(b'01 had a 9'), bytearray(b'little lamb---')] - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + Most Unix platforms. .. versionadded:: 3.3 @@ -1693,7 +1711,9 @@ to sockets. def send_fds(sock, msg, fds): return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))]) - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + Most Unix platforms. .. audit-event:: socket.sendmsg self,address socket.socket.sendmsg diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 7e26e2ec6f19d..dd6d243734a3b 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -474,9 +474,6 @@ Certificate handling * :attr:`openssl_capath_env` - OpenSSL's environment key that points to a capath, * :attr:`openssl_capath` - hard coded path to a capath directory - .. availability:: LibreSSL ignores the environment vars - :attr:`openssl_cafile_env` and :attr:`openssl_capath_env`. - .. versionadded:: 3.4 .. function:: enum_certificates(store_name) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 0a996feb22cef..fae81f8ac28ff 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -1473,7 +1473,7 @@ handling consistency are valid for these functions. >>> subprocess.getstatusoutput('/bin/kill $$') (-15, '') - .. availability:: POSIX & Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.3.4 Windows support was added. @@ -1495,7 +1495,7 @@ handling consistency are valid for these functions. >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' - .. availability:: POSIX & Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.3.4 Windows support added diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 1ac529ada1ce8..d3e569c6de3c6 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -338,7 +338,7 @@ always available. | | memory support. | +-----------------------------+----------------------------------------------+ - .. availability:: WebAssembly Emscripten platform (*wasm32-emscripten*). + .. availability:: Emscripten. .. versionadded:: 3.11 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index e654dedfd91a2..cc266fa323be3 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -192,7 +192,9 @@ This module defines the following functions: information (4 KiB pages are common; using multiples of 4096 for the stack size is the suggested approach in the absence of more specific information). - .. availability:: Windows, systems with POSIX threads. + .. availability:: Windows, pthreads. + + Unix platforms with POSIX threads support. This module also defines the following constant: @@ -429,7 +431,7 @@ since it is impossible to detect the termination of alien threads. system-wide) from the time the thread is created until the thread has been terminated. - .. availability:: Requires :func:`get_native_id` function. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. .. versionadded:: 3.8 diff --git a/Doc/library/time.rst b/Doc/library/time.rst index be17fa68eb7b5..9f23a6fc7d534 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -144,8 +144,10 @@ Functions Passing an invalid or expired *thread_id* may result in undefined behavior, such as segmentation fault. - .. availability:: Unix (see the man page for :manpage:`pthread_getcpuclockid(3)` for - further information). + .. availability:: Unix + + See the man page for :manpage:`pthread_getcpuclockid(3)` for + further information. .. versionadded:: 3.7 @@ -651,8 +653,9 @@ Functions Use :func:`thread_time_ns` to avoid the precision loss caused by the :class:`float` type. - .. availability:: Windows, Linux, Unix systems supporting - ``CLOCK_THREAD_CPUTIME_ID``. + .. availability:: Linux, Unix, Windows. + + Unix systems supporting ``CLOCK_THREAD_CPUTIME_ID``. .. versionadded:: 3.7 @@ -770,7 +773,7 @@ These constants are used as parameters for :func:`clock_getres` and have discontinuities if the time is changed using ``settimeofday()`` or similar. - .. availability:: Linux 2.6.39 or later. + .. availability:: Linux >= 2.6.39. .. versionadded:: 3.7 @@ -801,7 +804,7 @@ These constants are used as parameters for :func:`clock_getres` and Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw hardware-based time that is not subject to NTP adjustments. - .. availability:: Linux 2.6.28 and newer, macOS 10.12 and newer. + .. availability:: Linux >= 2.6.28, macOS >= 10.12. .. versionadded:: 3.3 @@ -819,7 +822,7 @@ These constants are used as parameters for :func:`clock_getres` and High-resolution per-process timer from the CPU. - .. availability:: FreeBSD, NetBSD 7 or later, OpenBSD. + .. availability:: FreeBSD, NetBSD >= 7, OpenBSD. .. versionadded:: 3.7 @@ -849,7 +852,7 @@ These constants are used as parameters for :func:`clock_getres` and suspended, providing accurate uptime measurement, both absolute and interval. - .. availability:: FreeBSD, OpenBSD 5.5 or later. + .. availability:: FreeBSD, OpenBSD >= 5.5. .. versionadded:: 3.7 @@ -860,7 +863,7 @@ These constants are used as parameters for :func:`clock_getres` and point, unaffected by frequency or time adjustments and not incremented while the system is asleep. - .. availability:: macOS 10.12 and newer. + .. availability:: macOS >= 10.12. .. versionadded:: 3.8 diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 9f8446ce52891..a795e05b8b98d 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -135,11 +135,22 @@ def run(self): class Availability(Directive): - has_content = False + has_content = True required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True + # known platform, libc, and threading implementations + known_platforms = frozenset({ + "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", + "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", "Unix", "VxWorks", + "WASI", "Windows", "macOS", + # libc + "BSD libc", "glibc", "musl", + # POSIX platforms with pthreads + "pthreads", + }) + def run(self): availability_ref = ':ref:`Availability `: ' pnode = nodes.paragraph(availability_ref + self.arguments[0], @@ -148,8 +159,53 @@ def run(self): pnode.extend(n + m) n, m = self.state.inline_text(self.arguments[0], self.lineno) pnode.extend(n + m) + if self.content: + content = " " + " ".join(self.content) + n, m = self.state.inline_text(content, self.content_offset) + pnode.extend(n + m) + + self.parse_platforms() + return [pnode] + def parse_platforms(self): + """Parse platform information from arguments + + Arguments is a comma-separated string of platforms. A platform may + be prefixed with "not " to indicate that a feature is not available. + + Example:: + + .. availability:: Windows, Linux >= 4.2, not Emscripten, not WASI + + Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not + parsed into separate tokens. + """ + platforms = {} + for arg in self.arguments[0].rstrip(".").split(","): + arg = arg.strip() + platform, _, version = arg.partition(" >= ") + if platform.startswith("not "): + version = False + platform = platform[4:] + elif not version: + version = True + platforms[platform] = version + + unknown = set(platforms).difference(self.known_platforms) + if unknown: + cls = type(self) + logger = logging.getLogger(cls.__qualname__) + logger.warn( + f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " + f"in '.. availability:: {self.arguments[0]}', see " + f"{__file__}:{cls.__qualname__}.known_platforms for a set " + "known platforms." + ) + + return platforms + + # Support for documenting audit event diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 0025869ba46d4..d40155edf3f50 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -975,7 +975,7 @@ conflict. order to force the interpreter to use ``ASCII`` instead of ``UTF-8`` for system interfaces. - .. availability:: \*nix. + .. availability:: Unix. .. versionadded:: 3.7 See :pep:`538` for more details. diff --git a/Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst b/Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst new file mode 100644 index 0000000000000..ece36bc4d1ced --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst @@ -0,0 +1,2 @@ +Use consistent syntax for platform availability. The directive now supports +a content body and emits a warning when it encounters an unknown platform. From webhook-mailer at python.org Mon Aug 1 09:04:19 2022 From: webhook-mailer at python.org (encukou) Date: Mon, 01 Aug 2022 13:04:19 -0000 Subject: [Python-checkins] gh-93649: Split heaptype tests from _testcapimodule.c (GH-95386) Message-ID: https://github.com/python/cpython/commit/664e96a98fcc7572d4b049b70b74cdd63bd736c6 commit: 664e96a98fcc7572d4b049b70b74cdd63bd736c6 branch: main author: Petr Viktorin committer: encukou date: 2022-08-01T15:04:14+02:00 summary: gh-93649: Split heaptype tests from _testcapimodule.c (GH-95386) This removes the unused negative_dictoffset function: the type this function would create is available as _testcapi.HeapCTypeWithNegativeDict files: A Modules/_testcapi/heaptype.c M Modules/Setup.stdlib.in M Modules/_testcapi/parts.h M Modules/_testcapimodule.c M PCbuild/_testcapi.vcxproj M PCbuild/_testcapi.vcxproj.filters diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 09eca9f980db1..c5dc1e8eb4537 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -169,7 +169,7 @@ @MODULE__XXTESTFUZZ_TRUE at _xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE at _testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE at _testinternalcapi _testinternalcapi.c - at MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c + at MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c # Some testing modules MUST be built as shared libraries. *shared* diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c new file mode 100644 index 0000000000000..9fb0051ca125e --- /dev/null +++ b/Modules/_testcapi/heaptype.c @@ -0,0 +1,973 @@ +#include "parts.h" +#include "structmember.h" // PyMemberDef + +static struct PyModuleDef *_testcapimodule = NULL; // set at initialization + +/* Tests for heap types (PyType_From*) */ + +static PyObject *pytype_fromspec_meta(PyObject* self, PyObject *meta) +{ + if (!PyType_Check(meta)) { + PyErr_SetString( + PyExc_TypeError, + "pytype_fromspec_meta: must be invoked with a type argument!"); + return NULL; + } + + PyType_Slot HeapCTypeViaMetaclass_slots[] = { + {0}, + }; + + PyType_Spec HeapCTypeViaMetaclass_spec = { + "_testcapi.HeapCTypeViaMetaclass", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT, + HeapCTypeViaMetaclass_slots + }; + + return PyType_FromMetaclass( + (PyTypeObject *) meta, NULL, &HeapCTypeViaMetaclass_spec, NULL); +} + + +static PyType_Slot empty_type_slots[] = { + {0, 0}, +}; + +static PyType_Spec MinimalMetaclass_spec = { + .name = "_testcapi.MinimalMetaclass", + .basicsize = sizeof(PyHeapTypeObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = empty_type_slots, +}; + +static PyType_Spec MinimalType_spec = { + .name = "_testcapi.MinimalSpecType", + .basicsize = 0, // Updated later + .flags = Py_TPFLAGS_DEFAULT, + .slots = empty_type_slots, +}; + + +static PyObject * +test_from_spec_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *metaclass = NULL; + PyObject *class = NULL; + PyObject *new = NULL; + PyObject *subclasses = NULL; + PyObject *result = NULL; + int r; + + metaclass = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass == NULL) { + goto finally; + } + class = PyObject_CallFunction(metaclass, "s(){}", "TestClass"); + if (class == NULL) { + goto finally; + } + + MinimalType_spec.basicsize = (int)(((PyTypeObject*)class)->tp_basicsize); + new = PyType_FromSpecWithBases(&MinimalType_spec, class); + if (new == NULL) { + goto finally; + } + if (Py_TYPE(new) != (PyTypeObject*)metaclass) { + PyErr_SetString(PyExc_AssertionError, + "Metaclass not set properly!"); + goto finally; + } + + /* Assert that __subclasses__ is updated */ + subclasses = PyObject_CallMethod(class, "__subclasses__", ""); + if (!subclasses) { + goto finally; + } + r = PySequence_Contains(subclasses, new); + if (r < 0) { + goto finally; + } + if (r == 0) { + PyErr_SetString(PyExc_AssertionError, + "subclasses not set properly!"); + goto finally; + } + + result = Py_NewRef(Py_None); + +finally: + Py_XDECREF(metaclass); + Py_XDECREF(class); + Py_XDECREF(new); + Py_XDECREF(subclasses); + return result; +} + + +static PyObject * +test_from_spec_invalid_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *metaclass_a = NULL; + PyObject *metaclass_b = NULL; + PyObject *class_a = NULL; + PyObject *class_b = NULL; + PyObject *bases = NULL; + PyObject *new = NULL; + PyObject *meta_error_string = NULL; + PyObject *exc_type = NULL; + PyObject *exc_value = NULL; + PyObject *exc_traceback = NULL; + PyObject *result = NULL; + + metaclass_a = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass_a == NULL) { + goto finally; + } + metaclass_b = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass_b == NULL) { + goto finally; + } + class_a = PyObject_CallFunction(metaclass_a, "s(){}", "TestClassA"); + if (class_a == NULL) { + goto finally; + } + + class_b = PyObject_CallFunction(metaclass_b, "s(){}", "TestClassB"); + if (class_b == NULL) { + goto finally; + } + + bases = PyTuple_Pack(2, class_a, class_b); + if (bases == NULL) { + goto finally; + } + + /* + * The following should raise a TypeError due to a MetaClass conflict. + */ + new = PyType_FromSpecWithBases(&MinimalType_spec, bases); + if (new != NULL) { + PyErr_SetString(PyExc_AssertionError, + "MetaType conflict not recognized by PyType_FromSpecWithBases"); + goto finally; + } + + // Assert that the correct exception was raised + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + + meta_error_string = PyUnicode_FromString("metaclass conflict:"); + if (meta_error_string == NULL) { + goto finally; + } + int res = PyUnicode_Contains(exc_value, meta_error_string); + if (res < 0) { + goto finally; + } + if (res == 0) { + PyErr_SetString(PyExc_AssertionError, + "TypeError did not inlclude expected message."); + goto finally; + } + result = Py_NewRef(Py_None); + } +finally: + Py_XDECREF(metaclass_a); + Py_XDECREF(metaclass_b); + Py_XDECREF(bases); + Py_XDECREF(new); + Py_XDECREF(meta_error_string); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_traceback); + Py_XDECREF(class_a); + Py_XDECREF(class_b); + return result; +} + + +static PyObject * +simple_str(PyObject *self) { + return PyUnicode_FromString(""); +} + + +static PyObject * +test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // Test that a heap type can be created from a spec that's later deleted + // (along with all its contents). + // All necessary data must be copied and held by the class + PyType_Spec *spec = NULL; + char *name = NULL; + char *doc = NULL; + PyType_Slot *slots = NULL; + PyObject *class = NULL; + PyObject *instance = NULL; + PyObject *obj = NULL; + PyObject *result = NULL; + + /* create a spec (and all its contents) on the heap */ + + const char NAME[] = "testcapi._Test"; + const char DOC[] = "a test class"; + + spec = PyMem_New(PyType_Spec, 1); + if (spec == NULL) { + PyErr_NoMemory(); + goto finally; + } + name = PyMem_New(char, sizeof(NAME)); + if (name == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(name, NAME, sizeof(NAME)); + + doc = PyMem_New(char, sizeof(DOC)); + if (doc == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(doc, DOC, sizeof(DOC)); + + spec->name = name; + spec->basicsize = sizeof(PyObject); + spec->itemsize = 0; + spec->flags = Py_TPFLAGS_DEFAULT; + slots = PyMem_New(PyType_Slot, 3); + if (slots == NULL) { + PyErr_NoMemory(); + goto finally; + } + slots[0].slot = Py_tp_str; + slots[0].pfunc = simple_str; + slots[1].slot = Py_tp_doc; + slots[1].pfunc = doc; + slots[2].slot = 0; + slots[2].pfunc = NULL; + spec->slots = slots; + + /* create the class */ + + class = PyType_FromSpec(spec); + if (class == NULL) { + goto finally; + } + + /* deallocate the spec (and all contents) */ + + // (Explicitly ovewrite memory before freeing, + // so bugs show themselves even without the debug allocator's help.) + memset(spec, 0xdd, sizeof(PyType_Spec)); + PyMem_Del(spec); + spec = NULL; + memset(name, 0xdd, sizeof(NAME)); + PyMem_Del(name); + name = NULL; + memset(doc, 0xdd, sizeof(DOC)); + PyMem_Del(doc); + doc = NULL; + memset(slots, 0xdd, 3 * sizeof(PyType_Slot)); + PyMem_Del(slots); + slots = NULL; + + /* check that everything works */ + + PyTypeObject *class_tp = (PyTypeObject *)class; + PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class; + assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0); + assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0); + assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0); + assert(strcmp(class_tp->tp_doc, "a test class") == 0); + + // call and check __str__ + instance = PyObject_CallNoArgs(class); + if (instance == NULL) { + goto finally; + } + obj = PyObject_Str(instance); + if (obj == NULL) { + goto finally; + } + assert(strcmp(PyUnicode_AsUTF8(obj), "") == 0); + Py_CLEAR(obj); + + result = Py_NewRef(Py_None); + finally: + PyMem_Del(spec); + PyMem_Del(name); + PyMem_Del(doc); + PyMem_Del(slots); + Py_XDECREF(class); + Py_XDECREF(instance); + Py_XDECREF(obj); + return result; +} + +PyType_Slot repeated_doc_slots[] = { + {Py_tp_doc, "A class used for tests?"}, + {Py_tp_doc, "A class used for tests"}, + {0, 0}, +}; + +PyType_Spec repeated_doc_slots_spec = { + .name = "RepeatedDocSlotClass", + .basicsize = sizeof(PyObject), + .slots = repeated_doc_slots, +}; + +typedef struct { + PyObject_HEAD + int data; +} HeapCTypeWithDataObject; + + +static struct PyMemberDef members_to_repeat[] = { + {"T_INT", T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL}, + {NULL} +}; + +PyType_Slot repeated_members_slots[] = { + {Py_tp_members, members_to_repeat}, + {Py_tp_members, members_to_repeat}, + {0, 0}, +}; + +PyType_Spec repeated_members_slots_spec = { + .name = "RepeatedMembersSlotClass", + .basicsize = sizeof(HeapCTypeWithDataObject), + .slots = repeated_members_slots, +}; + +static PyObject * +create_type_from_repeated_slots(PyObject *self, PyObject *variant_obj) +{ + PyObject *class = NULL; + int variant = PyLong_AsLong(variant_obj); + if (PyErr_Occurred()) { + return NULL; + } + switch (variant) { + case 0: + class = PyType_FromSpec(&repeated_doc_slots_spec); + break; + case 1: + class = PyType_FromSpec(&repeated_members_slots_spec); + break; + default: + PyErr_SetString(PyExc_ValueError, "bad test variant"); + break; + } + return class; +} + + +static PyMethodDef TestMethods[] = { + {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O}, + {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, + {"create_type_from_repeated_slots", + create_type_from_repeated_slots, METH_O}, + {"test_from_spec_metatype_inheritance", test_from_spec_metatype_inheritance, + METH_NOARGS}, + {"test_from_spec_invalid_metatype_inheritance", + test_from_spec_invalid_metatype_inheritance, + METH_NOARGS}, + {NULL}, +}; + + +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 +}; + +typedef struct { + PyObject_HEAD +} NullTpDocTypeObject; + +static PyType_Slot NullTpDocType_slots[] = { + {Py_tp_doc, NULL}, + {0, 0}, +}; + +static PyType_Spec NullTpDocType_spec = { + "_testcapi.NullTpDocType", + sizeof(NullTpDocTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + NullTpDocType_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__."); + +typedef struct { + PyObject_HEAD + int value; +} HeapCTypeObject; + +static struct PyMemberDef heapctype_members[] = { + {"value", T_INT, offsetof(HeapCTypeObject, value)}, + {NULL} /* Sentinel */ +}; + +static int +heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ((HeapCTypeObject *)self)->value = 10; + return 0; +} + +static int +heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static void +heapgcctype_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapGcCType_slots[] = { + {Py_tp_init, heapctype_init}, + {Py_tp_members, heapctype_members}, + {Py_tp_dealloc, heapgcctype_dealloc}, + {Py_tp_traverse, heapgcctype_traverse}, + {Py_tp_doc, (char*)heapgctype__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapGcCType_spec = { + "_testcapi.HeapGcCType", + sizeof(HeapCTypeObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + HeapGcCType_slots +}; + +PyDoc_STRVAR(heapctype__doc__, +"A heap type without GC, but with overridden dealloc.\n\n" +"The 'value' attribute is set to 10 in __init__."); + +static void +heapctype_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCType_slots[] = { + {Py_tp_init, heapctype_init}, + {Py_tp_members, heapctype_members}, + {Py_tp_dealloc, heapctype_dealloc}, + {Py_tp_doc, (char*)heapctype__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCType_spec = { + "_testcapi.HeapCType", + sizeof(HeapCTypeObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCType_slots +}; + +PyDoc_STRVAR(heapctypesubclass__doc__, +"Subclass of HeapCType, without GC.\n\n" +"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +typedef struct { + HeapCTypeObject base; + int value2; +} HeapCTypeSubclassObject; + +static int +heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + /* Call __init__ of the superclass */ + if (heapctype_init(self, args, kwargs) < 0) { + return -1; + } + /* Initialize additional element */ + ((HeapCTypeSubclassObject *)self)->value2 = 20; + return 0; +} + +static struct PyMemberDef heapctypesubclass_members[] = { + {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeSubclass_slots[] = { + {Py_tp_init, heapctypesubclass_init}, + {Py_tp_members, heapctypesubclass_members}, + {Py_tp_doc, (char*)heapctypesubclass__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSubclass_spec = { + "_testcapi.HeapCTypeSubclass", + sizeof(HeapCTypeSubclassObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeSubclass_slots +}; + +PyDoc_STRVAR(heapctypewithbuffer__doc__, +"Heap type with buffer support.\n\n" +"The buffer is set to [b'1', b'2', b'3', b'4']"); + +typedef struct { + HeapCTypeObject base; + char buffer[4]; +} HeapCTypeWithBufferObject; + +static int +heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) +{ + self->buffer[0] = '1'; + self->buffer[1] = '2'; + self->buffer[2] = '3'; + self->buffer[3] = '4'; + return PyBuffer_FillInfo( + view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); +} + +static void +heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) +{ + assert(view->obj == (void*) self); +} + +static PyType_Slot HeapCTypeWithBuffer_slots[] = { + {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, + {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, + {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithBuffer_spec = { + "_testcapi.HeapCTypeWithBuffer", + sizeof(HeapCTypeWithBufferObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithBuffer_slots +}; + +PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, +"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" +"__class__ is set to plain HeapCTypeSubclass during finalization.\n" +"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +static int +heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); + initproc base_init = PyType_GetSlot(base, Py_tp_init); + base_init(self, args, kwargs); + return 0; +} + +static void +heapctypesubclasswithfinalizer_finalize(PyObject *self) +{ + PyObject *error_type, *error_value, *error_traceback, *m; + PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + if (_testcapimodule == NULL) { + goto cleanup_finalize; + } + m = PyState_FindModule(_testcapimodule); + if (m == NULL) { + goto cleanup_finalize; + } + oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); + newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); + if (oldtype == NULL || newtype == NULL) { + goto cleanup_finalize; + } + + if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { + goto cleanup_finalize; + } + refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); + if (refcnt == NULL) { + goto cleanup_finalize; + } + if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { + goto cleanup_finalize; + } + Py_DECREF(refcnt); + refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); + if (refcnt == NULL) { + goto cleanup_finalize; + } + if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { + goto cleanup_finalize; + } + +cleanup_finalize: + Py_XDECREF(oldtype); + Py_XDECREF(newtype); + Py_XDECREF(refcnt); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { + {Py_tp_init, heapctypesubclasswithfinalizer_init}, + {Py_tp_members, heapctypesubclass_members}, + {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, + {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { + "_testcapi.HeapCTypeSubclassWithFinalizer", + sizeof(HeapCTypeSubclassObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + HeapCTypeSubclassWithFinalizer_slots +}; + +static PyType_Slot HeapCTypeMetaclass_slots[] = { + {0}, +}; + +static PyType_Spec HeapCTypeMetaclass_spec = { + "_testcapi.HeapCTypeMetaclass", + sizeof(PyHeapTypeObject), + sizeof(PyMemberDef), + Py_TPFLAGS_DEFAULT, + HeapCTypeMetaclass_slots +}; + +static PyObject * +heap_ctype_metaclass_custom_tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) +{ + return PyType_Type.tp_new(tp, args, kwargs); +} + +static PyType_Slot HeapCTypeMetaclassCustomNew_slots[] = { + { Py_tp_new, heap_ctype_metaclass_custom_tp_new }, + {0}, +}; + +static PyType_Spec HeapCTypeMetaclassCustomNew_spec = { + "_testcapi.HeapCTypeMetaclassCustomNew", + sizeof(PyHeapTypeObject), + sizeof(PyMemberDef), + Py_TPFLAGS_DEFAULT, + HeapCTypeMetaclassCustomNew_slots +}; + + +typedef struct { + PyObject_HEAD + PyObject *dict; +} HeapCTypeWithDictObject; + +static void +heapctypewithdict_dealloc(HeapCTypeWithDictObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + Py_XDECREF(self->dict); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyGetSetDef heapctypewithdict_getsetlist[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} /* Sentinel */ +}; + +static struct PyMemberDef heapctypewithdict_members[] = { + {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeWithDict_slots[] = { + {Py_tp_members, heapctypewithdict_members}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithdict_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithDict_spec = { + "_testcapi.HeapCTypeWithDict", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + +static struct PyMemberDef heapctypewithnegativedict_members[] = { + {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeWithNegativeDict_slots[] = { + {Py_tp_members, heapctypewithnegativedict_members}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithdict_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithNegativeDict_spec = { + "_testcapi.HeapCTypeWithNegativeDict", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithNegativeDict_slots +}; + +typedef struct { + PyObject_HEAD + PyObject *weakreflist; +} HeapCTypeWithWeakrefObject; + +static struct PyMemberDef heapctypewithweakref_members[] = { + {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, + {"__weaklistoffset__", T_PYSSIZET, + offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, + {NULL} /* Sentinel */ +}; + +static void +heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_XDECREF(self->weakreflist); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithWeakref_slots[] = { + {Py_tp_members, heapctypewithweakref_members}, + {Py_tp_dealloc, heapctypewithweakref_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithWeakref_spec = { + "_testcapi.HeapCTypeWithWeakref", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + +PyDoc_STRVAR(heapctypesetattr__doc__, +"A heap type without GC, but with overridden __setattr__.\n\n" +"The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); + +typedef struct { + PyObject_HEAD + long value; +} HeapCTypeSetattrObject; + +static struct PyMemberDef heapctypesetattr_members[] = { + {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, + {NULL} /* Sentinel */ +}; + +static int +heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ((HeapCTypeSetattrObject *)self)->value = 10; + return 0; +} + +static void +heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); +} + +static int +heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) +{ + PyObject *svalue = PyUnicode_FromString("value"); + if (svalue == NULL) + return -1; + int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); + Py_DECREF(svalue); + if (eq < 0) + return -1; + if (!eq) { + return PyObject_GenericSetAttr((PyObject*) self, attr, value); + } + if (value == NULL) { + self->value = 0; + return 0; + } + PyObject *ivalue = PyNumber_Long(value); + if (ivalue == NULL) + return -1; + long v = PyLong_AsLong(ivalue); + Py_DECREF(ivalue); + if (v == -1 && PyErr_Occurred()) + return -1; + self->value = v; + return 0; +} + +static PyType_Slot HeapCTypeSetattr_slots[] = { + {Py_tp_init, heapctypesetattr_init}, + {Py_tp_members, heapctypesetattr_members}, + {Py_tp_setattro, heapctypesetattr_setattro}, + {Py_tp_dealloc, heapctypesetattr_dealloc}, + {Py_tp_doc, (char*)heapctypesetattr__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSetattr_spec = { + "_testcapi.HeapCTypeSetattr", + sizeof(HeapCTypeSetattrObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeSetattr_slots +}; + +int +_PyTestCapi_Init_Heaptype(PyObject *m) { + _testcapimodule = PyModule_GetDef(m); + + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); + if (HeapDocCType == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + + /* bpo-41832: Add a new type to test PyType_FromSpec() + now can accept a NULL tp_doc slot. */ + PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); + if (NullTpDocType == NULL) { + return -1; + } + PyModule_AddObject(m, "NullTpDocType", NullTpDocType); + + PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); + if (HeapGcCType == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapGcCType", HeapGcCType); + + PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); + if (HeapCType == NULL) { + return -1; + } + PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); + if (subclass_bases == NULL) { + return -1; + } + PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); + if (HeapCTypeSubclass == NULL) { + return -1; + } + Py_DECREF(subclass_bases); + PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); + + PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); + if (HeapCTypeWithDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); + + PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); + if (HeapCTypeWithNegativeDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); + + PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); + if (HeapCTypeWithWeakref == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); + + PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); + if (HeapCTypeWithBuffer == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); + + PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); + if (HeapCTypeSetattr == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); + + PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); + if (subclass_with_finalizer_bases == NULL) { + return -1; + } + PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( + &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); + if (HeapCTypeSubclassWithFinalizer == NULL) { + return -1; + } + Py_DECREF(subclass_with_finalizer_bases); + PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); + + PyObject *HeapCTypeMetaclass = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclass_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclass == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclass", HeapCTypeMetaclass); + + PyObject *HeapCTypeMetaclassCustomNew = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclassCustomNew_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclassCustomNew == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew); + + return 0; +} diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index 54cddf4b0929f..e6d2ed23cb18e 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -1,3 +1,4 @@ #include "Python.h" int _PyTestCapi_Init_Vectorcall(PyObject *module); +int _PyTestCapi_Init_Heaptype(PyObject *module); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b9f75d154ee5c..f56b36a15e794 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -49,7 +49,6 @@ // Forward declarations static struct PyModuleDef _testcapimodule; -static PyType_Spec HeapTypeNameType_Spec; static PyObject *TestError; /* set to exception object in init */ @@ -311,30 +310,6 @@ test_dict_inner(int count) } } -static PyObject *pytype_fromspec_meta(PyObject* self, PyObject *meta) -{ - if (!PyType_Check(meta)) { - PyErr_SetString( - TestError, - "pytype_fromspec_meta: must be invoked with a type argument!"); - return NULL; - } - - PyType_Slot HeapCTypeViaMetaclass_slots[] = { - {0}, - }; - - PyType_Spec HeapCTypeViaMetaclass_spec = { - "_testcapi.HeapCTypeViaMetaclass", - sizeof(PyObject), - 0, - Py_TPFLAGS_DEFAULT, - HeapCTypeViaMetaclass_slots - }; - - return PyType_FromMetaclass( - (PyTypeObject *) meta, NULL, &HeapCTypeViaMetaclass_spec, NULL); -} static PyObject* @@ -1173,6 +1148,17 @@ test_get_statictype_slots(PyObject *self, PyObject *Py_UNUSED(ignored)) } +static PyType_Slot HeapTypeNameType_slots[] = { + {0}, +}; + +static PyType_Spec HeapTypeNameType_Spec = { + .name = "_testcapi.HeapTypeNameType", + .basicsize = sizeof(PyObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = HeapTypeNameType_slots, +}; + static PyObject * test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1211,339 +1197,6 @@ test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) } -static PyType_Slot empty_type_slots[] = { - {0, 0}, -}; - -static PyType_Spec MinimalMetaclass_spec = { - .name = "_testcapi.MinimalMetaclass", - .basicsize = sizeof(PyHeapTypeObject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .slots = empty_type_slots, -}; - -static PyType_Spec MinimalType_spec = { - .name = "_testcapi.MinimalSpecType", - .basicsize = 0, // Updated later - .flags = Py_TPFLAGS_DEFAULT, - .slots = empty_type_slots, -}; - -static PyObject * -test_from_spec_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *metaclass = NULL; - PyObject *class = NULL; - PyObject *new = NULL; - PyObject *subclasses = NULL; - PyObject *result = NULL; - int r; - - metaclass = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); - if (metaclass == NULL) { - goto finally; - } - class = PyObject_CallFunction(metaclass, "s(){}", "TestClass"); - if (class == NULL) { - goto finally; - } - - MinimalType_spec.basicsize = (int)(((PyTypeObject*)class)->tp_basicsize); - new = PyType_FromSpecWithBases(&MinimalType_spec, class); - if (new == NULL) { - goto finally; - } - if (Py_TYPE(new) != (PyTypeObject*)metaclass) { - PyErr_SetString(PyExc_AssertionError, - "Metaclass not set properly!"); - goto finally; - } - - /* Assert that __subclasses__ is updated */ - subclasses = PyObject_CallMethod(class, "__subclasses__", ""); - if (!subclasses) { - goto finally; - } - r = PySequence_Contains(subclasses, new); - if (r < 0) { - goto finally; - } - if (r == 0) { - PyErr_SetString(PyExc_AssertionError, - "subclasses not set properly!"); - goto finally; - } - - result = Py_NewRef(Py_None); - -finally: - Py_XDECREF(metaclass); - Py_XDECREF(class); - Py_XDECREF(new); - Py_XDECREF(subclasses); - return result; -} - - -static PyObject * -test_from_spec_invalid_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *metaclass_a = NULL; - PyObject *metaclass_b = NULL; - PyObject *class_a = NULL; - PyObject *class_b = NULL; - PyObject *bases = NULL; - PyObject *new = NULL; - PyObject *meta_error_string = NULL; - PyObject *exc_type = NULL; - PyObject *exc_value = NULL; - PyObject *exc_traceback = NULL; - PyObject *result = NULL; - - metaclass_a = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); - if (metaclass_a == NULL) { - goto finally; - } - metaclass_b = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); - if (metaclass_b == NULL) { - goto finally; - } - class_a = PyObject_CallFunction(metaclass_a, "s(){}", "TestClassA"); - if (class_a == NULL) { - goto finally; - } - - class_b = PyObject_CallFunction(metaclass_b, "s(){}", "TestClassB"); - if (class_b == NULL) { - goto finally; - } - - bases = PyTuple_Pack(2, class_a, class_b); - if (bases == NULL) { - goto finally; - } - - /* - * The following should raise a TypeError due to a MetaClass conflict. - */ - new = PyType_FromSpecWithBases(&MinimalType_spec, bases); - if (new != NULL) { - PyErr_SetString(PyExc_AssertionError, - "MetaType conflict not recognized by PyType_FromSpecWithBases"); - goto finally; - } - - // Assert that the correct exception was raised - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); - - meta_error_string = PyUnicode_FromString("metaclass conflict:"); - if (meta_error_string == NULL) { - goto finally; - } - int res = PyUnicode_Contains(exc_value, meta_error_string); - if (res < 0) { - goto finally; - } - if (res == 0) { - PyErr_SetString(PyExc_AssertionError, - "TypeError did not inlclude expected message."); - goto finally; - } - result = Py_NewRef(Py_None); - } -finally: - Py_XDECREF(metaclass_a); - Py_XDECREF(metaclass_b); - Py_XDECREF(bases); - Py_XDECREF(new); - Py_XDECREF(meta_error_string); - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_traceback); - Py_XDECREF(class_a); - Py_XDECREF(class_b); - return result; -} - - -static PyObject * -simple_str(PyObject *self) { - return PyUnicode_FromString(""); -} - - -static PyObject * -test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - // Test that a heap type can be created from a spec that's later deleted - // (along with all its contents). - // All necessary data must be copied and held by the class - PyType_Spec *spec = NULL; - char *name = NULL; - char *doc = NULL; - PyType_Slot *slots = NULL; - PyObject *class = NULL; - PyObject *instance = NULL; - PyObject *obj = NULL; - PyObject *result = NULL; - - /* create a spec (and all its contents) on the heap */ - - const char NAME[] = "testcapi._Test"; - const char DOC[] = "a test class"; - - spec = PyMem_New(PyType_Spec, 1); - if (spec == NULL) { - PyErr_NoMemory(); - goto finally; - } - name = PyMem_New(char, sizeof(NAME)); - if (name == NULL) { - PyErr_NoMemory(); - goto finally; - } - memcpy(name, NAME, sizeof(NAME)); - - doc = PyMem_New(char, sizeof(DOC)); - if (doc == NULL) { - PyErr_NoMemory(); - goto finally; - } - memcpy(doc, DOC, sizeof(DOC)); - - spec->name = name; - spec->basicsize = sizeof(PyObject); - spec->itemsize = 0; - spec->flags = Py_TPFLAGS_DEFAULT; - slots = PyMem_New(PyType_Slot, 3); - if (slots == NULL) { - PyErr_NoMemory(); - goto finally; - } - slots[0].slot = Py_tp_str; - slots[0].pfunc = simple_str; - slots[1].slot = Py_tp_doc; - slots[1].pfunc = doc; - slots[2].slot = 0; - slots[2].pfunc = NULL; - spec->slots = slots; - - /* create the class */ - - class = PyType_FromSpec(spec); - if (class == NULL) { - goto finally; - } - - /* deallocate the spec (and all contents) */ - - // (Explicitly ovewrite memory before freeing, - // so bugs show themselves even without the debug allocator's help.) - memset(spec, 0xdd, sizeof(PyType_Spec)); - PyMem_Del(spec); - spec = NULL; - memset(name, 0xdd, sizeof(NAME)); - PyMem_Del(name); - name = NULL; - memset(doc, 0xdd, sizeof(DOC)); - PyMem_Del(doc); - doc = NULL; - memset(slots, 0xdd, 3 * sizeof(PyType_Slot)); - PyMem_Del(slots); - slots = NULL; - - /* check that everything works */ - - PyTypeObject *class_tp = (PyTypeObject *)class; - PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class; - assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0); - assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0); - assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0); - assert(strcmp(class_tp->tp_doc, "a test class") == 0); - - // call and check __str__ - instance = PyObject_CallNoArgs(class); - if (instance == NULL) { - goto finally; - } - obj = PyObject_Str(instance); - if (obj == NULL) { - goto finally; - } - assert(strcmp(PyUnicode_AsUTF8(obj), "") == 0); - Py_CLEAR(obj); - - result = Py_NewRef(Py_None); - finally: - PyMem_Del(spec); - PyMem_Del(name); - PyMem_Del(doc); - PyMem_Del(slots); - Py_XDECREF(class); - Py_XDECREF(instance); - Py_XDECREF(obj); - return result; -} - -PyType_Slot repeated_doc_slots[] = { - {Py_tp_doc, "A class used for tests?"}, - {Py_tp_doc, "A class used for tests"}, - {0, 0}, -}; - -PyType_Spec repeated_doc_slots_spec = { - .name = "RepeatedDocSlotClass", - .basicsize = sizeof(PyObject), - .slots = repeated_doc_slots, -}; - -typedef struct { - PyObject_HEAD - int data; -} HeapCTypeWithDataObject; - - -static struct PyMemberDef members_to_repeat[] = { - {"T_INT", T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL}, - {NULL} -}; - -PyType_Slot repeated_members_slots[] = { - {Py_tp_members, members_to_repeat}, - {Py_tp_members, members_to_repeat}, - {0, 0}, -}; - -PyType_Spec repeated_members_slots_spec = { - .name = "RepeatedMembersSlotClass", - .basicsize = sizeof(HeapCTypeWithDataObject), - .slots = repeated_members_slots, -}; - -static PyObject * -create_type_from_repeated_slots(PyObject *self, PyObject *variant_obj) -{ - PyObject *class = NULL; - int variant = PyLong_AsLong(variant_obj); - if (PyErr_Occurred()) { - return NULL; - } - switch (variant) { - case 0: - class = PyType_FromSpec(&repeated_doc_slots_spec); - break; - case 1: - class = PyType_FromSpec(&repeated_members_slots_spec); - break; - default: - PyErr_SetString(PyExc_ValueError, "bad test variant"); - break; - } - return class; -} - - static PyObject * test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -6054,7 +5707,6 @@ test_macros(PyObject *self, PyObject *Py_UNUSED(args)) } -static PyObject *negative_dictoffset(PyObject *, PyObject *); static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*); static PyObject *getargs_s_hash_int2(PyObject *, PyObject *, PyObject*); @@ -6109,7 +5761,6 @@ static PyMethodDef TestMethods[] = { {"test_long_numbits", test_long_numbits, METH_NOARGS}, {"test_k_code", test_k_code, METH_NOARGS}, {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, - {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O}, {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, {"pyobject_repr_from_null", pyobject_repr_from_null, METH_NOARGS}, {"pyobject_str_from_null", pyobject_str_from_null, METH_NOARGS}, @@ -6128,20 +5779,11 @@ static PyMethodDef TestMethods[] = { {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, - {"negative_dictoffset", negative_dictoffset, METH_NOARGS}, {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, {"get_args", get_args, METH_VARARGS}, {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS}, {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, - {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, - {"create_type_from_repeated_slots", - create_type_from_repeated_slots, METH_O}, - {"test_from_spec_metatype_inheritance", test_from_spec_metatype_inheritance, - METH_NOARGS}, - {"test_from_spec_invalid_metatype_inheritance", - test_from_spec_invalid_metatype_inheritance, - METH_NOARGS}, {"get_kwargs", _PyCFunction_CAST(get_kwargs), METH_VARARGS|METH_KEYWORDS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, @@ -6914,509 +6556,6 @@ static PyTypeObject Generic_Type = { .tp_methods = generic_methods, }; -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 -}; - -typedef struct { - PyObject_HEAD -} HeapTypeNameObject; - -static PyType_Slot HeapTypeNameType_slots[] = { - {0}, -}; - -static PyType_Spec HeapTypeNameType_Spec = { - .name = "_testcapi.HeapTypeNameType", - .basicsize = sizeof(HeapTypeNameObject), - .flags = Py_TPFLAGS_DEFAULT, - .slots = HeapTypeNameType_slots, -}; - -typedef struct { - PyObject_HEAD -} NullTpDocTypeObject; - -static PyType_Slot NullTpDocType_slots[] = { - {Py_tp_doc, NULL}, - {0, 0}, -}; - -static PyType_Spec NullTpDocType_spec = { - "_testcapi.NullTpDocType", - sizeof(NullTpDocTypeObject), - 0, - Py_TPFLAGS_DEFAULT, - NullTpDocType_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__."); - -typedef struct { - PyObject_HEAD - int value; -} HeapCTypeObject; - -static struct PyMemberDef heapctype_members[] = { - {"value", T_INT, offsetof(HeapCTypeObject, value)}, - {NULL} /* Sentinel */ -}; - -static int -heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - ((HeapCTypeObject *)self)->value = 10; - return 0; -} - -static int -heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(self)); - return 0; -} - -static void -heapgcctype_dealloc(HeapCTypeObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - PyObject_GC_Del(self); - Py_DECREF(tp); -} - -static PyType_Slot HeapGcCType_slots[] = { - {Py_tp_init, heapctype_init}, - {Py_tp_members, heapctype_members}, - {Py_tp_dealloc, heapgcctype_dealloc}, - {Py_tp_traverse, heapgcctype_traverse}, - {Py_tp_doc, (char*)heapgctype__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapGcCType_spec = { - "_testcapi.HeapGcCType", - sizeof(HeapCTypeObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - HeapGcCType_slots -}; - -PyDoc_STRVAR(heapctype__doc__, -"A heap type without GC, but with overridden dealloc.\n\n" -"The 'value' attribute is set to 10 in __init__."); - -static void -heapctype_dealloc(HeapCTypeObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_Free(self); - Py_DECREF(tp); -} - -static PyType_Slot HeapCType_slots[] = { - {Py_tp_init, heapctype_init}, - {Py_tp_members, heapctype_members}, - {Py_tp_dealloc, heapctype_dealloc}, - {Py_tp_doc, (char*)heapctype__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCType_spec = { - "_testcapi.HeapCType", - sizeof(HeapCTypeObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCType_slots -}; - -PyDoc_STRVAR(heapctypesubclass__doc__, -"Subclass of HeapCType, without GC.\n\n" -"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); - -typedef struct { - HeapCTypeObject base; - int value2; -} HeapCTypeSubclassObject; - -static int -heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - /* Call __init__ of the superclass */ - if (heapctype_init(self, args, kwargs) < 0) { - return -1; - } - /* Initialize additional element */ - ((HeapCTypeSubclassObject *)self)->value2 = 20; - return 0; -} - -static struct PyMemberDef heapctypesubclass_members[] = { - {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeSubclass_slots[] = { - {Py_tp_init, heapctypesubclass_init}, - {Py_tp_members, heapctypesubclass_members}, - {Py_tp_doc, (char*)heapctypesubclass__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSubclass_spec = { - "_testcapi.HeapCTypeSubclass", - sizeof(HeapCTypeSubclassObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeSubclass_slots -}; - -PyDoc_STRVAR(heapctypewithbuffer__doc__, -"Heap type with buffer support.\n\n" -"The buffer is set to [b'1', b'2', b'3', b'4']"); - -typedef struct { - HeapCTypeObject base; - char buffer[4]; -} HeapCTypeWithBufferObject; - -static int -heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) -{ - self->buffer[0] = '1'; - self->buffer[1] = '2'; - self->buffer[2] = '3'; - self->buffer[3] = '4'; - return PyBuffer_FillInfo( - view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); -} - -static void -heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) -{ - assert(view->obj == (void*) self); -} - -static PyType_Slot HeapCTypeWithBuffer_slots[] = { - {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, - {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, - {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithBuffer_spec = { - "_testcapi.HeapCTypeWithBuffer", - sizeof(HeapCTypeWithBufferObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithBuffer_slots -}; - -PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, -"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" -"__class__ is set to plain HeapCTypeSubclass during finalization.\n" -"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); - -static int -heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); - initproc base_init = PyType_GetSlot(base, Py_tp_init); - base_init(self, args, kwargs); - return 0; -} - -static void -heapctypesubclasswithfinalizer_finalize(PyObject *self) -{ - PyObject *error_type, *error_value, *error_traceback, *m; - PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - m = PyState_FindModule(&_testcapimodule); - if (m == NULL) { - goto cleanup_finalize; - } - oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); - newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); - if (oldtype == NULL || newtype == NULL) { - goto cleanup_finalize; - } - - if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { - goto cleanup_finalize; - } - refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); - if (refcnt == NULL) { - goto cleanup_finalize; - } - if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { - goto cleanup_finalize; - } - Py_DECREF(refcnt); - refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); - if (refcnt == NULL) { - goto cleanup_finalize; - } - if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { - goto cleanup_finalize; - } - -cleanup_finalize: - Py_XDECREF(oldtype); - Py_XDECREF(newtype); - Py_XDECREF(refcnt); - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} - -static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { - {Py_tp_init, heapctypesubclasswithfinalizer_init}, - {Py_tp_members, heapctypesubclass_members}, - {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, - {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { - "_testcapi.HeapCTypeSubclassWithFinalizer", - sizeof(HeapCTypeSubclassObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, - HeapCTypeSubclassWithFinalizer_slots -}; - -static PyType_Slot HeapCTypeMetaclass_slots[] = { - {0}, -}; - -static PyType_Spec HeapCTypeMetaclass_spec = { - "_testcapi.HeapCTypeMetaclass", - sizeof(PyHeapTypeObject), - sizeof(PyMemberDef), - Py_TPFLAGS_DEFAULT, - HeapCTypeMetaclass_slots -}; - -static PyObject * -heap_ctype_metaclass_custom_tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) -{ - return PyType_Type.tp_new(tp, args, kwargs); -} - -static PyType_Slot HeapCTypeMetaclassCustomNew_slots[] = { - { Py_tp_new, heap_ctype_metaclass_custom_tp_new }, - {0}, -}; - -static PyType_Spec HeapCTypeMetaclassCustomNew_spec = { - "_testcapi.HeapCTypeMetaclassCustomNew", - sizeof(PyHeapTypeObject), - sizeof(PyMemberDef), - Py_TPFLAGS_DEFAULT, - HeapCTypeMetaclassCustomNew_slots -}; - - -typedef struct { - PyObject_HEAD - PyObject *dict; -} HeapCTypeWithDictObject; - -static void -heapctypewithdict_dealloc(HeapCTypeWithDictObject* self) -{ - - PyTypeObject *tp = Py_TYPE(self); - Py_XDECREF(self->dict); - PyObject_Free(self); - Py_DECREF(tp); -} - -static PyGetSetDef heapctypewithdict_getsetlist[] = { - {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, - {NULL} /* Sentinel */ -}; - -static struct PyMemberDef heapctypewithdict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeWithDict_slots[] = { - {Py_tp_members, heapctypewithdict_members}, - {Py_tp_getset, heapctypewithdict_getsetlist}, - {Py_tp_dealloc, heapctypewithdict_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithDict_spec = { - "_testcapi.HeapCTypeWithDict", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithDict_slots -}; - -static struct PyMemberDef heapctypewithnegativedict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeWithNegativeDict_slots[] = { - {Py_tp_members, heapctypewithnegativedict_members}, - {Py_tp_getset, heapctypewithdict_getsetlist}, - {Py_tp_dealloc, heapctypewithdict_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithNegativeDict_spec = { - "_testcapi.HeapCTypeWithNegativeDict", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithNegativeDict_slots -}; - -typedef struct { - PyObject_HEAD - PyObject *weakreflist; -} HeapCTypeWithWeakrefObject; - -static struct PyMemberDef heapctypewithweakref_members[] = { - {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, - {"__weaklistoffset__", T_PYSSIZET, - offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, - {NULL} /* Sentinel */ -}; - -static void -heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self) -{ - - PyTypeObject *tp = Py_TYPE(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_XDECREF(self->weakreflist); - PyObject_Free(self); - Py_DECREF(tp); -} - -static PyType_Slot HeapCTypeWithWeakref_slots[] = { - {Py_tp_members, heapctypewithweakref_members}, - {Py_tp_dealloc, heapctypewithweakref_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithWeakref_spec = { - "_testcapi.HeapCTypeWithWeakref", - sizeof(HeapCTypeWithWeakrefObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithWeakref_slots -}; - -PyDoc_STRVAR(heapctypesetattr__doc__, -"A heap type without GC, but with overridden __setattr__.\n\n" -"The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); - -typedef struct { - PyObject_HEAD - long value; -} HeapCTypeSetattrObject; - -static struct PyMemberDef heapctypesetattr_members[] = { - {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, - {NULL} /* Sentinel */ -}; - -static int -heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - ((HeapCTypeSetattrObject *)self)->value = 10; - return 0; -} - -static void -heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_Free(self); - Py_DECREF(tp); -} - -static int -heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) -{ - PyObject *svalue = PyUnicode_FromString("value"); - if (svalue == NULL) - return -1; - int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); - Py_DECREF(svalue); - if (eq < 0) - return -1; - if (!eq) { - return PyObject_GenericSetAttr((PyObject*) self, attr, value); - } - if (value == NULL) { - self->value = 0; - return 0; - } - PyObject *ivalue = PyNumber_Long(value); - if (ivalue == NULL) - return -1; - long v = PyLong_AsLong(ivalue); - Py_DECREF(ivalue); - if (v == -1 && PyErr_Occurred()) - return -1; - self->value = v; - return 0; -} - -static PyType_Slot HeapCTypeSetattr_slots[] = { - {Py_tp_init, heapctypesetattr_init}, - {Py_tp_members, heapctypesetattr_members}, - {Py_tp_setattro, heapctypesetattr_setattro}, - {Py_tp_dealloc, heapctypesetattr_dealloc}, - {Py_tp_doc, (char*)heapctypesetattr__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSetattr_spec = { - "_testcapi.HeapCTypeSetattr", - sizeof(HeapCTypeSetattrObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeSetattr_slots -}; - static PyMethodDef meth_instance_methods[] = { {"meth_varargs", meth_varargs, METH_VARARGS}, {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, @@ -7656,97 +6795,6 @@ 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); - - /* bpo-41832: Add a new type to test PyType_FromSpec() - now can accept a NULL tp_doc slot. */ - PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); - if (NullTpDocType == NULL) { - return NULL; - } - PyModule_AddObject(m, "NullTpDocType", NullTpDocType); - - PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); - if (HeapGcCType == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapGcCType", HeapGcCType); - - PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); - if (HeapCType == NULL) { - return NULL; - } - PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); - if (subclass_bases == NULL) { - return NULL; - } - PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); - if (HeapCTypeSubclass == NULL) { - return NULL; - } - Py_DECREF(subclass_bases); - PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); - - PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); - if (HeapCTypeWithDict == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); - - PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); - if (HeapCTypeWithNegativeDict == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); - - PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); - if (HeapCTypeWithWeakref == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); - - PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); - if (HeapCTypeWithBuffer == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); - - PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); - if (HeapCTypeSetattr == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); - - PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); - if (subclass_with_finalizer_bases == NULL) { - return NULL; - } - PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( - &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); - if (HeapCTypeSubclassWithFinalizer == NULL) { - return NULL; - } - Py_DECREF(subclass_with_finalizer_bases); - PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); - - PyObject *HeapCTypeMetaclass = PyType_FromMetaclass( - &PyType_Type, m, &HeapCTypeMetaclass_spec, (PyObject *) &PyType_Type); - if (HeapCTypeMetaclass == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeMetaclass", HeapCTypeMetaclass); - - PyObject *HeapCTypeMetaclassCustomNew = PyType_FromMetaclass( - &PyType_Type, m, &HeapCTypeMetaclassCustomNew_spec, (PyObject *) &PyType_Type); - if (HeapCTypeMetaclassCustomNew == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew); - if (PyType_Ready(&ContainerNoGC_type) < 0) { return NULL; } @@ -7759,17 +6807,14 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Vectorcall(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Heaptype(m) < 0) { + return NULL; + } PyState_AddModule(m, &_testcapimodule); return m; } -static PyObject * -negative_dictoffset(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); -} - /* Test the C API exposed when PY_SSIZE_T_CLEAN is not defined */ #undef Py_BuildValue diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index 07e23557e1dba..a88540cab19f9 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -95,6 +95,7 @@ + diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index 82fce057e2e27..a43ab5ea0ff94 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -15,6 +15,9 @@ Source Files + + Source Files + From webhook-mailer at python.org Mon Aug 1 09:07:40 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 01 Aug 2022 13:07:40 -0000 Subject: [Python-checkins] gh-95007: Remove the NoneType return converter from Argument Clinic Doc (#95529) Message-ID: https://github.com/python/cpython/commit/347c783673c22c3f37e21c485437404b67405512 commit: 347c783673c22c3f37e21c485437404b67405512 branch: main author: Noam Cohen committer: erlend-aasland date: 2022-08-01T15:07:35+02:00 summary: gh-95007: Remove the NoneType return converter from Argument Clinic Doc (#95529) The converter was removed in 74b5e4ce80858ac5c7d03411cb8cce7e6865f181 files: M Doc/howto/clinic.rst diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 2d368966bf5d3..d634c4b47db90 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1070,11 +1070,6 @@ None of these take parameters. For the first three, return -1 to indicate error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` pointer to indicate an error. -(There's also an experimental ``NoneType`` converter, which lets you -return ``Py_None`` on success or ``NULL`` on failure, without having -to increment the reference count on ``Py_None``. I'm not sure it adds -enough clarity to be worth using.) - To see all the return converters Argument Clinic supports, along with their parameters (if any), just run ``Tools/clinic/clinic.py --converters`` for the full list. From webhook-mailer at python.org Mon Aug 1 09:15:12 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 01 Aug 2022 13:15:12 -0000 Subject: [Python-checkins] gh-91146: More reduce allocation size of list from str.split/rsplit (gh-95493) Message-ID: https://github.com/python/cpython/commit/fb75d015f487e50079e8d2ea7859750684b124e4 commit: fb75d015f487e50079e8d2ea7859750684b124e4 branch: main author: Dong-hee Na committer: corona10 date: 2022-08-01T22:15:07+09:00 summary: gh-91146: More reduce allocation size of list from str.split/rsplit (gh-95493) Co-authored-by: Inada Naoki files: M Misc/NEWS.d/next/Core and Builtins/2022-07-31-03-22-58.gh-issue-91146.Y2Hziy.rst M Objects/unicodeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-31-03-22-58.gh-issue-91146.Y2Hziy.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-03-22-58.gh-issue-91146.Y2Hziy.rst index 52568dbedd130..9172ca298e809 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-31-03-22-58.gh-issue-91146.Y2Hziy.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-03-22-58.gh-issue-91146.Y2Hziy.rst @@ -1,2 +1,2 @@ Reduce allocation size of :class:`list` from :meth:`str.split` -and :meth:`str.rsplit`. Patch by Dong-hee Na. +and :meth:`str.rsplit`. Patch by Dong-hee Na and Inada Naoki. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 355d74fe3bbda..7ff79953257ee 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9698,11 +9698,11 @@ split(PyObject *self, PyObject* out; len1 = PyUnicode_GET_LENGTH(self); kind1 = PyUnicode_KIND(self); - if (maxcount < 0) { - maxcount = len1; - } - if (substring == NULL) + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) @@ -9728,9 +9728,16 @@ split(PyObject *self, default: Py_UNREACHABLE(); } + } kind2 = PyUnicode_KIND(substring); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) @@ -9785,11 +9792,11 @@ rsplit(PyObject *self, len1 = PyUnicode_GET_LENGTH(self); kind1 = PyUnicode_KIND(self); - if (maxcount < 0) { - maxcount = len1; - } - if (substring == NULL) + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) @@ -9815,9 +9822,15 @@ rsplit(PyObject *self, default: Py_UNREACHABLE(); } - + } kind2 = PyUnicode_KIND(substring); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) From webhook-mailer at python.org Mon Aug 1 09:35:04 2022 From: webhook-mailer at python.org (markshannon) Date: Mon, 01 Aug 2022 13:35:04 -0000 Subject: [Python-checkins] GH-95245: Store object values and dict pointers in single tagged pointer. (GH-95278) Message-ID: https://github.com/python/cpython/commit/de388c0a7b71c094d36ce40fecef87bdbb8a87d3 commit: de388c0a7b71c094d36ce40fecef87bdbb8a87d3 branch: main author: Mark Shannon committer: markshannon date: 2022-08-01T14:34:54+01:00 summary: GH-95245: Store object values and dict pointers in single tagged pointer. (GH-95278) files: A Misc/NEWS.d/next/Core and Builtins/2022-07-26-12-59-03.gh-issue-95245.GHWczn.rst M Include/cpython/dictobject.h M Include/cpython/object.h M Include/internal/pycore_object.h M Objects/dictobject.c M Objects/object.c M Objects/typeobject.c M Python/ceval.c M Python/specialize.c M Tools/gdb/libpython.py diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index c2e4a46e76195..565ad791a6cb2 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -83,6 +83,3 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); - -PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *self, visitproc visit, void *arg); -PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *self); diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 026803320a11b..60c7c3e2aa6bf 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -510,3 +510,7 @@ Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro; #define Py_TRASHCAN_SAFE_END(op) \ Py_TRASHCAN_END; \ } while(0); + + +PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); +PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj); diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 9f061d8b08772..173d36784cf13 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -274,24 +274,49 @@ extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name); -static inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj) +typedef union { + PyObject *dict; + /* Use a char* to generate a warning if directly assigning a PyDictValues */ + char *values; +} PyDictOrValues; + +static inline PyDictOrValues * +_PyObject_DictOrValuesPointer(PyObject *obj) { assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return ((PyDictValues **)obj)-4; + return ((PyDictOrValues *)obj)-3; } -static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj) +static inline int +_PyDictOrValues_IsValues(PyDictOrValues dorv) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return ((PyObject **)obj)-3; + return ((uintptr_t)dorv.values) & 1; +} + +static inline PyDictValues * +_PyDictOrValues_GetValues(PyDictOrValues dorv) +{ + assert(_PyDictOrValues_IsValues(dorv)); + return (PyDictValues *)(dorv.values + 1); +} + +static inline PyObject * +_PyDictOrValues_GetDict(PyDictOrValues dorv) +{ + assert(!_PyDictOrValues_IsValues(dorv)); + return dorv.dict; +} + +static inline void +_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values) +{ + ptr->values = ((char *)values) - 1; } #define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3) -extern PyObject ** _PyObject_DictPointer(PyObject *); -extern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); -extern void _PyObject_ClearInstanceAttributes(PyObject *self); -extern void _PyObject_FreeInstanceAttributes(PyObject *self); +extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); +extern void _PyObject_FreeInstanceAttributes(PyObject *obj); extern int _PyObject_IsInstanceDictEmpty(PyObject *); extern PyObject* _PyType_GetSubclasses(PyTypeObject *); diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-26-12-59-03.gh-issue-95245.GHWczn.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-26-12-59-03.gh-issue-95245.GHWczn.rst new file mode 100644 index 0000000000000..d6dccc8fcad0b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-26-12-59-03.gh-issue-95245.GHWczn.rst @@ -0,0 +1,2 @@ +Merge managed dict and values pointer into a single tagged pointer to save +one word in the pre-header. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 25e191fb8eadb..d8203486d76d2 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -5368,7 +5368,7 @@ init_inline_values(PyObject *obj, PyTypeObject *tp) for (int i = 0; i < size; i++) { values->values[i] = NULL; } - *_PyObject_ValuesPointer(obj) = values; + _PyDictOrValues_SetValues(_PyObject_DictOrValuesPointer(obj), values); return 0; } @@ -5394,7 +5394,7 @@ _PyObject_InitializeDict(PyObject *obj) if (dict == NULL) { return -1; } - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); *dictptr = dict; return 0; } @@ -5422,7 +5422,6 @@ make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) PyObject * _PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); OBJECT_STAT_INC(dict_materialized_on_request); return make_dict_from_instance_attributes(keys, values); @@ -5458,8 +5457,7 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, if (dict == NULL) { return -1; } - *_PyObject_ValuesPointer(obj) = NULL; - *_PyObject_ManagedDictPointer(obj) = dict; + _PyObject_DictOrValuesPointer(obj)->dict = dict; if (value == NULL) { return PyDict_DelItem(dict, name); } @@ -5488,6 +5486,37 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, return 0; } +/* Sanity check for managed dicts */ +#if 0 +#define CHECK(val) assert(val); if (!(val)) { return 0; } + +int +_PyObject_ManagedDictValidityCheck(PyObject *obj) +{ + PyTypeObject *tp = Py_TYPE(obj); + CHECK(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + int size = ((uint8_t *)values)[-2]; + int count = 0; + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + if (values->values[i] != NULL) { + count++; + } + } + CHECK(size == count); + } + else { + if (dorv_ptr->dict != NULL) { + CHECK(PyDict_Check(dorv_ptr->dict)); + } + } + return 1; +} +#endif + PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name) @@ -5511,105 +5540,94 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) if (tp->tp_dictoffset == 0) { return 1; } - PyObject **dictptr; + PyObject *dict; if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictValues *values = *_PyObject_ValuesPointer(obj); - if (values) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - if (values->values[i] != NULL) { + if (_PyDictOrValues_GetValues(dorv)->values[i] != NULL) { return 0; } } return 1; } - dictptr = _PyObject_ManagedDictPointer(obj); + dict = _PyDictOrValues_GetDict(dorv); } else { - dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + dict = *dictptr; } - PyObject *dict = *dictptr; if (dict == NULL) { return 1; } return ((PyDictObject *)dict)->ma_used == 0; } - -int -_PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg) -{ - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return 0; - } - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_VISIT((*values_ptr)->values[i]); - } - return 0; -} - -void -_PyObject_ClearInstanceAttributes(PyObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return; - } - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_CLEAR((*values_ptr)->values[i]); - } -} - void _PyObject_FreeInstanceAttributes(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + if (!_PyDictOrValues_IsValues(dorv)) { return; } + PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_XDECREF((*values_ptr)->values[i]); + Py_XDECREF(values->values[i]); } - free_values(*values_ptr); + free_values(values); } int -_PyObject_VisitManagedDict(PyObject *self, visitproc visit, void *arg) +_PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { - PyTypeObject *tp = Py_TYPE(self); + PyTypeObject *tp = Py_TYPE(obj); if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return 0; } assert(tp->tp_dictoffset); - int err = _PyObject_VisitInstanceAttributes(self, visit, arg); - if (err) { - return err; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_VISIT(values->values[i]); + } + } + else { + PyObject *dict = _PyDictOrValues_GetDict(dorv); + Py_VISIT(dict); } - Py_VISIT(*_PyObject_ManagedDictPointer(self)); return 0; } - void -_PyObject_ClearManagedDict(PyObject *self) +_PyObject_ClearManagedDict(PyObject *obj) { - PyTypeObject *tp = Py_TYPE(self); + PyTypeObject *tp = Py_TYPE(obj); if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return; } - _PyObject_FreeInstanceAttributes(self); - *_PyObject_ValuesPointer(self) = NULL; - Py_CLEAR(*_PyObject_ManagedDictPointer(self)); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_CLEAR(values->values[i]); + } + dorv_ptr->dict = NULL; + free_values(values); + } + else { + PyObject *dict = dorv_ptr->dict; + if (dict) { + dorv_ptr->dict = NULL; + Py_DECREF(dict); + } + } } PyObject * @@ -5618,25 +5636,26 @@ PyObject_GenericGetDict(PyObject *obj, void *context) PyObject *dict; PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - PyObject **dictptr = _PyObject_ManagedDictPointer(obj); - if (*values_ptr) { - assert(*dictptr == NULL); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); OBJECT_STAT_INC(dict_materialized_on_request); - *dictptr = dict = make_dict_from_instance_attributes(CACHED_KEYS(tp), *values_ptr); + dict = make_dict_from_instance_attributes(CACHED_KEYS(tp), values); if (dict != NULL) { - *values_ptr = NULL; + dorv_ptr->dict = dict; } } - else if (*dictptr == NULL) { - *dictptr = dict = PyDict_New(); - } else { - dict = *dictptr; + dict = _PyDictOrValues_GetDict(*dorv_ptr); + if (dict == NULL) { + dictkeys_incref(CACHED_KEYS(tp)); + dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + dorv_ptr->dict = dict; + } } } else { - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr == NULL) { PyErr_SetString(PyExc_AttributeError, "This object has no __dict__"); diff --git a/Objects/object.c b/Objects/object.c index 758b79eff5b3e..f0c0434fab3d1 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1054,14 +1054,12 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) } PyObject ** -_PyObject_DictPointer(PyObject *obj) +_PyObject_ComputedDictPointer(PyObject *obj) { Py_ssize_t dictoffset; PyTypeObject *tp = Py_TYPE(obj); - if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - return _PyObject_ManagedDictPointer(obj); - } + assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); dictoffset = tp->tp_dictoffset; if (dictoffset == 0) return NULL; @@ -1086,22 +1084,18 @@ PyObject ** _PyObject_GetDictPtr(PyObject *obj) { if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - return _PyObject_DictPointer(obj); - } - PyObject **dict_ptr = _PyObject_ManagedDictPointer(obj); - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (*values_ptr == NULL) { - return dict_ptr; + return _PyObject_ComputedDictPointer(obj); } - assert(*dict_ptr == NULL); - PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - PyErr_Clear(); - return NULL; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, _PyDictOrValues_GetValues(*dorv_ptr)); + if (dict == NULL) { + PyErr_Clear(); + return NULL; + } + dorv_ptr->dict = dict; } - *values_ptr = NULL; - *dict_ptr = dict; - return dict_ptr; + return &dorv_ptr->dict; } PyObject * @@ -1170,36 +1164,46 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } } } - PyDictValues *values; - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && - (values = *_PyObject_ValuesPointer(obj))) - { - assert(*_PyObject_DictPointer(obj) == NULL); - PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); - if (attr != NULL) { - *method = attr; - Py_XDECREF(descr); - return 0; - } - } - else { - PyObject **dictptr = _PyObject_DictPointer(obj); - PyObject *dict; - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - PyObject *attr = PyDict_GetItemWithError(dict, name); + PyObject *dict; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); if (attr != NULL) { - *method = Py_NewRef(attr); - Py_DECREF(dict); + *method = attr; Py_XDECREF(descr); return 0; } + dict = NULL; + } + else { + dict = dorv_ptr->dict; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr != NULL) { + dict = *dictptr; + } + else { + dict = NULL; + } + } + if (dict != NULL) { + Py_INCREF(dict); + PyObject *attr = PyDict_GetItemWithError(dict, name); + if (attr != NULL) { + *method = Py_NewRef(attr); Py_DECREF(dict); + Py_XDECREF(descr); + return 0; + } + Py_DECREF(dict); - if (PyErr_Occurred()) { - Py_XDECREF(descr); - return 0; - } + if (PyErr_Occurred()) { + Py_XDECREF(descr); + return 0; } } @@ -1243,7 +1247,6 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *descr = NULL; PyObject *res = NULL; descrgetfunc f; - PyObject **dictptr; if (!PyUnicode_Check(name)){ PyErr_Format(PyExc_TypeError, @@ -1274,30 +1277,31 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && - *_PyObject_ValuesPointer(obj)) - { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (PyUnicode_CheckExact(name)) { - assert(*_PyObject_DictPointer(obj) == NULL); - res = _PyObject_GetInstanceAttribute(obj, *values_ptr, name); - if (res != NULL) { - goto done; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + if (PyUnicode_CheckExact(name)) { + res = _PyObject_GetInstanceAttribute(obj, values, name); + if (res != NULL) { + goto done; + } + } + else { + dict = _PyObject_MakeDictFromInstanceAttributes(obj, values); + if (dict == NULL) { + res = NULL; + goto done; + } + dorv_ptr->dict = dict; } } else { - dictptr = _PyObject_DictPointer(obj); - assert(dictptr != NULL && *dictptr == NULL); - *dictptr = dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - res = NULL; - goto done; - } - *values_ptr = NULL; + dict = _PyDictOrValues_GetDict(*dorv_ptr); } } else { - dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr) { dict = *dictptr; } @@ -1389,27 +1393,34 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && *_PyObject_ValuesPointer(obj)) { - res = _PyObject_StoreInstanceAttribute(obj, *_PyObject_ValuesPointer(obj), name, value); + PyObject **dictptr; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + res = _PyObject_StoreInstanceAttribute( + obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); + goto error_check; + } + dictptr = &dorv_ptr->dict; } else { - PyObject **dictptr = _PyObject_DictPointer(obj); - if (dictptr == NULL) { - if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - tp->tp_name, name); - } - else { - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - tp->tp_name, name); - } - goto done; + dictptr = _PyObject_ComputedDictPointer(obj); + } + if (dictptr == NULL) { + if (descr == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); } else { - res = _PyObjectDict_SetItem(tp, dictptr, name, value); + PyErr_Format(PyExc_AttributeError, + "'%.50s' object attribute '%U' is read-only", + tp->tp_name, name); } + goto done; + } + else { + res = _PyObjectDict_SetItem(tp, dictptr, name, value); } } else { @@ -1420,6 +1431,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, res = PyDict_SetItem(dict, name, value); Py_DECREF(dict); } + error_check: if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { if (PyType_IsSubtype(tp, &PyType_Type)) { PyErr_Format(PyExc_AttributeError, @@ -1451,7 +1463,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) PyObject **dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) && - *_PyObject_ValuesPointer(obj) != NULL) + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(obj))) { /* Was unable to convert to dict */ PyErr_NoMemory(); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e4adf1c4e12f8..d33befc05d7ab 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1310,15 +1310,13 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) } if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - assert(type->tp_dictoffset); - int err = _PyObject_VisitInstanceAttributes(self, visit, arg); + int err = _PyObject_VisitManagedDict(self, visit, arg); if (err) { return err; } } - - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + else if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr && *dictptr) Py_VISIT(*dictptr); } @@ -1379,10 +1377,10 @@ subtype_clear(PyObject *self) /* Clear the instance dict (if any), to break cycles involving only __dict__ slots (as in the case 'self.__dict__ is self'). */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - _PyObject_ClearInstanceAttributes(self); + _PyObject_ClearManagedDict(self); } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + else if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr && *dictptr) Py_CLEAR(*dictptr); } @@ -1526,18 +1524,17 @@ subtype_dealloc(PyObject *self) /* If we added a dict, DECREF it, or free inline values. */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyObject **dictptr = _PyObject_ManagedDictPointer(self); - if (*dictptr != NULL) { - assert(*_PyObject_ValuesPointer(self) == NULL); - Py_DECREF(*dictptr); - *dictptr = NULL; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(self); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + _PyObject_FreeInstanceAttributes(self); } else { - _PyObject_FreeInstanceAttributes(self); + Py_XDECREF(_PyDictOrValues_GetDict(*dorv_ptr)); } + dorv_ptr->values = NULL; } else if (type->tp_dictoffset && !base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr != NULL) { PyObject *dict = *dictptr; if (dict != NULL) { @@ -5137,7 +5134,9 @@ object_set_class(PyObject *self, PyObject *value, void *closure) * so we must materialize the dictionary first. */ assert((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == (newto->tp_flags & Py_TPFLAGS_MANAGED_DICT)); _PyObject_GetDictPtr(self); - if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && *_PyObject_ValuesPointer(self)) { + if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self))) + { /* Was unable to convert to dict */ PyErr_NoMemory(); return -1; diff --git a/Python/ceval.c b/Python/ceval.c index 7ad26a70dd18c..abb934d494f3e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3564,9 +3564,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); assert(tp->tp_dictoffset < 0); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues *values = *_PyObject_ValuesPointer(owner); - DEOPT_IF(values == NULL, LOAD_ATTR); - res = values->values[cache->index]; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + res = _PyDictOrValues_GetValues(dorv)->values[cache->index]; DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); @@ -3613,7 +3613,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); DEOPT_IF(dict == NULL, LOAD_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(names, oparg>>1); @@ -3750,12 +3752,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues *values = *_PyObject_ValuesPointer(owner); - DEOPT_IF(values == NULL, STORE_ATTR); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); STAT_INC(STORE_ATTR, hit); Py_ssize_t index = cache->index; STACK_SHRINK(1); PyObject *value = POP(); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyObject *old_value = values->values[index]; values->values[index] = value; if (old_value == NULL) { @@ -3778,7 +3781,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); DEOPT_IF(dict == NULL, STORE_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(names, oparg); @@ -4680,8 +4685,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(type_version != 0); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self); - DEOPT_IF(dict != NULL, LOAD_ATTR); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != read_u32(cache->keys_version), LOAD_ATTR); diff --git a/Python/specialize.c b/Python/specialize.c index 53b2ae82b9836..d5877a191a10c 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -635,9 +635,8 @@ specialize_dict_access( return 0; } _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); - PyObject **dictptr = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = (PyDictObject *)*dictptr; - if (dict == NULL) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + if (_PyDictOrValues_IsValues(dorv)) { // Virtual dictionary PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; assert(PyUnicode_CheckExact(name)); @@ -652,7 +651,8 @@ specialize_dict_access( _Py_SET_OPCODE(*instr, values_op); } else { - if (!PyDict_CheckExact(dict)) { + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + if (dict == NULL || !PyDict_CheckExact(dict)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); return 0; } @@ -995,9 +995,9 @@ PyObject *descr, DescriptorClassification kind) ObjectDictKind dictkind; PyDictKeysObject *keys; if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyObject *dict = *_PyObject_ManagedDictPointer(owner); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; - if (dict == NULL) { + if (_PyDictOrValues_IsValues(dorv)) { dictkind = MANAGED_VALUES; } else { diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 80563ea59ec4b..d03c637912583 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -489,6 +489,8 @@ def get_attr_dict(self): dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer() dictptr = dictptr.cast(PyObjectPtrPtr) + if int(dictptr.dereference()) & 1: + return None return PyObjectPtr.from_pyobject_ptr(dictptr.dereference()) except RuntimeError: # Corrupt data somewhere; fail safe @@ -502,12 +504,14 @@ def get_keys_values(self): has_values = int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT if not has_values: return None - PyDictValuesPtrPtr = gdb.lookup_type("PyDictValues").pointer().pointer() - valuesptr = self._gdbval.cast(PyDictValuesPtrPtr) - 4 - values = valuesptr.dereference() - if int(values) == 0: + charptrptr_t = _type_char_ptr().pointer() + ptr = self._gdbval.cast(charptrptr_t) - 3 + char_ptr = ptr.dereference() + if (int(char_ptr) & 1) == 0: return None - values = values['values'] + char_ptr += 1 + values_ptr = char_ptr.cast(gdb.lookup_type("PyDictValues").pointer()) + values = values_ptr['values'] return PyKeysValuesPair(self.get_cached_keys(), values) def get_cached_keys(self): @@ -527,14 +531,15 @@ def proxyval(self, visited): return ProxyAlreadyVisited('<...>') visited.add(self.as_address()) - pyop_attr_dict = self.get_attr_dict() keys_values = self.get_keys_values() if keys_values: attr_dict = keys_values.proxyval(visited) - elif pyop_attr_dict: - attr_dict = pyop_attr_dict.proxyval(visited) else: - attr_dict = {} + pyop_attr_dict = self.get_attr_dict() + if pyop_attr_dict: + attr_dict = pyop_attr_dict.proxyval(visited) + else: + attr_dict = {} tp_name = self.safe_tp_name() # Class: From webhook-mailer at python.org Mon Aug 1 10:38:00 2022 From: webhook-mailer at python.org (pablogsal) Date: Mon, 01 Aug 2022 14:38:00 -0000 Subject: [Python-checkins] [3.11] gh-95174: Add pthread stubs for WASI (GH-95234) (#95503) Message-ID: https://github.com/python/cpython/commit/e62a0dfab2bbc29324ca1879e287fff7fa8f21e0 commit: e62a0dfab2bbc29324ca1879e287fff7fa8f21e0 branch: 3.11 author: Christian Heimes committer: pablogsal date: 2022-08-01T15:37:45+01:00 summary: [3.11] gh-95174: Add pthread stubs for WASI (GH-95234) (#95503) Co-authored-by: Brett Cannon . (cherry picked from commit 0fe645d6fd22a6f57e777a29e65cf9a4ff9785ae) Co-authored-by: Christian Heimes files: A Include/cpython/pthread_stubs.h A Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst A Python/thread_pthread_stubs.h M Doc/library/sys.rst M Include/cpython/pythread.h M Lib/test/pythoninfo.py M Lib/test/test_sys.py M Lib/test/test_threadsignals.py M Makefile.pre.in M Python/thread.c M Python/thread_pthread.h M Tools/wasm/README.md M Tools/wasm/config.site-wasm32-wasi M Tools/wasm/wasi-env M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index d3e569c6de3c6..632ce627d86f9 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1658,6 +1658,8 @@ always available. | | | | | * ``'nt'``: Windows threads | | | * ``'pthread'``: POSIX threads | + | | * ``'pthread-stubs'``: stub POSIX threads | + | | (on WebAssembly platforms without threading support) | | | * ``'solaris'``: Solaris threads | +------------------+---------------------------------------------------------+ | :const:`lock` | Name of the lock implementation: | diff --git a/Include/cpython/pthread_stubs.h b/Include/cpython/pthread_stubs.h new file mode 100644 index 0000000000000..d95ee03d8308c --- /dev/null +++ b/Include/cpython/pthread_stubs.h @@ -0,0 +1,88 @@ +#ifndef Py_CPYTHON_PTRHEAD_STUBS_H +#define Py_CPYTHON_PTRHEAD_STUBS_H + +#if !defined(HAVE_PTHREAD_STUBS) +# error "this header file requires stubbed pthreads." +#endif + +#ifndef _POSIX_THREADS +# define _POSIX_THREADS 1 +#endif + +/* Minimal pthread stubs for CPython. + * + * The stubs implement the minimum pthread API for CPython. + * - pthread_create() fails. + * - pthread_exit() calls exit(0). + * - pthread_key_*() functions implement minimal TSS without destructor. + * - all other functions do nothing and return 0. + */ + +#ifdef __wasi__ +// WASI's bits/alltypes.h provides type definitions when __NEED_ is set. +// The header file can be included multiple times. +# define __NEED_pthread_cond_t 1 +# define __NEED_pthread_condattr_t 1 +# define __NEED_pthread_mutex_t 1 +# define __NEED_pthread_mutexattr_t 1 +# define __NEED_pthread_key_t 1 +# define __NEED_pthread_t 1 +# define __NEED_pthread_attr_t 1 +# include +#else +typedef struct { void *__x; } pthread_cond_t; +typedef struct { unsigned __attr; } pthread_condattr_t; +typedef struct { void *__x; } pthread_mutex_t; +typedef struct { unsigned __attr; } pthread_mutexattr_t; +typedef unsigned pthread_key_t; +typedef unsigned pthread_t; +typedef struct { unsigned __attr; } pthread_attr_t; +#endif + +// mutex +PyAPI_FUNC(int) pthread_mutex_init(pthread_mutex_t *restrict mutex, + const pthread_mutexattr_t *restrict attr); +PyAPI_FUNC(int) pthread_mutex_destroy(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_trylock(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_lock(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_unlock(pthread_mutex_t *mutex); + +// condition +PyAPI_FUNC(int) pthread_cond_init(pthread_cond_t *restrict cond, + const pthread_condattr_t *restrict attr); +PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond); +PyAPI_FUNC(int) pthread_cond_wait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex); +PyAPI_FUNC(int) pthread_cond_timedwait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime); +PyAPI_FUNC(int) pthread_cond_signal(pthread_cond_t *cond); +PyAPI_FUNC(int) pthread_condattr_init(pthread_condattr_t *attr); +PyAPI_FUNC(int) pthread_condattr_setclock( + pthread_condattr_t *attr, clockid_t clock_id); + +// pthread +PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void *), + void *restrict arg); +PyAPI_FUNC(int) pthread_detach(pthread_t thread); +PyAPI_FUNC(pthread_t) pthread_self(void); +PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__)); +PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr); +PyAPI_FUNC(int) pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +PyAPI_FUNC(int) pthread_attr_destroy(pthread_attr_t *attr); + + +// pthread_key +#ifndef PTHREAD_KEYS_MAX +# define PTHREAD_KEYS_MAX 128 +#endif + +PyAPI_FUNC(int) pthread_key_create(pthread_key_t *key, + void (*destr_function)(void *)); +PyAPI_FUNC(int) pthread_key_delete(pthread_key_t key); +PyAPI_FUNC(void *) pthread_getspecific(pthread_key_t key); +PyAPI_FUNC(int) pthread_setspecific(pthread_key_t key, const void *value); + +#endif // Py_CPYTHON_PTRHEAD_STUBS_H diff --git a/Include/cpython/pythread.h b/Include/cpython/pythread.h index 1fd86a6a90f9a..ce4ec8f65b15e 100644 --- a/Include/cpython/pythread.h +++ b/Include/cpython/pythread.h @@ -20,6 +20,9 @@ PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock); but hardcode the unsigned long to avoid errors for include directive. */ # define NATIVE_TSS_KEY_T unsigned long +#elif defined(HAVE_PTHREAD_STUBS) +# include "cpython/pthread_stubs.h" +# define NATIVE_TSS_KEY_T pthread_key_t #else # error "Require native threads. See https://bugs.python.org/issue31370" #endif diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 2339e0049ef6e..61fd734d4c605 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -588,8 +588,8 @@ def collect_socket(info_add): try: hostname = socket.gethostname() - except OSError: - # WASI SDK 15.0 does not have gethostname(2). + except (OSError, AttributeError): + # WASI SDK 16.0 does not have gethostname(2). if sys.platform != "wasi": raise else: diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 26e0f2082ea2f..c513cf08a116d 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -626,7 +626,7 @@ def test_attributes(self): def test_thread_info(self): info = sys.thread_info self.assertEqual(len(info), 3) - self.assertIn(info.name, ('nt', 'pthread', 'solaris', None)) + self.assertIn(info.name, ('nt', 'pthread', 'pthread-stubs', 'solaris', None)) self.assertIn(info.lock, ('semaphore', 'mutex+cond', None)) @unittest.skipUnless(support.is_emscripten, "only available on Emscripten") diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py index e0ac18c946398..6a53d655015cd 100644 --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -36,7 +36,9 @@ def send_signals(): os.kill(process_pid, signal.SIGUSR2) signalled_all.release() + @threading_helper.requires_working_threading() + at unittest.skipUnless(hasattr(signal, "alarm"), "test requires signal.alarm") class ThreadSignals(unittest.TestCase): def test_signals(self): diff --git a/Makefile.pre.in b/Makefile.pre.in index e145315c45ca6..8fbcd7ac170af 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1573,6 +1573,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/objimpl.h \ $(srcdir)/Include/cpython/odictobject.h \ $(srcdir)/Include/cpython/picklebufobject.h \ + $(srcdir)/Include/cpython/pthread_stubs.h \ $(srcdir)/Include/cpython/pyctype.h \ $(srcdir)/Include/cpython/pydebug.h \ $(srcdir)/Include/cpython/pyerrors.h \ diff --git a/Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst b/Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst new file mode 100644 index 0000000000000..c751b5e3adc47 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst @@ -0,0 +1,2 @@ +wasm32-wasi builds no longer depend on WASIX's pthread stubs. Python now has +its own stubbed pthread API. diff --git a/Python/thread.c b/Python/thread.c index e80e8a906bc8e..08bcdda0483d7 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -93,8 +93,15 @@ _PyThread_debug_deprecation(void) #endif } -#if defined(_POSIX_THREADS) -# define PYTHREAD_NAME "pthread" +#if defined(HAVE_PTHREAD_STUBS) +# define PYTHREAD_NAME "pthread-stubs" +# include "thread_pthread_stubs.h" +#elif defined(_POSIX_THREADS) +# if defined(__EMSCRIPTEN__) || !defined(__EMSCRIPTEN_PTHREADS__) +# define PYTHREAD_NAME "pthread-stubs" +# else +# define PYTHREAD_NAME "pthread" +# endif # include "thread_pthread.h" #elif defined(NT_THREADS) # define PYTHREAD_NAME "nt" @@ -208,7 +215,9 @@ PyThread_GetInfo(void) } PyStructSequence_SET_ITEM(threadinfo, pos++, value); -#ifdef _POSIX_THREADS +#ifdef HAVE_PTHREAD_STUBS + value = Py_NewRef(Py_None); +#elif defined(_POSIX_THREADS) #ifdef USE_SEMAPHORES value = PyUnicode_FromString("semaphore"); #else @@ -219,8 +228,7 @@ PyThread_GetInfo(void) return NULL; } #else - Py_INCREF(Py_None); - value = Py_None; + value = Py_NewRef(Py_None); #endif PyStructSequence_SET_ITEM(threadinfo, pos++, value); diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 02c8427729545..ddc28c48c025e 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -7,7 +7,9 @@ #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) #define destructor xxdestructor #endif -#include +#ifndef HAVE_PTHREAD_STUBS +# include +#endif #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) #undef destructor #endif diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h new file mode 100644 index 0000000000000..8b80c0f87e250 --- /dev/null +++ b/Python/thread_pthread_stubs.h @@ -0,0 +1,185 @@ +#include "cpython/pthread_stubs.h" + +// mutex +int +pthread_mutex_init(pthread_mutex_t *restrict mutex, + const pthread_mutexattr_t *restrict attr) +{ + return 0; +} + +int +pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return 0; +} + +int +pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + return 0; +} + +int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return 0; +} + +int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return 0; +} + +// condition +int +pthread_cond_init(pthread_cond_t *restrict cond, + const pthread_condattr_t *restrict attr) +{ + return 0; +} + +PyAPI_FUNC(int)pthread_cond_destroy(pthread_cond_t *cond) +{ + return 0; +} + +int +pthread_cond_wait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex) +{ + return 0; +} + +int +pthread_cond_timedwait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime) +{ + return 0; +} + +int +pthread_cond_signal(pthread_cond_t *cond) +{ + return 0; +} + +int +pthread_condattr_init(pthread_condattr_t *attr) +{ + return 0; +} + +int +pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id) +{ + return 0; +} + +// pthread +int +pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void *), + void *restrict arg) +{ + return EAGAIN; +} + +int +pthread_detach(pthread_t thread) +{ + return 0; +} + +PyAPI_FUNC(pthread_t) pthread_self(void) +{ + return 0; +} + +int +pthread_exit(void *retval) +{ + exit(0); +} + +int +pthread_attr_init(pthread_attr_t *attr) +{ + return 0; +} + +int +pthread_attr_setstacksize( + pthread_attr_t *attr, size_t stacksize) +{ + return 0; +} + +int +pthread_attr_destroy(pthread_attr_t *attr) +{ + return 0; +} + +// pthread_key +typedef struct { + bool in_use; + void *value; +} py_tls_entry; + +static py_tls_entry py_tls_entries[PTHREAD_KEYS_MAX] = {0}; + +int +pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) +{ + if (!key) { + return EINVAL; + } + if (destr_function != NULL) { + Py_FatalError("pthread_key_create destructor is not supported"); + } + for (pthread_key_t idx = 0; idx < PTHREAD_KEYS_MAX; idx++) { + if (!py_tls_entries[idx].in_use) { + py_tls_entries[idx].in_use = true; + *key = idx; + return 0; + } + } + return EAGAIN; +} + +int +pthread_key_delete(pthread_key_t key) +{ + if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { + return EINVAL; + } + py_tls_entries[key].in_use = false; + py_tls_entries[key].value = NULL; + return 0; +} + + +void * +pthread_getspecific(pthread_key_t key) { + if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { + return NULL; + } + return py_tls_entries[key].value; +} + +int +pthread_setspecific(pthread_key_t key, const void *value) +{ + if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { + return EINVAL; + } + py_tls_entries[key].value = (void *)value; + return 0; +} + +// let thread_pthread define the Python API +#include "thread_pthread.h" diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index d08e807f565b2..6496a29e6ff80 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -226,16 +226,13 @@ AddType application/wasm wasm # WASI (wasm32-wasi) -WASI builds require [WASI SDK](https://github.com/WebAssembly/wasi-sdk) 15.0+ -and currently [wasix](https://github.com/singlestore-labs/wasix) for POSIX -compatibility stubs. +WASI builds require [WASI SDK](https://github.com/WebAssembly/wasi-sdk) 16.0+. ## Cross-compile to wasm32-wasi The script ``wasi-env`` sets necessary compiler and linker flags as well as ``pkg-config`` overrides. The script assumes that WASI-SDK is installed in -``/opt/wasi-sdk`` or ``$WASI_SDK_PATH`` and WASIX is installed in -``/opt/wasix`` or ``$WASIX_PATH``. +``/opt/wasi-sdk`` or ``$WASI_SDK_PATH``. ```shell mkdir -p builddir/wasi @@ -434,21 +431,15 @@ rm -f wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz ### Install [wasmtime](https://github.com/bytecodealliance/wasmtime) WASI runtime -**NOTE**: wasmtime 0.37 has a bug. Newer versions should be fine again. +wasmtime 0.38 or newer is required. ```shell curl -sSf -L -o ~/install-wasmtime.sh https://wasmtime.dev/install.sh chmod +x ~/install-wasmtime.sh -~/install-wasmtime.sh --version v0.36.0 +~/install-wasmtime.sh --version v0.38.0 ln -srf -t /usr/local/bin/ ~/.wasmtime/bin/wasmtime ``` -### Install [WASIX](https://github.com/singlestore-labs/wasix) - -```shell -git clone https://github.com/singlestore-labs/wasix.git ~/wasix -make install -C ~/wasix -``` ### WASI debugging diff --git a/Tools/wasm/config.site-wasm32-wasi b/Tools/wasm/config.site-wasm32-wasi index 237fa8b55624c..893a0d132cda5 100644 --- a/Tools/wasm/config.site-wasm32-wasi +++ b/Tools/wasm/config.site-wasm32-wasi @@ -32,14 +32,6 @@ ac_cv_func_makedev=no # OSError: [Errno 28] Invalid argument: '.' ac_cv_func_fdopendir=no -# WASIX stubs we don't want to use. -ac_cv_func_kill=no - -# WASI SDK 15.0 does not have chmod. -# Ignore WASIX stubs for now. -ac_cv_func_chmod=no -ac_cv_func_fchmod=no - # WASI sockets are limited to operations on given socket fd and inet sockets. # Disable AF_UNIX and AF_PACKET support, see socketmodule.h. ac_cv_header_sys_un_h=no diff --git a/Tools/wasm/wasi-env b/Tools/wasm/wasi-env index 06c54e6823d41..6c2d56e0e5e32 100755 --- a/Tools/wasm/wasi-env +++ b/Tools/wasm/wasi-env @@ -31,7 +31,6 @@ fi WASI_SDK_PATH="${WASI_SDK_PATH:-/opt/wasi-sdk}" WASI_SYSROOT="${WASI_SDK_PATH}/share/wasi-sysroot" -WASIX_PATH="${WASIX_PATH:-/opt/wasix}" if ! test -x "${WASI_SDK_PATH}/bin/clang"; then echo "Error: ${WASI_SDK_PATH}/bin/clang does not exist." >&2 @@ -65,12 +64,6 @@ PKG_CONFIG_PATH="" PKG_CONFIG_LIBDIR="${WASI_SYSROOT}/lib/pkgconfig:${WASI_SYSROOT}/share/pkgconfig" PKG_CONFIG_SYSROOT_DIR="${WASI_SYSROOT}" -# add WASIX (POSIX stubs for WASI) if WASIX is installed -if test -f "${WASIX_PATH}/lib/libwasix.a"; then - CFLAGS="${CFLAGS} -isystem ${WASIX_PATH}/include" - LDFLAGS="${LDFLAGS} -L${WASIX_PATH}/lib -lwasix" -fi - PATH="${WASI_SDK_PATH}/bin:${PATH}" export WASI_SDK_PATH WASI_SYSROOT diff --git a/configure b/configure index 66915270750b2..91227f00befc6 100755 --- a/configure +++ b/configure @@ -14153,11 +14153,16 @@ if test "x$ac_cv_lib_cma_pthread_create" = xyes; then : else + case $ac_sys_system in #( + WASI) : + posix_threads=stub ;; #( + *) : as_fn_error $? "could not find pthreads on your system" "$LINENO" 5 + ;; +esac fi - fi fi @@ -14313,6 +14318,14 @@ _ACEOF fi done +fi + +if test "x$posix_threads" = xstub; then : + + +$as_echo "#define HAVE_PTHREAD_STUBS 1" >>confdefs.h + + fi # Check for enable-ipv6 diff --git a/configure.ac b/configure.ac index 443637962def9..77fb609b74d56 100644 --- a/configure.ac +++ b/configure.ac @@ -4092,9 +4092,11 @@ pthread_create (NULL, NULL, start_routine, NULL)]])],[ posix_threads=yes LIBS="$LIBS -lcma" ],[ - AC_MSG_ERROR([could not find pthreads on your system]) - ]) - ])])])])]) + AS_CASE([$ac_sys_system], + [WASI], [posix_threads=stub], + [AC_MSG_ERROR([could not find pthreads on your system])] + ) + ])])])])])]) AC_CHECK_LIB(mpc, usconfig, [ LIBS="$LIBS -lmpc" @@ -4157,6 +4159,10 @@ if test "$posix_threads" = "yes"; then AC_CHECK_FUNCS(pthread_getcpuclockid) fi +AS_VAR_IF([posix_threads], [stub], [ + AC_DEFINE([HAVE_PTHREAD_STUBS], [1], [Define if platform requires stubbed pthreads support]) +]) + # Check for enable-ipv6 AH_TEMPLATE(ENABLE_IPV6, [Define if --enable-ipv6 is specified]) AC_MSG_CHECKING([if --enable-ipv6 is specified]) diff --git a/pyconfig.h.in b/pyconfig.h.in index dcbe703e77aec..75f1d90e9bd37 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -926,6 +926,9 @@ /* Define to 1 if you have the `pthread_sigmask' function. */ #undef HAVE_PTHREAD_SIGMASK +/* Define if platform requires stubbed pthreads support */ +#undef HAVE_PTHREAD_STUBS + /* Define to 1 if you have the header file. */ #undef HAVE_PTY_H From webhook-mailer at python.org Mon Aug 1 11:06:48 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 01 Aug 2022 15:06:48 -0000 Subject: [Python-checkins] no-issue: Fix typo of "thrid" instead of "third" in dis docs (gh-95510) Message-ID: https://github.com/python/cpython/commit/d965d1995ec3efbbf666c2e7fab02217744d08e7 commit: d965d1995ec3efbbf666c2e7fab02217744d08e7 branch: main author: Alex Hedges committer: corona10 date: 2022-08-02T00:06:43+09:00 summary: no-issue: Fix typo of "thrid" instead of "third" in dis docs (gh-95510) files: M Doc/library/dis.rst diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 85bd94b4eae94..68c3d1c0a4b24 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -449,7 +449,7 @@ result back on the stack. **Binary and in-place operations** In the following, TOS is the top-of-stack. -TOS1, TOS2, TOS3 are the second, thrid and fourth items on the stack, respectively. +TOS1, TOS2, TOS3 are the second, third and fourth items on the stack, respectively. Binary operations remove the top two items from the stack (TOS and TOS1). They perform the operation, then put the result back on the stack. From webhook-mailer at python.org Mon Aug 1 11:37:42 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 01 Aug 2022 15:37:42 -0000 Subject: [Python-checkins] gh-95445: Ensure Windows msi uninstalls document folder successfully (GH-95465) Message-ID: https://github.com/python/cpython/commit/7d8973870bb079bf71d094cd966d6b6336f1e25f commit: 7d8973870bb079bf71d094cd966d6b6336f1e25f branch: main author: neonene <53406459+neonene at users.noreply.github.com> committer: zooba date: 2022-08-01T16:37:32+01:00 summary: gh-95445: Ensure Windows msi uninstalls document folder successfully (GH-95465) files: A Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst M Tools/msi/doc/doc.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst b/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst new file mode 100644 index 0000000000000..565489ebf909d --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst @@ -0,0 +1 @@ +Fixes the unsuccessful removal of the HTML document directory when uninstalling with Windows msi. diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index e80fff43418bb..49798c752633f 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -17,6 +17,11 @@ + + + + + From webhook-mailer at python.org Mon Aug 1 12:02:14 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 01 Aug 2022 16:02:14 -0000 Subject: [Python-checkins] gh-95173: Add a regression test for sorting tuples containing None (#95464) Message-ID: https://github.com/python/cpython/commit/c0cd79021951b3ab10804d42b3963b9fb1a66be7 commit: c0cd79021951b3ab10804d42b3963b9fb1a66be7 branch: main author: Jacob Walls committer: erlend-aasland date: 2022-08-01T18:02:09+02:00 summary: gh-95173: Add a regression test for sorting tuples containing None (#95464) files: M Lib/test/test_sort.py diff --git a/Lib/test/test_sort.py b/Lib/test/test_sort.py index 41de4b684f625..3b6ad4d17b041 100644 --- a/Lib/test/test_sort.py +++ b/Lib/test/test_sort.py @@ -378,6 +378,12 @@ def test_not_all_tuples(self): self.assertRaises(TypeError, [(1.0, 1.0), (False, "A"), 6].sort) self.assertRaises(TypeError, [('a', 1), (1, 'a')].sort) self.assertRaises(TypeError, [(1, 'a'), ('a', 1)].sort) + + def test_none_in_tuples(self): + expected = [(None, 1), (None, 2)] + actual = sorted([(None, 2), (None, 1)]) + self.assertEqual(actual, expected) + #============================================================================== if __name__ == "__main__": From webhook-mailer at python.org Mon Aug 1 12:07:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 16:07:38 -0000 Subject: [Python-checkins] gh-95445: Ensure Windows msi uninstalls document folder successfully (GH-95465) Message-ID: https://github.com/python/cpython/commit/3192fd7683ad979d7f5ba996801da474c1606786 commit: 3192fd7683ad979d7f5ba996801da474c1606786 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T09:07:24-07:00 summary: gh-95445: Ensure Windows msi uninstalls document folder successfully (GH-95465) (cherry picked from commit 7d8973870bb079bf71d094cd966d6b6336f1e25f) Co-authored-by: neonene <53406459+neonene at users.noreply.github.com> files: A Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst M Tools/msi/doc/doc.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst b/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst new file mode 100644 index 0000000000000..565489ebf909d --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst @@ -0,0 +1 @@ +Fixes the unsuccessful removal of the HTML document directory when uninstalling with Windows msi. diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index e80fff43418bb..49798c752633f 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -17,6 +17,11 @@ + + + + + From webhook-mailer at python.org Mon Aug 1 12:30:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 16:30:08 -0000 Subject: [Python-checkins] gh-95173: Add a regression test for sorting tuples containing None (GH-95464) Message-ID: https://github.com/python/cpython/commit/76d83b1dfe4c7be04f51bbdb01f3b82df83f8958 commit: 76d83b1dfe4c7be04f51bbdb01f3b82df83f8958 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T09:29:57-07:00 summary: gh-95173: Add a regression test for sorting tuples containing None (GH-95464) (cherry picked from commit c0cd79021951b3ab10804d42b3963b9fb1a66be7) Co-authored-by: Jacob Walls files: M Lib/test/test_sort.py diff --git a/Lib/test/test_sort.py b/Lib/test/test_sort.py index 41de4b684f625..3b6ad4d17b041 100644 --- a/Lib/test/test_sort.py +++ b/Lib/test/test_sort.py @@ -378,6 +378,12 @@ def test_not_all_tuples(self): self.assertRaises(TypeError, [(1.0, 1.0), (False, "A"), 6].sort) self.assertRaises(TypeError, [('a', 1), (1, 'a')].sort) self.assertRaises(TypeError, [(1, 'a'), ('a', 1)].sort) + + def test_none_in_tuples(self): + expected = [(None, 1), (None, 2)] + actual = sorted([(None, 2), (None, 1)]) + self.assertEqual(actual, expected) + #============================================================================== if __name__ == "__main__": From webhook-mailer at python.org Mon Aug 1 12:30:20 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 01 Aug 2022 16:30:20 -0000 Subject: [Python-checkins] gh-95417: Quick fix for "ULONG_PTR differs in levels of indirection from void *" (GH-95538) Message-ID: https://github.com/python/cpython/commit/858c9a58bf56cefc792bf0eb1ba22984b7b2d150 commit: 858c9a58bf56cefc792bf0eb1ba22984b7b2d150 branch: main author: Oleg Iarygin committer: zooba date: 2022-08-01T17:30:15+01:00 summary: gh-95417: Quick fix for "ULONG_PTR differs in levels of indirection from void *" (GH-95538) files: M Modules/clinic/overlapped.c.h M Modules/overlapped.c diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 721b38c75ceef..1c216633eb95f 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -37,7 +37,7 @@ _overlapped_CreateIoCompletionPort(PyObject *module, PyObject *const *args, Py_s if (!ExistingCompletionPort && PyErr_Occurred()) { goto exit; } - CompletionKey = PyLong_AsVoidPtr(args[2]); + CompletionKey = (uintptr_t)PyLong_AsVoidPtr(args[2]); if (!CompletionKey && PyErr_Occurred()) { goto exit; } @@ -124,7 +124,7 @@ _overlapped_PostQueuedCompletionStatus(PyObject *module, PyObject *const *args, if (!_PyLong_UnsignedLong_Converter(args[1], &NumberOfBytes)) { goto exit; } - CompletionKey = PyLong_AsVoidPtr(args[2]); + CompletionKey = (uintptr_t)PyLong_AsVoidPtr(args[2]); if (!CompletionKey && PyErr_Occurred()) { goto exit; } @@ -1225,4 +1225,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=d90cda84e49a7c23 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=edd05b7a6c9c3aac input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 0cec9eedc87f0..369b1beae84e3 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -52,13 +52,21 @@ class HANDLE_converter(pointer_converter): class ULONG_PTR_converter(pointer_converter): type = 'ULONG_PTR' + def parse_arg(self, argname, displayname): + return """ + {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + class DWORD_converter(unsigned_long_converter): type = 'DWORD' class BOOL_converter(int_converter): type = 'BOOL' [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=a19133a9e14fae9c]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=8a07ea3018f4cec8]*/ /*[clinic input] module _overlapped From webhook-mailer at python.org Mon Aug 1 12:52:53 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 16:52:53 -0000 Subject: [Python-checkins] gh-91447: Fix findtext to only give an empty string on None (GH-91486) Message-ID: https://github.com/python/cpython/commit/a95e60db748ec6f2c19b5710c11f62e1e4d669f4 commit: a95e60db748ec6f2c19b5710c11f62e1e4d669f4 branch: main author: Eugene Triguba committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T09:52:39-07:00 summary: gh-91447: Fix findtext to only give an empty string on None (GH-91486) The API documentation for [findtext](https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findtext) states that this function gives back an empty string on "no text content." With the previous implementation, this would give back a empty string even on text content values such as 0 or False. This patch attempts to resolve that by only giving back an empty string if the text attribute is set to `None`. Resolves #91447. Automerge-Triggered-By: GH:gvanrossum files: A Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst M Lib/test/test_xml_etree.py M Lib/xml/etree/ElementPath.py diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 839955695b800..ee3154e99f32b 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2705,6 +2705,20 @@ def test_findtext_with_error(self): except ZeroDivisionError: pass + def test_findtext_with_falsey_text_attribute(self): + root_elem = ET.Element('foo') + sub_elem = ET.SubElement(root_elem, 'bar') + falsey = ["", 0, False, [], (), {}] + for val in falsey: + sub_elem.text = val + self.assertEqual(root_elem.findtext('./bar'), val) + + def test_findtext_with_none_text_attribute(self): + root_elem = ET.Element('foo') + sub_elem = ET.SubElement(root_elem, 'bar') + sub_elem.text = None + self.assertEqual(root_elem.findtext('./bar'), '') + def test_findall_with_mutating(self): e = ET.Element('foo') e.extend([ET.Element('bar')]) diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py index cd3c354d0813e..dc6bd28c03137 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -416,6 +416,8 @@ def findall(elem, path, namespaces=None): def findtext(elem, path, default=None, namespaces=None): try: elem = next(iterfind(elem, path, namespaces)) - return elem.text or "" + if elem.text is None: + return "" + return elem.text except StopIteration: return default diff --git a/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst b/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst new file mode 100644 index 0000000000000..6f9be2d3e9be4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst @@ -0,0 +1,2 @@ +Fix findtext in the xml module to only give an empty string when the text +attribute is set to None. From webhook-mailer at python.org Mon Aug 1 14:03:03 2022 From: webhook-mailer at python.org (brandtbucher) Date: Mon, 01 Aug 2022 18:03:03 -0000 Subject: [Python-checkins] GH-95150: Use position and exception tables for code hashing and equality (GH-95509) Message-ID: https://github.com/python/cpython/commit/c7e5bbaee88a71dc6e633e3cd451ed1798436382 commit: c7e5bbaee88a71dc6e633e3cd451ed1798436382 branch: main author: Brandt Bucher committer: brandtbucher date: 2022-08-01T11:02:56-07:00 summary: GH-95150: Use position and exception tables for code hashing and equality (GH-95509) files: A Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst M Lib/test/test_code.py M Lib/test/test_compile.py M Lib/test/test_syntax.py M Objects/codeobject.c diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index fd68f6dee7915..2386cf6b59f39 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -428,6 +428,27 @@ def func(): self.assertIsNone(line) self.assertEqual(end_line, new_code.co_firstlineno + 1) + def test_code_equality(self): + def f(): + try: + a() + except: + b() + else: + c() + finally: + d() + code_a = f.__code__ + code_b = code_a.replace(co_linetable=b"") + code_c = code_a.replace(co_exceptiontable=b"") + code_d = code_b.replace(co_exceptiontable=b"") + self.assertNotEqual(code_a, code_b) + self.assertNotEqual(code_a, code_c) + self.assertNotEqual(code_a, code_d) + self.assertNotEqual(code_b, code_c) + self.assertNotEqual(code_b, code_d) + self.assertNotEqual(code_c, code_d) + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1]) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index e6194460b787d..c64e4e55f4445 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -615,7 +615,7 @@ def check_same_constant(const): exec(code, ns) f1 = ns['f1'] f2 = ns['f2'] - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, const) self.assertEqual(repr(f1()), repr(const)) @@ -628,7 +628,7 @@ def check_same_constant(const): # Note: "lambda: ..." emits "LOAD_CONST Ellipsis", # whereas "lambda: Ellipsis" emits "LOAD_GLOBAL Ellipsis" f1, f2 = lambda: ..., lambda: ... - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, Ellipsis) self.assertEqual(repr(f1()), repr(Ellipsis)) @@ -643,7 +643,7 @@ def check_same_constant(const): # {0} is converted to a constant frozenset({0}) by the peephole # optimizer f1, f2 = lambda x: x in {0}, lambda x: x in {0} - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, frozenset({0})) self.assertTrue(f1(0)) @@ -1302,6 +1302,27 @@ def f(): self.assertIsNotNone(end_column) self.assertLessEqual((line, column), (end_line, end_column)) + @support.cpython_only + def test_column_offset_deduplication(self): + # GH-95150: Code with different column offsets shouldn't be merged! + for source in [ + "lambda: a", + "(a for b in c)", + "[a for b in c]", + "{a for b in c}", + "{a: b for c in d}", + ]: + with self.subTest(source): + code = compile(f"{source}, {source}", "", "eval") + self.assertEqual(len(code.co_consts), 2) + self.assertIsInstance(code.co_consts[0], types.CodeType) + self.assertIsInstance(code.co_consts[1], types.CodeType) + self.assertNotEqual(code.co_consts[0], code.co_consts[1]) + self.assertNotEqual( + list(code.co_consts[0].co_positions()), + list(code.co_consts[1].co_positions()), + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index b22a96b20298d..ae1066924b3cf 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2012,7 +2012,8 @@ def fib(n): a, b = 0, 1 """ try: - self.assertEqual(compile(s1, '', 'exec'), compile(s2, '', 'exec')) + compile(s1, '', 'exec') + compile(s2, '', 'exec') except SyntaxError: self.fail("Indented statement over multiple lines is valid") diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst new file mode 100644 index 0000000000000..c3db4714188b3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst @@ -0,0 +1,3 @@ +Update code object hashing and equality to consider all debugging and +exception handling tables. This fixes an issue where certain non-identical +code objects could be "deduplicated" during compilation. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 2f757c4d8a986..7ebbfdbdec18b 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1695,6 +1695,15 @@ code_richcompare(PyObject *self, PyObject *other, int op) eq = PyObject_RichCompareBool(co->co_localsplusnames, cp->co_localsplusnames, Py_EQ); if (eq <= 0) goto unequal; + eq = PyObject_RichCompareBool(co->co_linetable, cp->co_linetable, Py_EQ); + if (eq <= 0) { + goto unequal; + } + eq = PyObject_RichCompareBool(co->co_exceptiontable, + cp->co_exceptiontable, Py_EQ); + if (eq <= 0) { + goto unequal; + } if (op == Py_EQ) res = Py_True; @@ -1727,7 +1736,15 @@ code_hash(PyCodeObject *co) if (h2 == -1) return -1; h3 = PyObject_Hash(co->co_localsplusnames); if (h3 == -1) return -1; - h = h0 ^ h1 ^ h2 ^ h3 ^ + Py_hash_t h4 = PyObject_Hash(co->co_linetable); + if (h4 == -1) { + return -1; + } + Py_hash_t h5 = PyObject_Hash(co->co_exceptiontable); + if (h5 == -1) { + return -1; + } + h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ co->co_flags; if (h == -1) h = -2; From webhook-mailer at python.org Mon Aug 1 14:33:59 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 18:33:59 -0000 Subject: [Python-checkins] GH-95150: Use position and exception tables for code hashing and equality (GH-95509) Message-ID: https://github.com/python/cpython/commit/7baca3c05e16d1faeb8c77f07706b84677d97a3d commit: 7baca3c05e16d1faeb8c77f07706b84677d97a3d branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T11:33:49-07:00 summary: GH-95150: Use position and exception tables for code hashing and equality (GH-95509) (cherry picked from commit c7e5bbaee88a71dc6e633e3cd451ed1798436382) Co-authored-by: Brandt Bucher files: A Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst M Lib/test/test_code.py M Lib/test/test_compile.py M Lib/test/test_syntax.py M Objects/codeobject.c diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index fd68f6dee7915..2386cf6b59f39 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -428,6 +428,27 @@ def func(): self.assertIsNone(line) self.assertEqual(end_line, new_code.co_firstlineno + 1) + def test_code_equality(self): + def f(): + try: + a() + except: + b() + else: + c() + finally: + d() + code_a = f.__code__ + code_b = code_a.replace(co_linetable=b"") + code_c = code_a.replace(co_exceptiontable=b"") + code_d = code_b.replace(co_exceptiontable=b"") + self.assertNotEqual(code_a, code_b) + self.assertNotEqual(code_a, code_c) + self.assertNotEqual(code_a, code_d) + self.assertNotEqual(code_b, code_c) + self.assertNotEqual(code_b, code_d) + self.assertNotEqual(code_c, code_d) + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1]) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index edde54aaca00c..b4e65c6566429 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -613,7 +613,7 @@ def check_same_constant(const): exec(code, ns) f1 = ns['f1'] f2 = ns['f2'] - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, const) self.assertEqual(repr(f1()), repr(const)) @@ -626,7 +626,7 @@ def check_same_constant(const): # Note: "lambda: ..." emits "LOAD_CONST Ellipsis", # whereas "lambda: Ellipsis" emits "LOAD_GLOBAL Ellipsis" f1, f2 = lambda: ..., lambda: ... - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, Ellipsis) self.assertEqual(repr(f1()), repr(Ellipsis)) @@ -641,7 +641,7 @@ def check_same_constant(const): # {0} is converted to a constant frozenset({0}) by the peephole # optimizer f1, f2 = lambda x: x in {0}, lambda x: x in {0} - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, frozenset({0})) self.assertTrue(f1(0)) @@ -1264,6 +1264,27 @@ def f(): self.assertIsNotNone(end_column) self.assertLessEqual((line, column), (end_line, end_column)) + @support.cpython_only + def test_column_offset_deduplication(self): + # GH-95150: Code with different column offsets shouldn't be merged! + for source in [ + "lambda: a", + "(a for b in c)", + "[a for b in c]", + "{a for b in c}", + "{a: b for c in d}", + ]: + with self.subTest(source): + code = compile(f"{source}, {source}", "", "eval") + self.assertEqual(len(code.co_consts), 2) + self.assertIsInstance(code.co_consts[0], types.CodeType) + self.assertIsInstance(code.co_consts[1], types.CodeType) + self.assertNotEqual(code.co_consts[0], code.co_consts[1]) + self.assertNotEqual( + list(code.co_consts[0].co_positions()), + list(code.co_consts[1].co_positions()), + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index b22a96b20298d..ae1066924b3cf 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2012,7 +2012,8 @@ def fib(n): a, b = 0, 1 """ try: - self.assertEqual(compile(s1, '', 'exec'), compile(s2, '', 'exec')) + compile(s1, '', 'exec') + compile(s2, '', 'exec') except SyntaxError: self.fail("Indented statement over multiple lines is valid") diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst new file mode 100644 index 0000000000000..c3db4714188b3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst @@ -0,0 +1,3 @@ +Update code object hashing and equality to consider all debugging and +exception handling tables. This fixes an issue where certain non-identical +code objects could be "deduplicated" during compilation. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 40ac19d543b1e..970aa6116bfab 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1693,6 +1693,15 @@ code_richcompare(PyObject *self, PyObject *other, int op) eq = PyObject_RichCompareBool(co->co_localsplusnames, cp->co_localsplusnames, Py_EQ); if (eq <= 0) goto unequal; + eq = PyObject_RichCompareBool(co->co_linetable, cp->co_linetable, Py_EQ); + if (eq <= 0) { + goto unequal; + } + eq = PyObject_RichCompareBool(co->co_exceptiontable, + cp->co_exceptiontable, Py_EQ); + if (eq <= 0) { + goto unequal; + } if (op == Py_EQ) res = Py_True; @@ -1725,7 +1734,15 @@ code_hash(PyCodeObject *co) if (h2 == -1) return -1; h3 = PyObject_Hash(co->co_localsplusnames); if (h3 == -1) return -1; - h = h0 ^ h1 ^ h2 ^ h3 ^ + Py_hash_t h4 = PyObject_Hash(co->co_linetable); + if (h4 == -1) { + return -1; + } + Py_hash_t h5 = PyObject_Hash(co->co_exceptiontable); + if (h5 == -1) { + return -1; + } + h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ co->co_flags; if (h == -1) h = -2; From webhook-mailer at python.org Mon Aug 1 17:22:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 01 Aug 2022 21:22:38 -0000 Subject: [Python-checkins] gh-91447: Fix findtext to only give an empty string on None (GH-91486) Message-ID: https://github.com/python/cpython/commit/b12dba40ff00e0c7a47036401cdcfbe3845d9c2a commit: b12dba40ff00e0c7a47036401cdcfbe3845d9c2a branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T14:22:33-07:00 summary: gh-91447: Fix findtext to only give an empty string on None (GH-91486) The API documentation for [findtext](https://docs.python.org/3/library/xml.etree.elementtree.htmlGH-xml.etree.ElementTree.Element.findtext) states that this function gives back an empty string on "no text content." With the previous implementation, this would give back a empty string even on text content values such as 0 or False. This patch attempts to resolve that by only giving back an empty string if the text attribute is set to `None`. Resolves GH-91447. Automerge-Triggered-By: GH:gvanrossum (cherry picked from commit a95e60db748ec6f2c19b5710c11f62e1e4d669f4) Co-authored-by: Eugene Triguba files: A Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst M Lib/test/test_xml_etree.py M Lib/xml/etree/ElementPath.py diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index afa4641e6906b..63b6725af8970 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2734,6 +2734,20 @@ def test_findtext_with_error(self): except ZeroDivisionError: pass + def test_findtext_with_falsey_text_attribute(self): + root_elem = ET.Element('foo') + sub_elem = ET.SubElement(root_elem, 'bar') + falsey = ["", 0, False, [], (), {}] + for val in falsey: + sub_elem.text = val + self.assertEqual(root_elem.findtext('./bar'), val) + + def test_findtext_with_none_text_attribute(self): + root_elem = ET.Element('foo') + sub_elem = ET.SubElement(root_elem, 'bar') + sub_elem.text = None + self.assertEqual(root_elem.findtext('./bar'), '') + def test_findall_with_mutating(self): e = ET.Element('foo') e.extend([ET.Element('bar')]) diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py index cd3c354d0813e..dc6bd28c03137 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -416,6 +416,8 @@ def findall(elem, path, namespaces=None): def findtext(elem, path, default=None, namespaces=None): try: elem = next(iterfind(elem, path, namespaces)) - return elem.text or "" + if elem.text is None: + return "" + return elem.text except StopIteration: return default diff --git a/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst b/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst new file mode 100644 index 0000000000000..6f9be2d3e9be4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst @@ -0,0 +1,2 @@ +Fix findtext in the xml module to only give an empty string when the text +attribute is set to None. From webhook-mailer at python.org Mon Aug 1 19:13:32 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Mon, 01 Aug 2022 23:13:32 -0000 Subject: [Python-checkins] gh-90110: Get the C Analyzer Tool Working Again (gh-95545) Message-ID: https://github.com/python/cpython/commit/a7161f95aaeb6d71e4db58bd8a47ffcfa7bda2fa commit: a7161f95aaeb6d71e4db58bd8a47ffcfa7bda2fa branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-08-01T17:13:23-06:00 summary: gh-90110: Get the C Analyzer Tool Working Again (gh-95545) files: M Tools/c-analyzer/check-c-globals.py M Tools/c-analyzer/cpython/_parser.py M Tools/c-analyzer/cpython/globals-to-fix.tsv M Tools/c-analyzer/cpython/ignored.tsv diff --git a/Tools/c-analyzer/check-c-globals.py b/Tools/c-analyzer/check-c-globals.py index b1364a612bb7d..73742f70a388a 100644 --- a/Tools/c-analyzer/check-c-globals.py +++ b/Tools/c-analyzer/check-c-globals.py @@ -1,7 +1,9 @@ +import sys + from cpython.__main__ import main, configure_logger -def parse_args(): +def parse_args(argv=sys.argv[1:]): import argparse from c_common.scriptutil import ( add_verbosity_cli, @@ -13,7 +15,8 @@ def parse_args(): processors = [ add_verbosity_cli(parser), add_traceback_cli(parser), - _cli_check(parser, checks=''), + #_cli_check(parser, checks=''), + _cli_check(parser), ] args = parser.parse_args() diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index eaad7278ed79e..af223b1149418 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -71,6 +71,7 @@ def clean_lines(text): Python/dynload_hpux.c # dl.h Python/thread_pthread.h Python/emscripten_signal.c +Python/thread_pthread_stubs.h # only huge constants (safe but parsing is slow) Modules/_blake2/impl/blake2-kat.h @@ -136,6 +137,7 @@ def clean_lines(text): Include/internal/*.h Py_BUILD_CORE 1 Python/**/*.c Py_BUILD_CORE 1 Parser/**/*.c Py_BUILD_CORE 1 +Parser/**/*.h Py_BUILD_CORE 1 Objects/**/*.c Py_BUILD_CORE 1 Modules/_asynciomodule.c Py_BUILD_CORE 1 @@ -205,6 +207,7 @@ def clean_lines(text): Include/cpython/tupleobject.h Py_CPYTHON_TUPLEOBJECT_H 1 Include/cpython/unicodeobject.h Py_CPYTHON_UNICODEOBJECT_H 1 Include/internal/pycore_code.h SIZEOF_VOID_P 8 +Include/internal/pycore_frame.h SIZEOF_VOID_P 8 # implied include of pyport.h Include/**/*.h PyAPI_DATA(RTYPE) extern RTYPE diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index bc9d6aabb0936..496bc9a264b1d 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -114,7 +114,7 @@ Objects/genericaliasobject.c - _Py_GenericAliasIterType - Objects/iterobject.c - _PyAnextAwaitable_Type - # Not in a .h file: Objects/memoryobject.c - _PyMemoryIter_Type - -#Objects/unicodeobject.c - _PyUnicodeASCIIIter_Type - +Objects/unicodeobject.c - _PyUnicodeASCIIIter_Type - Objects/unionobject.c - _PyUnion_Type - Python/context.c - _PyContextTokenMissing_Type - Python/hamt.c - _PyHamtItems_Type - @@ -349,7 +349,10 @@ Objects/clinic/unicodeobject.c.h unicode_split _parser - Objects/clinic/unicodeobject.c.h unicode_splitlines _parser - Python/clinic/Python-tokenize.c.h tokenizeriter_new _parser - Python/clinic/_warnings.c.h warnings_warn _parser - +Python/clinic/_warnings.c.h warnings_warn_explicit _parser - +Python/clinic/bltinmodule.c.h builtin___import__ _parser - Python/clinic/bltinmodule.c.h builtin_compile _parser - +Python/clinic/bltinmodule.c.h builtin_exec _parser - Python/clinic/bltinmodule.c.h builtin_pow _parser - Python/clinic/bltinmodule.c.h builtin_print _parser - Python/clinic/bltinmodule.c.h builtin_round _parser - @@ -511,6 +514,8 @@ Python/bootstrap_hash.c - urandom_cache - Python/ceval.c - lltrace - # XXX This should have been found by the analyzer but wasn't: Python/ceval.c make_pending_calls busy - +Python/ceval.c _PyEval_SetProfile reentrant - +Python/ceval.c _PyEval_SetTrace reentrant - Python/dynload_shlib.c - handles - Python/dynload_shlib.c - nhandles - # XXX This should have been found by the analyzer but wasn't: @@ -587,6 +592,10 @@ Modules/_io/textio.c - PyIncrementalNewlineDecoder_Type - Modules/_io/textio.c - PyTextIOBase_Type - Modules/_io/textio.c - PyTextIOWrapper_Type - Modules/_io/winconsoleio.c - PyWindowsConsoleIO_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptor2_Type - Modules/_threadmodule.c - Locktype - Modules/_threadmodule.c - RLocktype - Modules/_threadmodule.c - localdummytype - @@ -629,6 +638,10 @@ Modules/signalmodule.c - ItimerError - # cached - initialized once # _PyArg_Parser +Modules/clinic/_asynciomodule.c.h _asyncio_Task__check_future _parser - +Modules/clinic/_csv.c.h _csv_unregister_dialect _parser - +Modules/clinic/_csv.c.h _csv_get_dialect _parser - +Modules/clinic/_csv.c.h _csv_field_size_limit _parser - Modules/clinic/_codecsmodule.c.h _codecs_decode _parser - Modules/clinic/_codecsmodule.c.h _codecs_encode _parser - Modules/clinic/_sre.c.h _sre_SRE_Match_expand _parser - @@ -646,6 +659,10 @@ Modules/clinic/_sre.c.h _sre_SRE_Pattern_subn _parser - Modules/clinic/_sre.c.h _sre_SRE_Scanner_match _parser - Modules/clinic/_sre.c.h _sre_SRE_Scanner_search _parser - Modules/clinic/_sre.c.h _sre_compile _parser - +Modules/clinic/_winapi.c.h _winapi_LCMapStringEx _parser - +Modules/clinic/arraymodule.c.h array_array_fromfile _parser - +Modules/clinic/arraymodule.c.h array_array_tofile _parser - +Modules/clinic/arraymodule.c.h array_array___reduce_ex__ _parser - Modules/clinic/gcmodule.c.h gc_collect _parser - Modules/clinic/gcmodule.c.h gc_get_objects _parser - Modules/clinic/itertoolsmodule.c.h itertools_accumulate _parser - @@ -681,6 +698,7 @@ Modules/clinic/posixmodule.c.h os_scandir _parser - Modules/clinic/posixmodule.c.h os_stat _parser - Modules/clinic/posixmodule.c.h os_unlink _parser - Modules/clinic/posixmodule.c.h os_utime _parser - +Modules/clinic/socketmodule.c.h sock_initobj _parser - #----------------------- # other @@ -942,6 +960,7 @@ Modules/xxmodule.c - ErrorObject - # _Py_IDENTIFIER (global) Modules/_asynciomodule.c - PyId___asyncio_running_event_loop__ - Modules/_asynciomodule.c - PyId__asyncio_future_blocking - +Modules/_asynciomodule.c - PyId__check_future static - Modules/_asynciomodule.c - PyId_add_done_callback - Modules/_asynciomodule.c - PyId_call_soon - Modules/_asynciomodule.c - PyId_cancel - @@ -1256,11 +1275,13 @@ Modules/clinic/zlibmodule.c.h zlib_decompressobj _parser - # other - during module init Modules/_asynciomodule.c - asyncio_mod - Modules/_asynciomodule.c - traceback_extract_stack - -Modules/_asynciomodule.c - asyncio_get_event_loop_policy - +Modules/_asynciomodule.c - asyncio_future_repr_func - Modules/_asynciomodule.c - asyncio_future_repr_info_func - +Modules/_asynciomodule.c - asyncio_get_event_loop_policy - Modules/_asynciomodule.c - asyncio_iscoroutine_func - Modules/_asynciomodule.c - asyncio_task_get_stack_func - Modules/_asynciomodule.c - asyncio_task_print_stack_func - +Modules/_asynciomodule.c - asyncio_task_repr_func - Modules/_asynciomodule.c - asyncio_task_repr_info_func - Modules/_asynciomodule.c - asyncio_InvalidStateError - Modules/_asynciomodule.c - asyncio_CancelledError - @@ -1303,6 +1324,7 @@ Modules/_ssl.c - lib_codes_to_names - Modules/_ssl.c - _ssl_locks - Modules/_struct.c - cache - Modules/arraymodule.c array_array___reduce_ex__ array_reconstructor - +Modules/arraymodule.c array_array___reduce_ex___impl array_reconstructor - Modules/cjkcodecs/cjkcodecs.h getmultibytecodec cofunc - # state @@ -1313,6 +1335,7 @@ Modules/_asynciomodule.c - all_tasks - Modules/_asynciomodule.c - current_tasks - Modules/_asynciomodule.c - iscoroutine_typecache - Modules/_ctypes/_ctypes.c - _ctypes_ptrtype_cache - +Modules/_testinternalcapi.c - record_list - Modules/_tkinter.c - tcl_lock - Modules/_tkinter.c - excInCmd - Modules/_tkinter.c - valInCmd - @@ -1401,3 +1424,4 @@ Modules/rotatingtree.c - random_stream - Modules/rotatingtree.c - random_value - Modules/socketmodule.c - defaulttimeout - Modules/syslogmodule.c - S_log_open - +Modules/clinic/_asynciomodule.c.h _asyncio_Task__check_future _parser - diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 63d0695bfb4a6..ba48ef4933a46 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -64,6 +64,10 @@ Modules/_sqlite/module.c - pysqlite_BaseTypeAdapted - Modules/_sqlite/module.h - pysqlite_global_state - Modules/_testcapimodule.c - _PyBytesIOBuffer_Type - Modules/posixmodule.c - _Py_open_cloexec_works - +Objects/object.c - _Py_GenericAliasIterType - +Objects/object.c - _PyMemoryIter_Type - +Objects/object.c - _PyLineIterator - +Objects/object.c - _PyPositionsIterator - Python/importdl.h - _PyImport_DynLoadFiletab - @@ -186,6 +190,7 @@ Modules/_testcapimodule.c - x - Modules/_testcapimodule.c getargs_keyword_only keywords - Modules/_testcapimodule.c getargs_keywords keywords - Modules/_testcapimodule.c getargs_positional_only_and_keywords keywords - +Modules/_testcapimodule.c getargs_s_hash_int2 keywords static char*[] Modules/_testcapimodule.c make_exception_with_doc kwlist - Modules/_testcapimodule.c raise_SIGINT_then_send_None PyId_send - Modules/_testcapimodule.c slot_tp_del PyId___tp_del__ - @@ -400,11 +405,12 @@ Python/sysmodule.c sys_set_asyncgen_hooks keywords - #----------------------- # PyModuleDef - Modules/_multiprocessing/posixshmem.c - _posixshmemmodule - Modules/_sqlite/module.h - _sqlite3module - +Modules/_sre/sre.c - sremodule static struct - Modules/_ssl.c - _sslmodule_def - Modules/_ssl.h - _sslmodule_def - +Modules/_testcapi/heaptype.c - _testcapimodule static - Modules/_testmultiphase.c - def_module_state_shared - Modules/_threadmodule.c - thread_module - Modules/_typingmodule.c - typingmodule - @@ -422,6 +428,7 @@ Python/sysmodule.c - sysmodule - # PyModuleDef_Slot Modules/_abc.c - _abcmodule_slots - +Modules/_bisectmodule.c - bisect_slots - Modules/_blake2/blake2module.c - _blake2_slots - Modules/_bz2module.c - _bz2_slots - Modules/_codecsmodule.c - _codecs_slots - @@ -448,6 +455,7 @@ Modules/_scproxy.c - _scproxy_slots - Modules/_sha3/sha3module.c - _sha3_slots - Modules/_sqlite/module.c - module_slots - Modules/_sre.c - sre_slots - +Modules/_sre/sre.c - sre_slots - Modules/_ssl.c - sslmodule_slots - Modules/_stat.c - stat_slots - Modules/_statisticsmodule.c - _statisticsmodule_slots - @@ -615,10 +623,15 @@ Modules/_randommodule.c - random_methods - Modules/_scproxy.c - mod_methods - Modules/_sha3/sha3module.c - SHA3_methods - Modules/_sha3/sha3module.c - SHAKE_methods - +Modules/_sqlite/blob.c - blob_methods static PyMethodDef[] Modules/_sqlite/connection.c - connection_methods - Modules/_sqlite/cursor.c - cursor_methods - Modules/_sqlite/module.c - module_methods - Modules/_sqlite/row.c - row_methods - +Modules/_sre/sre.c - _functions - +Modules/_sre/sre.c - pattern_methods - +Modules/_sre/sre.c - match_methods - +Modules/_sre/sre.c - scanner_methods - Modules/_sre.c - _functions - Modules/_sre.c - match_methods - Modules/_sre.c - pattern_methods - @@ -633,6 +646,8 @@ Modules/_statisticsmodule.c - statistics_methods - Modules/_struct.c - module_functions - Modules/_struct.c - s_methods - Modules/_struct.c - unpackiter_methods - +Modules/_testcapi/heaptype.c - TestMethods - +Modules/_testcapi/vectorcall.c - TestMethods - Modules/_threadmodule.c - lock_methods - Modules/_threadmodule.c - rlock_methods - Modules/_threadmodule.c - thread_methods - @@ -772,6 +787,7 @@ Objects/fileobject.c - stdprinter_methods - Objects/floatobject.c - float_methods - Objects/frameobject.c - frame_methods - Objects/genericaliasobject.c - ga_methods - +Objects/genericaliasobject.c - ga_iter_methods - Objects/genobject.c - async_gen_asend_methods - Objects/genobject.c - async_gen_athrow_methods - Objects/genobject.c - async_gen_methods - @@ -862,15 +878,28 @@ Modules/_json.c - encoder_members - Modules/_json.c - scanner_members - Modules/_lzmamodule.c - Decompressor_members - Modules/_multiprocessing/semaphore.c - semlock_members - +Modules/_operator.c - attrgetter_members - +Modules/_operator.c - itemgetter_members - Modules/_pickle.c - Pickler_members - Modules/_queuemodule.c - simplequeue_members - +Modules/_sqlite/blob.c - blob_members - Modules/_sqlite/connection.c - connection_members - Modules/_sqlite/cursor.c - cursor_members - Modules/_sqlite/statement.c - stmt_members - +Modules/_sre/sre.c - match_members - +Modules/_sre/sre.c - pattern_members - +Modules/_sre/sre.c - scanner_members - Modules/_sre.c - match_members - Modules/_sre.c - pattern_members - Modules/_sre.c - scanner_members - Modules/_struct.c - s_members - +Modules/_testcapi/heaptype.c - heapctype_members - +Modules/_testcapi/heaptype.c - heapctypesetattr_members - +Modules/_testcapi/heaptype.c - heapctypesubclass_members - +Modules/_testcapi/heaptype.c - heapctypewithdict_members - +Modules/_testcapi/heaptype.c - heapctypewithnegativedict_members - +Modules/_testcapi/heaptype.c - heapctypewithweakref_members - +Modules/_testcapi/heaptype.c - members_to_repeat - Modules/_threadmodule.c - local_dummy_type_members - Modules/_threadmodule.c - local_type_members - Modules/_threadmodule.c - lock_type_members - @@ -1080,7 +1109,10 @@ Modules/_io/winconsoleio.c - winconsoleio_getsetlist - Modules/_pickle.c - Pickler_getsets - Modules/_pickle.c - Unpickler_getsets - Modules/_sha3/sha3module.c - SHA3_getseters - +Modules/_sha3/sha3module.c - SHAKE_getseters - Modules/_sqlite/connection.c - connection_getset - +Modules/_sre/sre.c - pattern_getset - +Modules/_sre/sre.c - match_getset - Modules/_sre.c - match_getset - Modules/_sre.c - pattern_getset - Modules/_ssl.c - PySSLSession_getsetlist - @@ -1088,6 +1120,7 @@ Modules/_ssl.c - context_getsetlist - Modules/_ssl.c - memory_bio_getsetlist - Modules/_ssl.c - ssl_getsetlist - Modules/_struct.c - s_getsetlist - +Modules/_testcapi/heaptype.c - heapctypewithdict_getsetlist - Modules/_tkinter.c - PyTclObject_getsetlist - Modules/_xxsubinterpretersmodule.c - channelid_getsets - Modules/arraymodule.c - array_getsets - @@ -1172,6 +1205,7 @@ Modules/_json.c - PyScannerType_slots - Modules/_lsprof.c - _lsprof_profiler_type_spec_slots - Modules/_lzmamodule.c - lzma_compressor_type_slots - Modules/_lzmamodule.c - lzma_decompressor_type_slots - +Modules/_multiprocessing/semaphore.c - _PyMp_SemLockType_slots - Modules/_operator.c - attrgetter_type_slots - Modules/_operator.c - itemgetter_type_slots - Modules/_operator.c - methodcaller_type_slots - @@ -1184,11 +1218,15 @@ Modules/_sha3/sha3module.c - sha3_256_slots - Modules/_sha3/sha3module.c - sha3_384_slots - Modules/_sha3/sha3module.c - sha3_512_slots - Modules/_sha3/sha3module.c - type_slots_obj - +Modules/_sqlite/blob.c - blob_slots - Modules/_sqlite/connection.c - connection_slots - Modules/_sqlite/cursor.c - cursor_slots - Modules/_sqlite/prepare_protocol.c - type_slots - Modules/_sqlite/row.c - row_slots - Modules/_sqlite/statement.c - stmt_slots - +Modules/_sre/sre.c - match_slots - +Modules/_sre/sre.c - pattern_slots - +Modules/_sre/sre.c - scanner_slots - Modules/_sre.c - match_slots - Modules/_sre.c - pattern_slots - Modules/_sre.c - scanner_slots - @@ -1200,6 +1238,22 @@ Modules/_ssl.c - sslerror_type_slots - Modules/_ssl/cert.c - PySSLCertificate_slots - Modules/_struct.c - PyStructType_slots - Modules/_struct.c - unpackiter_type_slots - +Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_slots - +Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_slots - +Modules/_testcapi/heaptype.c - HeapCTypeSetattr_slots - +Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_slots - +Modules/_testcapi/heaptype.c - HeapCTypeSubclass_slots - +Modules/_testcapi/heaptype.c - HeapCTypeWithBuffer_slots - +Modules/_testcapi/heaptype.c - HeapCTypeWithDict_slots - +Modules/_testcapi/heaptype.c - HeapCTypeWithNegativeDict_slots - +Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_slots - +Modules/_testcapi/heaptype.c - HeapCType_slots - +Modules/_testcapi/heaptype.c - HeapDocCType_slots - +Modules/_testcapi/heaptype.c - HeapGcCType_slots - +Modules/_testcapi/heaptype.c - NullTpDocType_slots - +Modules/_testcapi/heaptype.c - empty_type_slots - +Modules/_testcapi/heaptype.c - repeated_doc_slots - +Modules/_testcapi/heaptype.c - repeated_members_slots - Modules/_testcapimodule.c - HeapTypeNameType_slots - Modules/_testcapimodule.c - NullTpDocType_slots - Modules/_threadmodule.c - local_dummy_type_slots - @@ -1269,6 +1323,8 @@ Modules/_json.c - PyScannerType_spec - Modules/_lsprof.c - _lsprof_profiler_type_spec - Modules/_lzmamodule.c - lzma_compressor_type_spec - Modules/_lzmamodule.c - lzma_decompressor_type_spec - +Modules/_multiprocessing/multiprocessing.h - _PyMp_SemLockType_spec - +Modules/_multiprocessing/semaphore.c - _PyMp_SemLockType_spec - Modules/_operator.c - attrgetter_type_spec - Modules/_operator.c - itemgetter_type_spec - Modules/_operator.c - methodcaller_type_spec - @@ -1281,11 +1337,15 @@ Modules/_sha3/sha3module.c - sha3_256_spec - Modules/_sha3/sha3module.c - sha3_384_spec - Modules/_sha3/sha3module.c - sha3_512_spec - Modules/_sha3/sha3module.c - type_spec_obj - +Modules/_sqlite/blob.c - blob_spec - Modules/_sqlite/connection.c - connection_spec - Modules/_sqlite/cursor.c - cursor_spec - Modules/_sqlite/prepare_protocol.c - type_spec - Modules/_sqlite/row.c - row_spec - Modules/_sqlite/statement.c - stmt_spec - +Modules/_sre/sre.c - pattern_spec - +Modules/_sre/sre.c - match_spec - +Modules/_sre/sre.c - scanner_spec - Modules/_sre.c - match_spec - Modules/_sre.c - pattern_spec - Modules/_sre.c - scanner_spec - @@ -1297,6 +1357,23 @@ Modules/_ssl.c - sslerror_type_spec - Modules/_ssl/cert.c - PySSLCertificate_spec - Modules/_struct.c - PyStructType_spec - Modules/_struct.c - unpackiter_type_spec - +Modules/_testcapi/heaptype.c - MinimalMetaclass_spec - +Modules/_testcapi/heaptype.c - MinimalType_spec - +Modules/_testcapi/heaptype.c - repeated_doc_slots_spec - +Modules/_testcapi/heaptype.c - repeated_members_slots_spec - +Modules/_testcapi/heaptype.c - HeapDocCType_spec - +Modules/_testcapi/heaptype.c - NullTpDocType_spec - +Modules/_testcapi/heaptype.c - HeapGcCType_spec - +Modules/_testcapi/heaptype.c - HeapCType_spec - +Modules/_testcapi/heaptype.c - HeapCTypeSubclass_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithBuffer_spec - +Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_spec - +Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_spec - +Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithDict_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithNegativeDict_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_spec - +Modules/_testcapi/heaptype.c - HeapCTypeSetattr_spec - Modules/_testcapimodule.c - HeapTypeNameType_Spec - Modules/_testcapimodule.c - NullTpDocType_spec - Modules/_threadmodule.c - local_dummy_type_spec - @@ -1423,6 +1500,7 @@ Modules/_ctypes/cfield.c - ffi_type_void - Modules/_datetimemodule.c - epoch - Modules/_datetimemodule.c - max_fold_seconds - Modules/_datetimemodule.c datetime_isoformat specs - +Modules/_datetimemodule.c parse_hh_mm_ss_ff correction - Modules/_datetimemodule.c time_isoformat specs - Modules/_decimal/_decimal.c - cond_map - Modules/_decimal/_decimal.c - dec_signal_string - @@ -1437,6 +1515,9 @@ Modules/_io/_iomodule.c - static_types - Modules/_io/textio.c - encodefuncs - Modules/_localemodule.c - langinfo_constants - Modules/_sqlite/module.c - error_codes - +Modules/_sre/sre.c pattern_repr flag_names - +# XXX I'm pretty sure this is actually constant: +Modules/_sre/sre_targets.h - sre_targets - Modules/_sre.c pattern_repr flag_names - Modules/_struct.c - bigendian_table - Modules/_struct.c - lilendian_table - @@ -1500,6 +1581,7 @@ Python/ast_opt.c fold_unaryop ops - Python/codecs.c - Py_hexdigits - Python/codecs.c - ucnhash_capi - Python/codecs.c _PyCodecRegistry_Init methods - +Python/compile.c - NO_LOCATION - Python/dynload_shlib.c - _PyImport_DynLoadFiletab - Python/dynload_stub.c - _PyImport_DynLoadFiletab - Python/frozen.c - aliases - @@ -1517,4 +1599,5 @@ Python/pylifecycle.c - _TARGET_LOCALES - Python/specialize.c - adaptive_opcodes - Python/specialize.c - cache_requirements - Python/specialize.c - compare_masks - +Python/specialize.c - _PyOpcode_Adaptive - Python/sysmodule.c - whatstrings - From webhook-mailer at python.org Mon Aug 1 19:57:56 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 01 Aug 2022 23:57:56 -0000 Subject: [Python-checkins] gh-92219: Clarify that some options to the installer may break the install (GH-95548) Message-ID: https://github.com/python/cpython/commit/d2c1a9c76c001b18c14e50779b0ee41ea4ccf0b3 commit: d2c1a9c76c001b18c14e50779b0ee41ea4ccf0b3 branch: main author: Steve Dower committer: zooba date: 2022-08-02T00:57:46+01:00 summary: gh-92219: Clarify that some options to the installer may break the install (GH-95548) files: M Doc/using/windows.rst diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 1025c14e397df..2db73c8c5b9c2 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -194,18 +194,22 @@ of available options is shown below. | Include_debug | Install debug binaries | 0 | +---------------------------+--------------------------------------+--------------------------+ | Include_dev | Install developer headers and | 1 | -| | libraries | | +| | libraries. Omitting this may lead to | | +| | an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_exe | Install :file:`python.exe` and | 1 | -| | related files | | +| | related files. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_launcher | Install :ref:`launcher`. | 1 | +---------------------------+--------------------------------------+--------------------------+ -| InstallLauncherAllUsers | Installs :ref:`launcher` for all | 1 | -| | users. | | +| InstallLauncherAllUsers | Installs the launcher for all | 1 | +| | users. Also requires | | +| | ``Include_launcher`` to be set to 1 | | +---------------------------+--------------------------------------+--------------------------+ | Include_lib | Install standard library and | 1 | -| | extension modules | | +| | extension modules. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_pip | Install bundled pip and setuptools | 1 | +---------------------------+--------------------------------------+--------------------------+ From webhook-mailer at python.org Mon Aug 1 20:06:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 02 Aug 2022 00:06:31 -0000 Subject: [Python-checkins] gh-92219: Clarify that some options to the installer may break the install (GH-95548) Message-ID: https://github.com/python/cpython/commit/5f139e5044c96156560c8028058beb0e79177b29 commit: 5f139e5044c96156560c8028058beb0e79177b29 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T17:06:22-07:00 summary: gh-92219: Clarify that some options to the installer may break the install (GH-95548) (cherry picked from commit d2c1a9c76c001b18c14e50779b0ee41ea4ccf0b3) Co-authored-by: Steve Dower files: M Doc/using/windows.rst diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 7fb40a38a6fbc..076679bdba613 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -181,18 +181,22 @@ of available options is shown below. | Include_debug | Install debug binaries | 0 | +---------------------------+--------------------------------------+--------------------------+ | Include_dev | Install developer headers and | 1 | -| | libraries | | +| | libraries. Omitting this may lead to | | +| | an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_exe | Install :file:`python.exe` and | 1 | -| | related files | | +| | related files. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_launcher | Install :ref:`launcher`. | 1 | +---------------------------+--------------------------------------+--------------------------+ -| InstallLauncherAllUsers | Installs :ref:`launcher` for all | 1 | -| | users. | | +| InstallLauncherAllUsers | Installs the launcher for all | 1 | +| | users. Also requires | | +| | ``Include_launcher`` to be set to 1 | | +---------------------------+--------------------------------------+--------------------------+ | Include_lib | Install standard library and | 1 | -| | extension modules | | +| | extension modules. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_pip | Install bundled pip and setuptools | 1 | +---------------------------+--------------------------------------+--------------------------+ From webhook-mailer at python.org Tue Aug 2 00:10:43 2022 From: webhook-mailer at python.org (terryjreedy) Date: Tue, 02 Aug 2022 04:10:43 -0000 Subject: [Python-checkins] gh-95191: IDLE: Include prompts when saving Shell #95554 Message-ID: https://github.com/python/cpython/commit/b85411fc5e9e223a6bd44f89f674ee3b2e29b99e commit: b85411fc5e9e223a6bd44f89f674ee3b2e29b99e branch: main author: Terry Jan Reedy committer: terryjreedy date: 2022-08-02T00:10:39-04:00 summary: gh-95191: IDLE: Include prompts when saving Shell #95554 files: A Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_iomenu.py M Lib/idlelib/iomenu.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 0e3a50bb63991..ce95e2f9948b5 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,8 @@ Released on 2022-10-03 ========================= +gh-95191: Include prompts when saving Shell (interactive input/output). + gh-95511: Fix the Shell context menu copy-with-prompts bug of copying an extra line when one selects whole lines. diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index e338893c09e6a..2fb836dba2167 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,10 +1,12 @@ "Test , coverage 17%." -from idlelib import iomenu, util +from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk from idlelib.editor import EditorWindow +from idlelib import util +from idlelib.idle_test.mock_idle import Func class IOBindingTest(unittest.TestCase): @@ -36,9 +38,14 @@ def test_fixnewlines_end(self): io = self.io fix = io.fixnewlines text = io.editwin.text + + # Make the editor temporarily look like Shell. self.editwin.interp = None - eq(fix(), '') - del self.editwin.interp + shelltext = '>>> if 1' + self.editwin.get_prompt_text = Func(result=shelltext) + eq(fix(), shelltext) # Get... call and '\n' not added. + del self.editwin.interp, self.editwin.get_prompt_text + text.insert(1.0, 'a') eq(fix(), 'a'+io.eol_convention) eq(text.get('1.0', 'end-1c'), 'a\n') diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 327e885203c3c..af8159c2b33f5 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -251,11 +251,17 @@ def writefile(self, filename): return False def fixnewlines(self): - "Return text with final \n if needed and os eols." - if (self.text.get("end-2c") != '\n' - and not hasattr(self.editwin, "interp")): # Not shell. - self.text.insert("end-1c", "\n") - text = self.text.get("1.0", "end-1c") + """Return text with os eols. + + Add prompts if shell else final \n if missing. + """ + + if hasattr(self.editwin, "interp"): # Saving shell. + text = self.editwin.get_prompt_text('1.0', self.text.index('end-1c')) + else: + if self.text.get("end-2c") != '\n': + self.text.insert("end-1c", "\n") # Changes 'end-1c' value. + text = self.text.get('1.0', "end-1c") if self.eol_convention != "\n": text = text.replace("\n", self.eol_convention) return text diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 3806122962288..e68233a5a4131 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -986,6 +986,23 @@ def replace_event(self, event): def get_standard_extension_names(self): return idleConf.GetExtensions(shell_only=True) + def get_prompt_text(self, first, last): + """Return text between first and last with prompts added.""" + text = self.text.get(first, last) + lineno_range = range( + int(float(first)), + int(float(last)) + ) + prompts = [ + self.shell_sidebar.line_prompts.get(lineno) + for lineno in lineno_range + ] + return "\n".join( + line if prompt is None else f"{prompt} {line}" + for prompt, line in zip(prompts, text.splitlines()) + ) + "\n" + + def copy_with_prompts_callback(self, event=None): """Copy selected lines to the clipboard, with prompts. @@ -1002,23 +1019,9 @@ def copy_with_prompts_callback(self, event=None): sellast = text.index('sel.last') if sellast[-1] != '0': sellast = text.index("sel.last+1line linestart") - - selected_text = self.text.get(selfirst, sellast) - selection_lineno_range = range( - int(float(selfirst)), - int(float(sellast)) - ) - prompts = [ - self.shell_sidebar.line_prompts.get(lineno) - for lineno in selection_lineno_range - ] - selected_text_with_prompts = "\n".join( - line if prompt is None else f"{prompt} {line}" - for prompt, line in zip(prompts, selected_text.splitlines()) - ) + "\n" - text.clipboard_clear() - text.clipboard_append(selected_text_with_prompts) + prompt_text = self.get_prompt_text(selfirst, sellast) + text.clipboard_append(prompt_text) reading = False executing = False diff --git a/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst new file mode 100644 index 0000000000000..94d3dbbd529f0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst @@ -0,0 +1 @@ +Include prompts when saving Shell (interactive input and output). From webhook-mailer at python.org Tue Aug 2 00:23:56 2022 From: webhook-mailer at python.org (terryjreedy) Date: Tue, 02 Aug 2022 04:23:56 -0000 Subject: [Python-checkins] gh-83270: Update IDLE's credits (#95528) Message-ID: https://github.com/python/cpython/commit/698fa8bf6075c1594966ef6da8501a6f81db50f2 commit: 698fa8bf6075c1594966ef6da8501a6f81db50f2 branch: main author: Erlend Egeberg Aasland committer: terryjreedy date: 2022-08-02T00:23:42-04:00 summary: gh-83270: Update IDLE's credits (#95528) Co-authored-by: Terry Jan Reedy files: M Lib/idlelib/CREDITS.txt diff --git a/Lib/idlelib/CREDITS.txt b/Lib/idlelib/CREDITS.txt index 3a50eb8e7f2ac..4a42af586a4a9 100644 --- a/Lib/idlelib/CREDITS.txt +++ b/Lib/idlelib/CREDITS.txt @@ -2,9 +2,10 @@ Guido van Rossum, as well as being the creator of the Python language, is the original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development was carried out in the SF IDLEfork project. The +Until Python 2.3, IDLE's development was carried out in the SF IDLEfork project. The objective was to develop a version of IDLE which had an execution environment which could be initialized prior to each run of user code. +IDLefork was merged into the Python code base in 2003. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -28,6 +29,15 @@ Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful patches. Thanks, guys! +Major contributors since 2005: + +- 2005: Tal Einat +- 2010: Terry Jan Reedy (current maintainer) +- 2013: Roger Serwys +- 2014: Saimadhav Heblikar +- 2015: Mark Roseman +- 2017: Louie Lu, Cheryl Sabella, and Serhiy Storchaka + For additional details refer to NEWS.txt and Changelog. Please contact the IDLE maintainer (kbk at shore.net) to have yourself included From webhook-mailer at python.org Tue Aug 2 00:54:37 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 02 Aug 2022 04:54:37 -0000 Subject: [Python-checkins] gh-83270: Update IDLE's credits (GH-95528) Message-ID: https://github.com/python/cpython/commit/118851b8baf3bfe87f073b3b2f495de5dd8b8f84 commit: 118851b8baf3bfe87f073b3b2f495de5dd8b8f84 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-01T21:54:28-07:00 summary: gh-83270: Update IDLE's credits (GH-95528) Co-authored-by: Terry Jan Reedy (cherry picked from commit 698fa8bf6075c1594966ef6da8501a6f81db50f2) Co-authored-by: Erlend Egeberg Aasland files: M Lib/idlelib/CREDITS.txt diff --git a/Lib/idlelib/CREDITS.txt b/Lib/idlelib/CREDITS.txt index 3a50eb8e7f2ac..4a42af586a4a9 100644 --- a/Lib/idlelib/CREDITS.txt +++ b/Lib/idlelib/CREDITS.txt @@ -2,9 +2,10 @@ Guido van Rossum, as well as being the creator of the Python language, is the original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development was carried out in the SF IDLEfork project. The +Until Python 2.3, IDLE's development was carried out in the SF IDLEfork project. The objective was to develop a version of IDLE which had an execution environment which could be initialized prior to each run of user code. +IDLefork was merged into the Python code base in 2003. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -28,6 +29,15 @@ Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful patches. Thanks, guys! +Major contributors since 2005: + +- 2005: Tal Einat +- 2010: Terry Jan Reedy (current maintainer) +- 2013: Roger Serwys +- 2014: Saimadhav Heblikar +- 2015: Mark Roseman +- 2017: Louie Lu, Cheryl Sabella, and Serhiy Storchaka + For additional details refer to NEWS.txt and Changelog. Please contact the IDLE maintainer (kbk at shore.net) to have yourself included From webhook-mailer at python.org Tue Aug 2 02:14:30 2022 From: webhook-mailer at python.org (terryjreedy) Date: Tue, 02 Aug 2022 06:14:30 -0000 Subject: [Python-checkins] gh-95191: IDLE: Include prompts when saving Shell GH-95554 (#95557) Message-ID: https://github.com/python/cpython/commit/8570f6d1a09a71e11f860fdb6f338f48995b5b36 commit: 8570f6d1a09a71e11f860fdb6f338f48995b5b36 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: terryjreedy date: 2022-08-02T02:14:19-04:00 summary: gh-95191: IDLE: Include prompts when saving Shell GH-95554 (#95557) (cherry picked from commit b85411fc5e9e223a6bd44f89f674ee3b2e29b99e) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_iomenu.py M Lib/idlelib/iomenu.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 0e3a50bb63991..ce95e2f9948b5 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,8 @@ Released on 2022-10-03 ========================= +gh-95191: Include prompts when saving Shell (interactive input/output). + gh-95511: Fix the Shell context menu copy-with-prompts bug of copying an extra line when one selects whole lines. diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index e338893c09e6a..2fb836dba2167 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,10 +1,12 @@ "Test , coverage 17%." -from idlelib import iomenu, util +from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk from idlelib.editor import EditorWindow +from idlelib import util +from idlelib.idle_test.mock_idle import Func class IOBindingTest(unittest.TestCase): @@ -36,9 +38,14 @@ def test_fixnewlines_end(self): io = self.io fix = io.fixnewlines text = io.editwin.text + + # Make the editor temporarily look like Shell. self.editwin.interp = None - eq(fix(), '') - del self.editwin.interp + shelltext = '>>> if 1' + self.editwin.get_prompt_text = Func(result=shelltext) + eq(fix(), shelltext) # Get... call and '\n' not added. + del self.editwin.interp, self.editwin.get_prompt_text + text.insert(1.0, 'a') eq(fix(), 'a'+io.eol_convention) eq(text.get('1.0', 'end-1c'), 'a\n') diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 327e885203c3c..af8159c2b33f5 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -251,11 +251,17 @@ def writefile(self, filename): return False def fixnewlines(self): - "Return text with final \n if needed and os eols." - if (self.text.get("end-2c") != '\n' - and not hasattr(self.editwin, "interp")): # Not shell. - self.text.insert("end-1c", "\n") - text = self.text.get("1.0", "end-1c") + """Return text with os eols. + + Add prompts if shell else final \n if missing. + """ + + if hasattr(self.editwin, "interp"): # Saving shell. + text = self.editwin.get_prompt_text('1.0', self.text.index('end-1c')) + else: + if self.text.get("end-2c") != '\n': + self.text.insert("end-1c", "\n") # Changes 'end-1c' value. + text = self.text.get('1.0', "end-1c") if self.eol_convention != "\n": text = text.replace("\n", self.eol_convention) return text diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 3806122962288..e68233a5a4131 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -986,6 +986,23 @@ def replace_event(self, event): def get_standard_extension_names(self): return idleConf.GetExtensions(shell_only=True) + def get_prompt_text(self, first, last): + """Return text between first and last with prompts added.""" + text = self.text.get(first, last) + lineno_range = range( + int(float(first)), + int(float(last)) + ) + prompts = [ + self.shell_sidebar.line_prompts.get(lineno) + for lineno in lineno_range + ] + return "\n".join( + line if prompt is None else f"{prompt} {line}" + for prompt, line in zip(prompts, text.splitlines()) + ) + "\n" + + def copy_with_prompts_callback(self, event=None): """Copy selected lines to the clipboard, with prompts. @@ -1002,23 +1019,9 @@ def copy_with_prompts_callback(self, event=None): sellast = text.index('sel.last') if sellast[-1] != '0': sellast = text.index("sel.last+1line linestart") - - selected_text = self.text.get(selfirst, sellast) - selection_lineno_range = range( - int(float(selfirst)), - int(float(sellast)) - ) - prompts = [ - self.shell_sidebar.line_prompts.get(lineno) - for lineno in selection_lineno_range - ] - selected_text_with_prompts = "\n".join( - line if prompt is None else f"{prompt} {line}" - for prompt, line in zip(prompts, selected_text.splitlines()) - ) + "\n" - text.clipboard_clear() - text.clipboard_append(selected_text_with_prompts) + prompt_text = self.get_prompt_text(selfirst, sellast) + text.clipboard_append(prompt_text) reading = False executing = False diff --git a/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst new file mode 100644 index 0000000000000..94d3dbbd529f0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst @@ -0,0 +1 @@ +Include prompts when saving Shell (interactive input and output). From webhook-mailer at python.org Tue Aug 2 03:43:11 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 02 Aug 2022 07:43:11 -0000 Subject: [Python-checkins] gh-95516: Add param types and clarify param descriptions of LogRecord (GH-95517) Message-ID: https://github.com/python/cpython/commit/75a6441718dcbc65d993c9544e67e25bef120e82 commit: 75a6441718dcbc65d993c9544e67e25bef120e82 branch: main author: CAM Gerlach committer: vsajip date: 2022-08-02T08:42:35+01:00 summary: gh-95516: Add param types and clarify param descriptions of LogRecord (GH-95517) files: M Doc/library/logging.rst diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 8ec1eda32b153..319340a39350e 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -712,6 +712,7 @@ the :class:`LogRecord` being processed. Obviously changing the LogRecord needs to be done with some care, but it does allow the injection of contextual information into logs (see :ref:`filters-contextual`). + .. _log-record: LogRecord Objects @@ -727,32 +728,54 @@ wire). Contains all the information pertinent to the event being logged. - The primary information is passed in :attr:`msg` and :attr:`args`, which - are combined using ``msg % args`` to create the :attr:`message` field of the - record. - - :param name: The name of the logger used to log the event represented by - this LogRecord. Note that this name will always have this - value, even though it may be emitted by a handler attached to - a different (ancestor) logger. - :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) - Note that this is converted to *two* attributes of the LogRecord: - ``levelno`` for the numeric value and ``levelname`` for the - corresponding level name. - :param pathname: The full pathname of the source file where the logging call - was made. - :param lineno: The line number in the source file where the logging call was - made. - :param msg: The event description message, possibly a format string with - placeholders for variable data. - :param args: Variable data to merge into the *msg* argument to obtain the - event description. + The primary information is passed in *msg* and *args*, + which are combined using ``msg % args`` to create + the :attr:`!message` attribute of the record. + + :param name: The name of the logger used to log the event + represented by this :class:`!LogRecord`. + Note that the logger name in the :class:`!LogRecord` + will always have this value, + even though it may be emitted by a handler + attached to a different (ancestor) logger. + :type name: str + + :param level: The :ref:`numeric level ` of the logging event + (such as ``10`` for ``DEBUG``, ``20`` for ``INFO``, etc). + Note that this is converted to *two* attributes of the LogRecord: + :attr:`!levelno` for the numeric value + and :attr:`!levelname` for the corresponding level name. + :type level: int + + :param pathname: The full string path of the source file + where the logging call was made. + :type pathname: str + + :param lineno: The line number in the source file + where the logging call was made. + :type lineno: int + + :param msg: The event description message, + which can be a %-format string with placeholders for variable data. + :type msg: str + + :param args: Variable data to merge into the *msg* argument + to obtain the event description. + :type args: tuple | dict[str, typing.Any] + :param exc_info: An exception tuple with the current exception information, - or ``None`` if no exception information is available. - :param func: The name of the function or method from which the logging call - was invoked. - :param sinfo: A text string representing stack information from the base of - the stack in the current thread, up to the logging call. + as returned by :func:`sys.exc_info`, + or ``None`` if no exception information is available. + :type exc_info: tuple[type[BaseException], BaseException, types.TracebackType] | None + + :param func: The name of the function or method + from which the logging call was invoked. + :type func: str | None + + :param sinfo: A text string representing stack information + from the base of the stack in the current thread, + up to the logging call. + :type sinfo: str | None .. method:: getMessage() From webhook-mailer at python.org Tue Aug 2 05:55:26 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 02 Aug 2022 09:55:26 -0000 Subject: [Python-checkins] [3.11] gh-95516: Add param types and clarify param descriptions of LogRecord (GH-95517) (GH-95566) Message-ID: https://github.com/python/cpython/commit/eff6778899733042c803e3a2de80342b5cad7dce commit: eff6778899733042c803e3a2de80342b5cad7dce branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip date: 2022-08-02T10:54:49+01:00 summary: [3.11] gh-95516: Add param types and clarify param descriptions of LogRecord (GH-95517) (GH-95566) Co-authored-by: CAM Gerlach files: M Doc/library/logging.rst diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 0b8057c759a6f..89412898ce0e6 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -707,6 +707,7 @@ the :class:`LogRecord` being processed. Obviously changing the LogRecord needs to be done with some care, but it does allow the injection of contextual information into logs (see :ref:`filters-contextual`). + .. _log-record: LogRecord Objects @@ -722,32 +723,54 @@ wire). Contains all the information pertinent to the event being logged. - The primary information is passed in :attr:`msg` and :attr:`args`, which - are combined using ``msg % args`` to create the :attr:`message` field of the - record. - - :param name: The name of the logger used to log the event represented by - this LogRecord. Note that this name will always have this - value, even though it may be emitted by a handler attached to - a different (ancestor) logger. - :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) - Note that this is converted to *two* attributes of the LogRecord: - ``levelno`` for the numeric value and ``levelname`` for the - corresponding level name. - :param pathname: The full pathname of the source file where the logging call - was made. - :param lineno: The line number in the source file where the logging call was - made. - :param msg: The event description message, possibly a format string with - placeholders for variable data. - :param args: Variable data to merge into the *msg* argument to obtain the - event description. + The primary information is passed in *msg* and *args*, + which are combined using ``msg % args`` to create + the :attr:`!message` attribute of the record. + + :param name: The name of the logger used to log the event + represented by this :class:`!LogRecord`. + Note that the logger name in the :class:`!LogRecord` + will always have this value, + even though it may be emitted by a handler + attached to a different (ancestor) logger. + :type name: str + + :param level: The :ref:`numeric level ` of the logging event + (such as ``10`` for ``DEBUG``, ``20`` for ``INFO``, etc). + Note that this is converted to *two* attributes of the LogRecord: + :attr:`!levelno` for the numeric value + and :attr:`!levelname` for the corresponding level name. + :type level: int + + :param pathname: The full string path of the source file + where the logging call was made. + :type pathname: str + + :param lineno: The line number in the source file + where the logging call was made. + :type lineno: int + + :param msg: The event description message, + which can be a %-format string with placeholders for variable data. + :type msg: str + + :param args: Variable data to merge into the *msg* argument + to obtain the event description. + :type args: tuple | dict[str, typing.Any] + :param exc_info: An exception tuple with the current exception information, - or ``None`` if no exception information is available. - :param func: The name of the function or method from which the logging call - was invoked. - :param sinfo: A text string representing stack information from the base of - the stack in the current thread, up to the logging call. + as returned by :func:`sys.exc_info`, + or ``None`` if no exception information is available. + :type exc_info: tuple[type[BaseException], BaseException, types.TracebackType] | None + + :param func: The name of the function or method + from which the logging call was invoked. + :type func: str | None + + :param sinfo: A text string representing stack information + from the base of the stack in the current thread, + up to the logging call. + :type sinfo: str | None .. method:: getMessage() From webhook-mailer at python.org Tue Aug 2 06:05:45 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 02 Aug 2022 10:05:45 -0000 Subject: [Python-checkins] Python 3.10.6 Message-ID: https://github.com/python/cpython/commit/9c7b4bd1646f2170247f88cf59936740d9c4c004 commit: 9c7b4bd1646f2170247f88cf59936740d9c4c004 branch: 3.10 author: Pablo Galindo committer: pablogsal date: 2022-08-01T21:25:27+01:00 summary: Python 3.10.6 files: A Misc/NEWS.d/3.10.6.rst D Misc/NEWS.d/next/Build/2021-11-16-14-44-06.bpo-45816.nbdmVK.rst D Misc/NEWS.d/next/Build/2022-07-14-02-45-44.gh-issue-94841.lLRTdf.rst D Misc/NEWS.d/next/C API/2022-07-16-14-57-23.gh-issue-94864.Pb41ab.rst D Misc/NEWS.d/next/C API/2022-07-17-18-21-40.gh-issue-94930.gPFGDL.rst D Misc/NEWS.d/next/Core and Builtins/2022-05-17-20-41-43.gh-issue-92858.eIXJTn.rst D Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst D Misc/NEWS.d/next/Core and Builtins/2022-05-18-18-34-45.gh-issue-92930.kpYPOb.rst D Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst D Misc/NEWS.d/next/Core and Builtins/2022-06-10-12-03-17.gh-issue-93671.idkQqG.rst D Misc/NEWS.d/next/Core and Builtins/2022-06-21-05-07-00.gh-issue-93964.Cg1LE7.rst D Misc/NEWS.d/next/Core and Builtins/2022-06-26-14-37-03.gh-issue-94192.ab7tn7.rst D Misc/NEWS.d/next/Core and Builtins/2022-06-28-14-20-36.gh-issue-94360.DiEnen.rst D Misc/NEWS.d/next/Core and Builtins/2022-06-29-15-45-04.gh-issue-94329.olUQyk.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-15-16-15-04.gh-issue-91153.HiBmtt.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-18-04-48-34.gh-issue-94947.df9gUw.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-18-05-10-29.gh-issue-94949.OsZ7_s.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst D Misc/NEWS.d/next/Documentation/2022-03-30-17-56-01.bpo-47161.gesHfS.rst D Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst D Misc/NEWS.d/next/Documentation/2022-05-29-21-22-54.gh-issue-86986.lFXw8j.rst D Misc/NEWS.d/next/Documentation/2022-06-15-12-12-49.gh-issue-87260.epyI7D.rst D Misc/NEWS.d/next/Documentation/2022-06-16-10-10-59.gh-issue-61162.1ypkG8.rst D Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst D Misc/NEWS.d/next/Documentation/2022-07-07-08-42-05.gh-issue-94321.pmCIPb.rst D Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst D Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst D Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst D Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst D Misc/NEWS.d/next/Library/2018-09-28-22-18-03.bpo-34828.5Zyi_S.rst D Misc/NEWS.d/next/Library/2021-12-27-15-32-15.bpo-45924.0ZpHX2.rst D Misc/NEWS.d/next/Library/2022-01-03-15-07-06.bpo-46197.Z0djv6.rst D Misc/NEWS.d/next/Library/2022-02-06-12-59-32.bpo-46053.sHFo3S.rst D Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst D Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst D Misc/NEWS.d/next/Library/2022-04-15-17-38-55.gh-issue-91577.Ah7cLL.rst D Misc/NEWS.d/next/Library/2022-05-24-11-19-04.gh-issue-74696.-cnf-A.rst D Misc/NEWS.d/next/Library/2022-05-30-21-42-50.gh-issue-83658.01Ntx0.rst D Misc/NEWS.d/next/Library/2022-05-31-14-58-40.gh-issue-93353.9Hvm6o.rst D Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst D Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst D Misc/NEWS.d/next/Library/2022-06-06-12-58-27.gh-issue-79579.e8rB-M.rst D Misc/NEWS.d/next/Library/2022-06-07-14-53-46.gh-issue-90549.T4FMKY.rst D Misc/NEWS.d/next/Library/2022-06-08-20-11-02.gh-issue-90494.LIZT85.rst D Misc/NEWS.d/next/Library/2022-06-11-13-32-17.gh-issue-79512.A1KTDr.rst D Misc/NEWS.d/next/Library/2022-06-15-21-28-16.gh-issue-83499.u3DQJ-.rst D Misc/NEWS.d/next/Library/2022-06-21-11-40-31.gh-issue-84753.FW1pxO.rst D Misc/NEWS.d/next/Library/2022-06-22-11-16-11.gh-issue-94101.V9vDG8.rst D Misc/NEWS.d/next/Library/2022-06-24-19-23-59.gh-issue-94207.VhS1eS.rst D Misc/NEWS.d/next/Library/2022-06-25-13-33-18.gh-issue-94245.-zQY1a.rst D Misc/NEWS.d/next/Library/2022-06-25-16-27-02.gh-issue-94254.beP16v.rst D Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst D Misc/NEWS.d/next/Library/2022-06-29-09-48-37.gh-issue-92336.otA6c6.rst D Misc/NEWS.d/next/Library/2022-07-02-19-46-30.gh-issue-94510.xOatDC.rst D Misc/NEWS.d/next/Library/2022-07-07-15-46-55.gh-issue-94637.IYEiUM.rst D Misc/NEWS.d/next/Library/2022-07-11-10-41-48.gh-issue-94736.EbsgeK.rst D Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst D Misc/NEWS.d/next/Library/2022-07-22-17-19-57.gh-issue-93157.RXByAk.rst D Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst D Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst D Misc/NEWS.d/next/Library/2022-07-24-09-15-35.gh-issue-95194.ERVmqG.rst D Misc/NEWS.d/next/Library/2022-07-24-12-00-06.gh-issue-95199.-5A64k.rst D Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst D Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst D Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst D Misc/NEWS.d/next/Security/2022-05-19-08-53-07.gh-issue-92888.TLtR9W.rst D Misc/NEWS.d/next/Security/2022-06-15-20-09-23.gh-issue-87389.QVaC3f.rst D Misc/NEWS.d/next/Tests/2022-03-14-23-28-17.bpo-47016.K-t2QX.rst D Misc/NEWS.d/next/Tests/2022-05-25-23-00-35.gh-issue-92886.Y-vrWj.rst D Misc/NEWS.d/next/Tests/2022-06-03-16-26-04.gh-issue-57539.HxWgYO.rst D Misc/NEWS.d/next/Tests/2022-06-17-13-55-11.gh-issue-93957.X4ovYV.rst D Misc/NEWS.d/next/Tests/2022-06-17-15-20-09.gh-issue-93951.CW1Vv4.rst D Misc/NEWS.d/next/Tests/2022-06-27-21-27-20.gh-issue-94208.VR6HX-.rst D Misc/NEWS.d/next/Tests/2022-07-05-17-53-13.gh-issue-91330.Qys5IL.rst D Misc/NEWS.d/next/Tests/2022-07-24-20-19-05.gh-issue-95212.fHiU4e.rst D Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst D Misc/NEWS.d/next/Tools-Demos/2022-06-29-22-47-11.gh-issue-94430.hdov8L.rst D Misc/NEWS.d/next/Tools-Demos/2022-07-04-01-37-42.gh-issue-94538.1rgy1Y.rst D Misc/NEWS.d/next/Windows/2022-03-20-15-47-35.bpo-42658.16eXtb.rst D Misc/NEWS.d/next/Windows/2022-05-16-11-45-06.gh-issue-92841.NQx107.rst D Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 2d2e7a858fca2..cef4374cbca24 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 10 -#define PY_MICRO_VERSION 5 +#define PY_MICRO_VERSION 6 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.10.5+" +#define PY_VERSION "3.10.6" /*--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 17f0cb4f2042f..6473b95e6da3e 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 Jun 6 12:53:10 2022 +# Autogenerated by Sphinx on Mon Aug 1 21:23:42 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -4091,7 +4091,7 @@ ' invoking the superclass?s "__new__()" method using\n' ' "super().__new__(cls[, ...])" with appropriate arguments ' 'and then\n' - ' modifying the newly-created instance as necessary before ' + ' modifying the newly created instance as necessary before ' 'returning\n' ' it.\n' '\n' @@ -4494,7 +4494,7 @@ 'Python.This is\n' ' intended to provide protection against a ' 'denial-of-service caused\n' - ' by carefully-chosen inputs that exploit the worst ' + ' by carefully chosen inputs that exploit the worst ' 'case\n' ' performance of a dict insertion, O(n^2) complexity. ' 'See\n' @@ -9000,7 +9000,7 @@ ' invoking the superclass?s "__new__()" method using\n' ' "super().__new__(cls[, ...])" with appropriate arguments ' 'and then\n' - ' modifying the newly-created instance as necessary before ' + ' modifying the newly created instance as necessary before ' 'returning\n' ' it.\n' '\n' @@ -9401,7 +9401,7 @@ 'is\n' ' intended to provide protection against a ' 'denial-of-service caused\n' - ' by carefully-chosen inputs that exploit the worst case\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 ' diff --git a/Misc/NEWS.d/3.10.6.rst b/Misc/NEWS.d/3.10.6.rst new file mode 100644 index 0000000000000..fbbb77d91ab81 --- /dev/null +++ b/Misc/NEWS.d/3.10.6.rst @@ -0,0 +1,824 @@ +.. date: 2022-06-15-20-09-23 +.. gh-issue: 87389 +.. nonce: QVaC3f +.. release date: 2022-08-01 +.. section: Security + +:mod:`http.server`: Fix an open redirection vulnerability in the HTTP server +when an URI path starts with ``//``. Vulnerability discovered, and initial +fix proposed, by Hamza Avvan. + +.. + +.. date: 2022-05-19-08-53-07 +.. gh-issue: 92888 +.. nonce: TLtR9W +.. section: Security + +Fix ``memoryview`` use after free when accessing the backing buffer in +certain cases. + +.. + +.. date: 2022-07-28-08-33-31 +.. gh-issue: 95355 +.. nonce: yN4XVk +.. section: Core and Builtins + +``_PyPegen_Parser_New`` now properly detects token memory allocation errors. +Patch by Honglin Zhu. + +.. + +.. date: 2022-07-19-09-41-55 +.. gh-issue: 94938 +.. nonce: xYBlM7 +.. section: Core and Builtins + +Fix error detection in some builtin functions when keyword argument name is +an instance of a str subclass with overloaded ``__eq__`` and ``__hash__``. +Previously it could cause SystemError or other undesired behavior. + +.. + +.. date: 2022-07-18-05-10-29 +.. gh-issue: 94949 +.. nonce: OsZ7_s +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse parenthesized context managers when +passed ``feature_version`` less than ``(3, 9)``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-18-04-48-34 +.. gh-issue: 94947 +.. nonce: df9gUw +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse assignment expressions when passed +``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-16-08-14-17 +.. gh-issue: 94869 +.. nonce: eRwMsX +.. section: Core and Builtins + +Fix the column offsets for some expressions in multi-line f-strings +:mod:`ast` nodes. Patch by Pablo Galindo. + +.. + +.. date: 2022-07-15-16-15-04 +.. gh-issue: 91153 +.. nonce: HiBmtt +.. section: Core and Builtins + +Fix an issue where a :class:`bytearray` item assignment could crash if it's +resized by the new value's :meth:`__index__` method. + +.. + +.. date: 2022-06-29-15-45-04 +.. gh-issue: 94329 +.. nonce: olUQyk +.. section: Core and Builtins + +Compile and run code with unpacking of extremely large sequences (1000s of +elements). Such code failed to compile. It now compiles and runs correctly. + +.. + +.. date: 2022-06-28-14-20-36 +.. gh-issue: 94360 +.. nonce: DiEnen +.. section: Core and Builtins + +Fixed a tokenizer crash when reading encoded files with syntax errors from +``stdin`` with non utf-8 encoded text. Patch by Pablo Galindo + +.. + +.. date: 2022-06-26-14-37-03 +.. gh-issue: 94192 +.. nonce: ab7tn7 +.. section: Core and Builtins + +Fix error for dictionary literals with invalid expression as value. + +.. + +.. date: 2022-06-21-05-07-00 +.. gh-issue: 93964 +.. nonce: Cg1LE7 +.. section: Core and Builtins + +Strengthened compiler overflow checks to prevent crashes when compiling very +large source files. + +.. + +.. date: 2022-06-10-12-03-17 +.. gh-issue: 93671 +.. nonce: idkQqG +.. section: Core and Builtins + +Fix some exponential backtrace case happening with deeply nested sequence +patterns in match statements. Patch by Pablo Galindo + +.. + +.. date: 2022-05-20-09-25-34 +.. gh-issue: 93021 +.. nonce: k3Aji2 +.. section: Core and Builtins + +Fix the :attr:`__text_signature__` for :meth:`__get__` methods implemented +in C. Patch by Jelle Zijlstra. + +.. + +.. date: 2022-05-18-18-34-45 +.. gh-issue: 92930 +.. nonce: kpYPOb +.. section: Core and Builtins + +Fixed a crash in ``_pickle.c`` from mutating collections during +``__reduce__`` or ``persistent_id``. + +.. + +.. date: 2022-05-18-08-32-33 +.. gh-issue: 92914 +.. nonce: tJUeTD +.. section: Core and Builtins + +Always round the allocated size for lists up to the nearest even number. + +.. + +.. date: 2022-05-17-20-41-43 +.. gh-issue: 92858 +.. nonce: eIXJTn +.. section: Core and Builtins + +Improve error message for some suites with syntax error before ':' + +.. + +.. date: 2022-07-27-19-43-07 +.. gh-issue: 95339 +.. nonce: NuVQ68 +.. section: Library + +Update bundled pip to 22.2.1. + +.. + +.. date: 2022-07-27-11-35-45 +.. gh-issue: 95045 +.. nonce: iysT-Q +.. section: Library + +Fix GC crash when deallocating ``_lsprof.Profiler`` by untracking it before +calling any callbacks. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-24-12-59-02 +.. gh-issue: 95087 +.. nonce: VvqXkN +.. section: Library + +Fix IndexError in parsing invalid date in the :mod:`email` module. + +.. + +.. date: 2022-07-24-12-00-06 +.. gh-issue: 95199 +.. nonce: -5A64k +.. section: Library + +Upgrade bundled setuptools to 63.2.0. + +.. + +.. date: 2022-07-24-09-15-35 +.. gh-issue: 95194 +.. nonce: ERVmqG +.. section: Library + +Upgrade bundled pip to 22.2. + +.. + +.. date: 2022-07-23-10-50-05 +.. gh-issue: 93899 +.. nonce: VT34A5 +.. section: Library + +Fix check for existence of :data:`os.EFD_CLOEXEC`, :data:`os.EFD_NONBLOCK` +and :data:`os.EFD_SEMAPHORE` flags on older kernel versions where these +flags are not present. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-23-10-42-05 +.. gh-issue: 95166 +.. nonce: xw6p3C +.. section: Library + +Fix :meth:`concurrent.futures.Executor.map` to cancel the currently waiting +on future on an error - e.g. TimeoutError or KeyboardInterrupt. + +.. + +.. date: 2022-07-22-17-19-57 +.. gh-issue: 93157 +.. nonce: RXByAk +.. section: Library + +Fix :mod:`fileinput` module didn't support ``errors`` option when +``inplace`` is true. + +.. + +.. date: 2022-07-14-00-43-52 +.. gh-issue: 94821 +.. nonce: e17ghU +.. section: Library + +Fix binding of unix socket to empty address on Linux to use an available +address from the abstract namespace, instead of "\0". + +.. + +.. date: 2022-07-11-10-41-48 +.. gh-issue: 94736 +.. nonce: EbsgeK +.. section: Library + +Fix crash when deallocating an instance of a subclass of +``_multiprocessing.SemLock``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-07-15-46-55 +.. gh-issue: 94637 +.. nonce: IYEiUM +.. section: Library + +:meth:`SSLContext.set_default_verify_paths` now releases the GIL around +``SSL_CTX_set_default_verify_paths`` call. The function call performs I/O +and CPU intensive work. + +.. + +.. date: 2022-07-02-19-46-30 +.. gh-issue: 94510 +.. nonce: xOatDC +.. section: Library + +Re-entrant calls to :func:`sys.setprofile` and :func:`sys.settrace` now +raise :exc:`RuntimeError`. Patch by Pablo Galindo. + +.. + +.. date: 2022-06-29-09-48-37 +.. gh-issue: 92336 +.. nonce: otA6c6 +.. section: Library + +Fix bug where :meth:`linecache.getline` fails on bad files with +:exc:`UnicodeDecodeError` or :exc:`SyntaxError`. It now returns an empty +string as per the documentation. + +.. + +.. date: 2022-06-26-10-59-15 +.. gh-issue: 89988 +.. nonce: K8rnmt +.. section: Library + +Fix memory leak in :class:`pickle.Pickler` when looking up +:attr:`dispatch_table`. Patch by Kumar Aditya. + +.. + +.. date: 2022-06-25-16-27-02 +.. gh-issue: 94254 +.. nonce: beP16v +.. section: Library + +Fixed types of :mod:`struct` module to be immutable. Patch by Kumar Aditya. + +.. + +.. date: 2022-06-25-13-33-18 +.. gh-issue: 94245 +.. nonce: -zQY1a +.. section: Library + +Fix pickling and copying of ``typing.Tuple[()]``. + +.. + +.. date: 2022-06-24-19-23-59 +.. gh-issue: 94207 +.. nonce: VhS1eS +.. section: Library + +Made :class:`_struct.Struct` GC-tracked in order to fix a reference leak in +the :mod:`_struct` module. + +.. + +.. date: 2022-06-22-11-16-11 +.. gh-issue: 94101 +.. nonce: V9vDG8 +.. section: Library + +Manual instantiation of :class:`ssl.SSLSession` objects is no longer allowed +as it lead to misconfigured instances that crashed the interpreter when +attributes where accessed on them. + +.. + +.. date: 2022-06-21-11-40-31 +.. gh-issue: 84753 +.. nonce: FW1pxO +.. section: Library + +:func:`inspect.iscoroutinefunction`, :func:`inspect.isgeneratorfunction`, +and :func:`inspect.isasyncgenfunction` now properly return ``True`` for +duck-typed function-like objects like instances of +:class:`unittest.mock.AsyncMock`. + +This makes :func:`inspect.iscoroutinefunction` consistent with the behavior +of :func:`asyncio.iscoroutinefunction`. Patch by Mehdi ABAAKOUK. + +.. + +.. date: 2022-06-15-21-28-16 +.. gh-issue: 83499 +.. nonce: u3DQJ- +.. section: Library + +Fix double closing of file description in :mod:`tempfile`. + +.. + +.. date: 2022-06-11-13-32-17 +.. gh-issue: 79512 +.. nonce: A1KTDr +.. section: Library + +Fixed names and ``__module__`` value of :mod:`weakref` classes +:class:`~weakref.ReferenceType`, :class:`~weakref.ProxyType`, +:class:`~weakref.CallableProxyType`. It makes them pickleable. + +.. + +.. date: 2022-06-08-20-11-02 +.. gh-issue: 90494 +.. nonce: LIZT85 +.. section: Library + +:func:`copy.copy` and :func:`copy.deepcopy` now always raise a TypeError if +``__reduce__()`` returns a tuple with length 6 instead of silently ignore +the 6th item or produce incorrect result. + +.. + +.. date: 2022-06-07-14-53-46 +.. gh-issue: 90549 +.. nonce: T4FMKY +.. section: Library + +Fix a multiprocessing bug where a global named resource (such as a +semaphore) could leak when a child process is spawned (as opposed to +forked). + +.. + +.. date: 2022-06-06-12-58-27 +.. gh-issue: 79579 +.. nonce: e8rB-M +.. section: Library + +:mod:`sqlite3` now correctly detects DML queries with leading comments. +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-05-22-22-42 +.. gh-issue: 93421 +.. nonce: 43UO_8 +.. section: Library + +Update :data:`sqlite3.Cursor.rowcount` when a DML statement has run to +completion. This fixes the row count for SQL queries like ``UPDATE ... +RETURNING``. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-02-08-40-58 +.. gh-issue: 91810 +.. nonce: Gtk44w +.. section: Library + +Suppress writing an XML declaration in open files in ``ElementTree.write()`` +with ``encoding='unicode'`` and ``xml_declaration=None``. + +.. + +.. date: 2022-05-31-14-58-40 +.. gh-issue: 93353 +.. nonce: 9Hvm6o +.. section: Library + +Fix the :func:`importlib.resources.as_file` context manager to remove the +temporary file if destroyed late during Python finalization: keep a local +reference to the :func:`os.remove` function. Patch by Victor Stinner. + +.. + +.. date: 2022-05-30-21-42-50 +.. gh-issue: 83658 +.. nonce: 01Ntx0 +.. section: Library + +Make :class:`multiprocessing.Pool` raise an exception if +``maxtasksperchild`` is not ``None`` or a positive int. + +.. + +.. date: 2022-05-24-11-19-04 +.. gh-issue: 74696 +.. nonce: -cnf-A +.. section: Library + +:func:`shutil.make_archive` no longer temporarily changes the current +working directory during creation of standard ``.zip`` or tar archives. + +.. + +.. date: 2022-04-15-17-38-55 +.. gh-issue: 91577 +.. nonce: Ah7cLL +.. section: Library + +Move imports in :class:`~multiprocessing.SharedMemory` methods to module +level so that they can be executed late in python finalization. + +.. + +.. bpo: 47231 +.. date: 2022-04-08-22-12-11 +.. nonce: lvyglt +.. section: Library + +Fixed an issue with inconsistent trailing slashes in tarfile longname +directories. + +.. + +.. bpo: 46755 +.. date: 2022-02-15-12-40-48 +.. nonce: zePJfx +.. section: Library + +In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to +prevent stack trace from being written twice. + +.. + +.. bpo: 46053 +.. date: 2022-02-06-12-59-32 +.. nonce: sHFo3S +.. section: Library + +Fix OSS audio support on NetBSD. + +.. + +.. bpo: 46197 +.. date: 2022-01-03-15-07-06 +.. nonce: Z0djv6 +.. section: Library + +Fix :mod:`ensurepip` environment isolation for subprocess running ``pip``. + +.. + +.. bpo: 45924 +.. date: 2021-12-27-15-32-15 +.. nonce: 0ZpHX2 +.. section: Library + +Fix :mod:`asyncio` incorrect traceback when future's exception is raised +multiple times. Patch by Kumar Aditya. + +.. + +.. bpo: 34828 +.. date: 2018-09-28-22-18-03 +.. nonce: 5Zyi_S +.. section: Library + +:meth:`sqlite3.Connection.iterdump` now handles databases that use +``AUTOINCREMENT`` in one or more tables. + +.. + +.. date: 2022-07-07-08-42-05 +.. gh-issue: 94321 +.. nonce: pmCIPb +.. section: Documentation + +Document the :pep:`246` style protocol type +:class:`sqlite3.PrepareProtocol`. + +.. + +.. date: 2022-06-19-18-18-22 +.. gh-issue: 86128 +.. nonce: 39DDTD +.. section: Documentation + +Document a limitation in ThreadPoolExecutor where its exit handler is +executed before any handlers in atexit. + +.. + +.. date: 2022-06-16-10-10-59 +.. gh-issue: 61162 +.. nonce: 1ypkG8 +.. section: Documentation + +Clarify :mod:`sqlite3` behavior when +:ref:`sqlite3-connection-context-manager`. + +.. + +.. date: 2022-06-15-12-12-49 +.. gh-issue: 87260 +.. nonce: epyI7D +.. section: Documentation + +Align :mod:`sqlite3` argument specs with the actual implementation. + +.. + +.. date: 2022-05-29-21-22-54 +.. gh-issue: 86986 +.. nonce: lFXw8j +.. section: Documentation + +The minimum Sphinx version required to build the documentation is now 3.2. + +.. + +.. date: 2022-05-26-14-51-25 +.. gh-issue: 88831 +.. nonce: 5Cccr5 +.. section: Documentation + +Augmented documentation of asyncio.create_task(). Clarified the need to keep +strong references to tasks and added a code snippet detailing how to to +this. + +.. + +.. bpo: 47161 +.. date: 2022-03-30-17-56-01 +.. nonce: gesHfS +.. section: Documentation + +Document that :class:`pathlib.PurePath` does not collapse initial double +slashes because they denote UNC paths. + +.. + +.. date: 2022-07-26-15-22-19 +.. gh-issue: 95280 +.. nonce: h8HvbP +.. section: Tests + +Fix problem with ``test_ssl`` ``test_get_ciphers`` on systems that require +perfect forward secrecy (PFS) ciphers. + +.. + +.. date: 2022-07-24-20-19-05 +.. gh-issue: 95212 +.. nonce: fHiU4e +.. section: Tests + +Make multiprocessing test case ``test_shared_memory_recreate`` +parallel-safe. + +.. + +.. date: 2022-07-05-17-53-13 +.. gh-issue: 91330 +.. nonce: Qys5IL +.. section: Tests + +Added more tests for :mod:`dataclasses` to cover behavior with data +descriptor-based fields. + +# Write your Misc/NEWS entry below. It should be a simple ReST paragraph. # +Don't start with "- Issue #: " or "- gh-issue-: " or that sort of +stuff. +########################################################################### + +.. + +.. date: 2022-06-27-21-27-20 +.. gh-issue: 94208 +.. nonce: VR6HX- +.. section: Tests + +``test_ssl`` is now checking for supported TLS version and protocols in more +tests. + +.. + +.. date: 2022-06-17-15-20-09 +.. gh-issue: 93951 +.. nonce: CW1Vv4 +.. section: Tests + +In test_bdb.StateTestCase.test_skip, avoid including auxiliary importers. + +.. + +.. date: 2022-06-17-13-55-11 +.. gh-issue: 93957 +.. nonce: X4ovYV +.. section: Tests + +Provide nicer error reporting from subprocesses in +test_venv.EnsurePipTest.test_with_pip. + +.. + +.. date: 2022-06-03-16-26-04 +.. gh-issue: 57539 +.. nonce: HxWgYO +.. section: Tests + +Increase calendar test coverage for +:meth:`calendar.LocaleTextCalendar.formatweekday`. + +.. + +.. date: 2022-05-25-23-00-35 +.. gh-issue: 92886 +.. nonce: Y-vrWj +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_zipimport.py`` + +.. + +.. bpo: 47016 +.. date: 2022-03-14-23-28-17 +.. nonce: K-t2QX +.. section: Tests + +Create a GitHub Actions workflow for verifying bundled pip and setuptools. +Patch by Illia Volochii and Adam Turner. + +.. + +.. date: 2022-07-14-02-45-44 +.. gh-issue: 94841 +.. nonce: lLRTdf +.. section: Build + +Fix the possible performance regression of :c:func:`PyObject_Free` compiled +with MSVC version 1932. + +.. + +.. bpo: 45816 +.. date: 2021-11-16-14-44-06 +.. nonce: nbdmVK +.. section: Build + +Python now supports building with Visual Studio 2022 (MSVC v143, VS Version +17.0). Patch by Jeremiah Vivian. + +.. + +.. date: 2022-07-16-16-18-32 +.. gh-issue: 90844 +.. nonce: vwITT3 +.. section: Windows + +Allow virtual environments to correctly launch when they have spaces in the +path. + +.. + +.. date: 2022-05-16-11-45-06 +.. gh-issue: 92841 +.. nonce: NQx107 +.. section: Windows + +:mod:`asyncio` no longer throws ``RuntimeError: Event loop is closed`` on +interpreter exit after asynchronous socket activity. Patch by Oleg Iarygin. + +.. + +.. bpo: 42658 +.. date: 2022-03-20-15-47-35 +.. nonce: 16eXtb +.. section: Windows + +Support native Windows case-insensitive path comparisons by using +``LCMapStringEx`` instead of :func:`str.lower` in :func:`ntpath.normcase`. +Add ``LCMapStringEx`` to the :mod:`_winapi` module. + +.. + +.. date: 2022-07-31-22-15-14 +.. gh-issue: 95511 +.. nonce: WX6PmB +.. section: IDLE + +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. + +.. + +.. date: 2022-07-30-15-10-39 +.. gh-issue: 95471 +.. nonce: z3scVG +.. section: IDLE + +In the Edit menu, move ``Select All`` and add a new separator. + +.. + +.. date: 2022-07-29-11-08-52 +.. gh-issue: 95411 +.. nonce: dazlqH +.. section: IDLE + +Enable using IDLE's module browser with .pyw files. + +.. + +.. date: 2022-07-28-18-56-57 +.. gh-issue: 89610 +.. nonce: hcosiM +.. section: IDLE + +Add .pyi as a recognized extension for IDLE on macOS. This allows opening +stub files by double clicking on them in the Finder. + +.. + +.. date: 2022-07-04-01-37-42 +.. gh-issue: 94538 +.. nonce: 1rgy1Y +.. section: Tools/Demos + +Fix Argument Clinic output to custom file destinations. Patch by Erlend E. +Aasland. + +.. + +.. date: 2022-06-29-22-47-11 +.. gh-issue: 94430 +.. nonce: hdov8L +.. section: Tools/Demos + +Allow parameters named ``module`` and ``self`` with custom C names in +Argument Clinic. Patch by Erlend E. Aasland + +.. + +.. date: 2022-07-17-18-21-40 +.. gh-issue: 94930 +.. nonce: gPFGDL +.. section: C API + +Fix ``SystemError`` raised when :c:func:`PyArg_ParseTupleAndKeywords` is +used with ``#`` in ``(...)`` but without ``PY_SSIZE_T_CLEAN`` defined. + +.. + +.. date: 2022-07-16-14-57-23 +.. gh-issue: 94864 +.. nonce: Pb41ab +.. section: C API + +Fix ``PyArg_Parse*`` with deprecated format units "u" and "Z". It returned 1 +(success) when warnings are turned into exceptions. diff --git a/Misc/NEWS.d/next/Build/2021-11-16-14-44-06.bpo-45816.nbdmVK.rst b/Misc/NEWS.d/next/Build/2021-11-16-14-44-06.bpo-45816.nbdmVK.rst deleted file mode 100644 index 4a14c90bf0138..0000000000000 --- a/Misc/NEWS.d/next/Build/2021-11-16-14-44-06.bpo-45816.nbdmVK.rst +++ /dev/null @@ -1 +0,0 @@ -Python now supports building with Visual Studio 2022 (MSVC v143, VS Version 17.0). Patch by Jeremiah Vivian. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Build/2022-07-14-02-45-44.gh-issue-94841.lLRTdf.rst b/Misc/NEWS.d/next/Build/2022-07-14-02-45-44.gh-issue-94841.lLRTdf.rst deleted file mode 100644 index f7ad4f88a51db..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-07-14-02-45-44.gh-issue-94841.lLRTdf.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the possible performance regression of :c:func:`PyObject_Free` compiled with MSVC version 1932. diff --git a/Misc/NEWS.d/next/C API/2022-07-16-14-57-23.gh-issue-94864.Pb41ab.rst b/Misc/NEWS.d/next/C API/2022-07-16-14-57-23.gh-issue-94864.Pb41ab.rst deleted file mode 100644 index ed2a954778020..0000000000000 --- a/Misc/NEWS.d/next/C API/2022-07-16-14-57-23.gh-issue-94864.Pb41ab.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``PyArg_Parse*`` with deprecated format units "u" and "Z". It returned 1 -(success) when warnings are turned into exceptions. diff --git a/Misc/NEWS.d/next/C API/2022-07-17-18-21-40.gh-issue-94930.gPFGDL.rst b/Misc/NEWS.d/next/C API/2022-07-17-18-21-40.gh-issue-94930.gPFGDL.rst deleted file mode 100644 index 5b79d757b1e4a..0000000000000 --- a/Misc/NEWS.d/next/C API/2022-07-17-18-21-40.gh-issue-94930.gPFGDL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``SystemError`` raised when :c:func:`PyArg_ParseTupleAndKeywords` is -used with ``#`` in ``(...)`` but without ``PY_SSIZE_T_CLEAN`` defined. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-17-20-41-43.gh-issue-92858.eIXJTn.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-17-20-41-43.gh-issue-92858.eIXJTn.rst deleted file mode 100644 index fa91d941b1759..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-17-20-41-43.gh-issue-92858.eIXJTn.rst +++ /dev/null @@ -1 +0,0 @@ -Improve error message for some suites with syntax error before ':' diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst deleted file mode 100644 index 1242a15c029dc..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst +++ /dev/null @@ -1 +0,0 @@ -Always round the allocated size for lists up to the nearest even number. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-18-18-34-45.gh-issue-92930.kpYPOb.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-18-18-34-45.gh-issue-92930.kpYPOb.rst deleted file mode 100644 index cd5d7b3214ea4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-18-18-34-45.gh-issue-92930.kpYPOb.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a crash in ``_pickle.c`` from mutating collections during ``__reduce__`` or ``persistent_id``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst deleted file mode 100644 index 8fdd8dfb4229a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the :attr:`__text_signature__` for :meth:`__get__` methods implemented -in C. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-10-12-03-17.gh-issue-93671.idkQqG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-10-12-03-17.gh-issue-93671.idkQqG.rst deleted file mode 100644 index a775715335951..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-10-12-03-17.gh-issue-93671.idkQqG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix some exponential backtrace case happening with deeply nested sequence -patterns in match statements. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-21-05-07-00.gh-issue-93964.Cg1LE7.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-21-05-07-00.gh-issue-93964.Cg1LE7.rst deleted file mode 100644 index b184a7b2f7116..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-21-05-07-00.gh-issue-93964.Cg1LE7.rst +++ /dev/null @@ -1 +0,0 @@ -Strengthened compiler overflow checks to prevent crashes when compiling very large source files. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-26-14-37-03.gh-issue-94192.ab7tn7.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-26-14-37-03.gh-issue-94192.ab7tn7.rst deleted file mode 100644 index ebd8b04e45091..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-26-14-37-03.gh-issue-94192.ab7tn7.rst +++ /dev/null @@ -1 +0,0 @@ -Fix error for dictionary literals with invalid expression as value. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-28-14-20-36.gh-issue-94360.DiEnen.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-28-14-20-36.gh-issue-94360.DiEnen.rst deleted file mode 100644 index 0a74ba38b0ac4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-28-14-20-36.gh-issue-94360.DiEnen.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a tokenizer crash when reading encoded files with syntax errors from -``stdin`` with non utf-8 encoded text. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-29-15-45-04.gh-issue-94329.olUQyk.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-29-15-45-04.gh-issue-94329.olUQyk.rst deleted file mode 100644 index afd31b6e4dc44..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-29-15-45-04.gh-issue-94329.olUQyk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Compile and run code with unpacking of extremely large sequences (1000s of elements). -Such code failed to compile. It now compiles and runs correctly. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-15-16-15-04.gh-issue-91153.HiBmtt.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-15-16-15-04.gh-issue-91153.HiBmtt.rst deleted file mode 100644 index 2caa0170f75bc..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-15-16-15-04.gh-issue-91153.HiBmtt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue where a :class:`bytearray` item assignment could crash if it's -resized by the new value's :meth:`__index__` method. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst deleted file mode 100644 index 2ccf91b0cd99a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-16-08-14-17.gh-issue-94869.eRwMsX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the column offsets for some expressions in multi-line f-strings -:mod:`ast` nodes. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-18-04-48-34.gh-issue-94947.df9gUw.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-18-04-48-34.gh-issue-94947.df9gUw.rst deleted file mode 100644 index 360ea67048fe2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-18-04-48-34.gh-issue-94947.df9gUw.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`ast.parse` will no longer parse assignment expressions when passed ``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-18-05-10-29.gh-issue-94949.OsZ7_s.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-18-05-10-29.gh-issue-94949.OsZ7_s.rst deleted file mode 100644 index bc452d434da0f..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-18-05-10-29.gh-issue-94949.OsZ7_s.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`ast.parse` will no longer parse parenthesized context managers when passed ``feature_version`` less than ``(3, 9)``. Patch by Shantanu Jain. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst deleted file mode 100644 index cc4feae685f23..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix error detection in some builtin functions when keyword argument name is -an instance of a str subclass with overloaded ``__eq__`` and ``__hash__``. -Previously it could cause SystemError or other undesired behavior. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst deleted file mode 100644 index 6a289991e0d60..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst +++ /dev/null @@ -1 +0,0 @@ -``_PyPegen_Parser_New`` now properly detects token memory allocation errors. Patch by Honglin Zhu. diff --git a/Misc/NEWS.d/next/Documentation/2022-03-30-17-56-01.bpo-47161.gesHfS.rst b/Misc/NEWS.d/next/Documentation/2022-03-30-17-56-01.bpo-47161.gesHfS.rst deleted file mode 100644 index 6b552daa7c13a..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-03-30-17-56-01.bpo-47161.gesHfS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document that :class:`pathlib.PurePath` does not collapse -initial double slashes because they denote UNC paths. diff --git a/Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst b/Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst deleted file mode 100644 index 983bea981a9b2..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-05-26-14-51-25.gh-issue-88831.5Cccr5.rst +++ /dev/null @@ -1 +0,0 @@ -Augmented documentation of asyncio.create_task(). Clarified the need to keep strong references to tasks and added a code snippet detailing how to to this. diff --git a/Misc/NEWS.d/next/Documentation/2022-05-29-21-22-54.gh-issue-86986.lFXw8j.rst b/Misc/NEWS.d/next/Documentation/2022-05-29-21-22-54.gh-issue-86986.lFXw8j.rst deleted file mode 100644 index 1db028c30f67a..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-05-29-21-22-54.gh-issue-86986.lFXw8j.rst +++ /dev/null @@ -1 +0,0 @@ -The minimum Sphinx version required to build the documentation is now 3.2. diff --git a/Misc/NEWS.d/next/Documentation/2022-06-15-12-12-49.gh-issue-87260.epyI7D.rst b/Misc/NEWS.d/next/Documentation/2022-06-15-12-12-49.gh-issue-87260.epyI7D.rst deleted file mode 100644 index 4c6cee86ca115..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-06-15-12-12-49.gh-issue-87260.epyI7D.rst +++ /dev/null @@ -1 +0,0 @@ -Align :mod:`sqlite3` argument specs with the actual implementation. diff --git a/Misc/NEWS.d/next/Documentation/2022-06-16-10-10-59.gh-issue-61162.1ypkG8.rst b/Misc/NEWS.d/next/Documentation/2022-06-16-10-10-59.gh-issue-61162.1ypkG8.rst deleted file mode 100644 index c8b3a22223218..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-06-16-10-10-59.gh-issue-61162.1ypkG8.rst +++ /dev/null @@ -1 +0,0 @@ -Clarify :mod:`sqlite3` behavior when :ref:`sqlite3-connection-context-manager`. diff --git a/Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst b/Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst deleted file mode 100644 index bab006856deea..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst +++ /dev/null @@ -1 +0,0 @@ -Document a limitation in ThreadPoolExecutor where its exit handler is executed before any handlers in atexit. diff --git a/Misc/NEWS.d/next/Documentation/2022-07-07-08-42-05.gh-issue-94321.pmCIPb.rst b/Misc/NEWS.d/next/Documentation/2022-07-07-08-42-05.gh-issue-94321.pmCIPb.rst deleted file mode 100644 index c1a8dcd853538..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-07-07-08-42-05.gh-issue-94321.pmCIPb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document the :pep:`246` style protocol type -:class:`sqlite3.PrepareProtocol`. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst b/Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst deleted file mode 100644 index 0d283711e3e86..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add .pyi as a recognized extension for IDLE on macOS. This allows opening -stub files by double clicking on them in the Finder. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst b/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst deleted file mode 100644 index 94ca8b2c2ea95..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst +++ /dev/null @@ -1 +0,0 @@ -Enable using IDLE's module browser with .pyw files. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst b/Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst deleted file mode 100644 index 73a9d8058965c..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst +++ /dev/null @@ -1 +0,0 @@ -In the Edit menu, move ``Select All`` and add a new separator. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst deleted file mode 100644 index 803fa5f2a2ab0..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the Shell context menu copy-with-prompts bug of copying an extra line -when one selects whole lines. diff --git a/Misc/NEWS.d/next/Library/2018-09-28-22-18-03.bpo-34828.5Zyi_S.rst b/Misc/NEWS.d/next/Library/2018-09-28-22-18-03.bpo-34828.5Zyi_S.rst deleted file mode 100644 index b0e10a158b5b1..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-09-28-22-18-03.bpo-34828.5Zyi_S.rst +++ /dev/null @@ -1 +0,0 @@ -:meth:`sqlite3.Connection.iterdump` now handles databases that use ``AUTOINCREMENT`` in one or more tables. diff --git a/Misc/NEWS.d/next/Library/2021-12-27-15-32-15.bpo-45924.0ZpHX2.rst b/Misc/NEWS.d/next/Library/2021-12-27-15-32-15.bpo-45924.0ZpHX2.rst deleted file mode 100644 index 5cda22737adb7..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-27-15-32-15.bpo-45924.0ZpHX2.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`asyncio` incorrect traceback when future's exception is raised multiple times. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-01-03-15-07-06.bpo-46197.Z0djv6.rst b/Misc/NEWS.d/next/Library/2022-01-03-15-07-06.bpo-46197.Z0djv6.rst deleted file mode 100644 index 7a3b2d59dfaf4..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-03-15-07-06.bpo-46197.Z0djv6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`ensurepip` environment isolation for subprocess running ``pip``. diff --git a/Misc/NEWS.d/next/Library/2022-02-06-12-59-32.bpo-46053.sHFo3S.rst b/Misc/NEWS.d/next/Library/2022-02-06-12-59-32.bpo-46053.sHFo3S.rst deleted file mode 100644 index ce375885792e8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-06-12-59-32.bpo-46053.sHFo3S.rst +++ /dev/null @@ -1 +0,0 @@ -Fix OSS audio support on NetBSD. diff --git a/Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst b/Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst deleted file mode 100644 index 399caf7253593..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst +++ /dev/null @@ -1,2 +0,0 @@ -In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to -prevent stack trace from being written twice. diff --git a/Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst b/Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst deleted file mode 100644 index ee05c5e285675..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed an issue with inconsistent trailing slashes in tarfile longname directories. diff --git a/Misc/NEWS.d/next/Library/2022-04-15-17-38-55.gh-issue-91577.Ah7cLL.rst b/Misc/NEWS.d/next/Library/2022-04-15-17-38-55.gh-issue-91577.Ah7cLL.rst deleted file mode 100644 index 0f44f34011f9c..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-15-17-38-55.gh-issue-91577.Ah7cLL.rst +++ /dev/null @@ -1 +0,0 @@ -Move imports in :class:`~multiprocessing.SharedMemory` methods to module level so that they can be executed late in python finalization. diff --git a/Misc/NEWS.d/next/Library/2022-05-24-11-19-04.gh-issue-74696.-cnf-A.rst b/Misc/NEWS.d/next/Library/2022-05-24-11-19-04.gh-issue-74696.-cnf-A.rst deleted file mode 100644 index 5b2e460e9ea07..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-24-11-19-04.gh-issue-74696.-cnf-A.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`shutil.make_archive` no longer temporarily changes the current -working directory during creation of standard ``.zip`` or tar archives. diff --git a/Misc/NEWS.d/next/Library/2022-05-30-21-42-50.gh-issue-83658.01Ntx0.rst b/Misc/NEWS.d/next/Library/2022-05-30-21-42-50.gh-issue-83658.01Ntx0.rst deleted file mode 100644 index a187309540980..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-30-21-42-50.gh-issue-83658.01Ntx0.rst +++ /dev/null @@ -1 +0,0 @@ -Make :class:`multiprocessing.Pool` raise an exception if ``maxtasksperchild`` is not ``None`` or a positive int. diff --git a/Misc/NEWS.d/next/Library/2022-05-31-14-58-40.gh-issue-93353.9Hvm6o.rst b/Misc/NEWS.d/next/Library/2022-05-31-14-58-40.gh-issue-93353.9Hvm6o.rst deleted file mode 100644 index 67be3c68f47cb..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-05-31-14-58-40.gh-issue-93353.9Hvm6o.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix the :func:`importlib.resources.as_file` context manager to remove the -temporary file if destroyed late during Python finalization: keep a local -reference to the :func:`os.remove` function. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst b/Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst deleted file mode 100644 index e40005886afc3..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst +++ /dev/null @@ -1,2 +0,0 @@ -Suppress writing an XML declaration in open files in ``ElementTree.write()`` -with ``encoding='unicode'`` and ``xml_declaration=None``. diff --git a/Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst b/Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst deleted file mode 100644 index 9e1d6554e0ab2..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-05-22-22-42.gh-issue-93421.43UO_8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Update :data:`sqlite3.Cursor.rowcount` when a DML statement has run to -completion. This fixes the row count for SQL queries like -``UPDATE ... RETURNING``. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2022-06-06-12-58-27.gh-issue-79579.e8rB-M.rst b/Misc/NEWS.d/next/Library/2022-06-06-12-58-27.gh-issue-79579.e8rB-M.rst deleted file mode 100644 index 82b1a1c28a600..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-06-12-58-27.gh-issue-79579.e8rB-M.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`sqlite3` now correctly detects DML queries with leading comments. -Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2022-06-07-14-53-46.gh-issue-90549.T4FMKY.rst b/Misc/NEWS.d/next/Library/2022-06-07-14-53-46.gh-issue-90549.T4FMKY.rst deleted file mode 100644 index 6ebdc394900e6..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-07-14-53-46.gh-issue-90549.T4FMKY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a multiprocessing bug where a global named resource (such as a semaphore) -could leak when a child process is spawned (as opposed to forked). diff --git a/Misc/NEWS.d/next/Library/2022-06-08-20-11-02.gh-issue-90494.LIZT85.rst b/Misc/NEWS.d/next/Library/2022-06-08-20-11-02.gh-issue-90494.LIZT85.rst deleted file mode 100644 index 95416768793ea..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-08-20-11-02.gh-issue-90494.LIZT85.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`copy.copy` and :func:`copy.deepcopy` now always raise a TypeError if -``__reduce__()`` returns a tuple with length 6 instead of silently ignore -the 6th item or produce incorrect result. diff --git a/Misc/NEWS.d/next/Library/2022-06-11-13-32-17.gh-issue-79512.A1KTDr.rst b/Misc/NEWS.d/next/Library/2022-06-11-13-32-17.gh-issue-79512.A1KTDr.rst deleted file mode 100644 index 5393fb52e93c3..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-11-13-32-17.gh-issue-79512.A1KTDr.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed names and ``__module__`` value of :mod:`weakref` classes -:class:`~weakref.ReferenceType`, :class:`~weakref.ProxyType`, -:class:`~weakref.CallableProxyType`. It makes them pickleable. diff --git a/Misc/NEWS.d/next/Library/2022-06-15-21-28-16.gh-issue-83499.u3DQJ-.rst b/Misc/NEWS.d/next/Library/2022-06-15-21-28-16.gh-issue-83499.u3DQJ-.rst deleted file mode 100644 index 6b32b238dfded..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-15-21-28-16.gh-issue-83499.u3DQJ-.rst +++ /dev/null @@ -1 +0,0 @@ -Fix double closing of file description in :mod:`tempfile`. diff --git a/Misc/NEWS.d/next/Library/2022-06-21-11-40-31.gh-issue-84753.FW1pxO.rst b/Misc/NEWS.d/next/Library/2022-06-21-11-40-31.gh-issue-84753.FW1pxO.rst deleted file mode 100644 index eeae2edf7161a..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-21-11-40-31.gh-issue-84753.FW1pxO.rst +++ /dev/null @@ -1,7 +0,0 @@ -:func:`inspect.iscoroutinefunction`, :func:`inspect.isgeneratorfunction`, -and :func:`inspect.isasyncgenfunction` now properly return ``True`` for -duck-typed function-like objects like instances of -:class:`unittest.mock.AsyncMock`. - -This makes :func:`inspect.iscoroutinefunction` consistent with the -behavior of :func:`asyncio.iscoroutinefunction`. Patch by Mehdi ABAAKOUK. diff --git a/Misc/NEWS.d/next/Library/2022-06-22-11-16-11.gh-issue-94101.V9vDG8.rst b/Misc/NEWS.d/next/Library/2022-06-22-11-16-11.gh-issue-94101.V9vDG8.rst deleted file mode 100644 index bcef0ca07470a..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-22-11-16-11.gh-issue-94101.V9vDG8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Manual instantiation of :class:`ssl.SSLSession` objects is no longer allowed -as it lead to misconfigured instances that crashed the interpreter when -attributes where accessed on them. diff --git a/Misc/NEWS.d/next/Library/2022-06-24-19-23-59.gh-issue-94207.VhS1eS.rst b/Misc/NEWS.d/next/Library/2022-06-24-19-23-59.gh-issue-94207.VhS1eS.rst deleted file mode 100644 index 3d38524ac0e83..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-24-19-23-59.gh-issue-94207.VhS1eS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Made :class:`_struct.Struct` GC-tracked in order to fix a reference leak in -the :mod:`_struct` module. diff --git a/Misc/NEWS.d/next/Library/2022-06-25-13-33-18.gh-issue-94245.-zQY1a.rst b/Misc/NEWS.d/next/Library/2022-06-25-13-33-18.gh-issue-94245.-zQY1a.rst deleted file mode 100644 index de84918d5ecee..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-25-13-33-18.gh-issue-94245.-zQY1a.rst +++ /dev/null @@ -1 +0,0 @@ -Fix pickling and copying of ``typing.Tuple[()]``. diff --git a/Misc/NEWS.d/next/Library/2022-06-25-16-27-02.gh-issue-94254.beP16v.rst b/Misc/NEWS.d/next/Library/2022-06-25-16-27-02.gh-issue-94254.beP16v.rst deleted file mode 100644 index 81482bcd4f897..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-25-16-27-02.gh-issue-94254.beP16v.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed types of :mod:`struct` module to be immutable. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst b/Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst deleted file mode 100644 index 811a8d6031e0b..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst +++ /dev/null @@ -1 +0,0 @@ -Fix memory leak in :class:`pickle.Pickler` when looking up :attr:`dispatch_table`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-06-29-09-48-37.gh-issue-92336.otA6c6.rst b/Misc/NEWS.d/next/Library/2022-06-29-09-48-37.gh-issue-92336.otA6c6.rst deleted file mode 100644 index eb74e0ceb7446..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-29-09-48-37.gh-issue-92336.otA6c6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where :meth:`linecache.getline` fails on bad files with :exc:`UnicodeDecodeError` or :exc:`SyntaxError`. It now returns an empty string as per the documentation. diff --git a/Misc/NEWS.d/next/Library/2022-07-02-19-46-30.gh-issue-94510.xOatDC.rst b/Misc/NEWS.d/next/Library/2022-07-02-19-46-30.gh-issue-94510.xOatDC.rst deleted file mode 100644 index 55856d5756559..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-02-19-46-30.gh-issue-94510.xOatDC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Re-entrant calls to :func:`sys.setprofile` and :func:`sys.settrace` now -raise :exc:`RuntimeError`. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2022-07-07-15-46-55.gh-issue-94637.IYEiUM.rst b/Misc/NEWS.d/next/Library/2022-07-07-15-46-55.gh-issue-94637.IYEiUM.rst deleted file mode 100644 index 20cbbcd5088b7..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-07-15-46-55.gh-issue-94637.IYEiUM.rst +++ /dev/null @@ -1,3 +0,0 @@ -:meth:`SSLContext.set_default_verify_paths` now releases the GIL around -``SSL_CTX_set_default_verify_paths`` call. The function call performs I/O -and CPU intensive work. diff --git a/Misc/NEWS.d/next/Library/2022-07-11-10-41-48.gh-issue-94736.EbsgeK.rst b/Misc/NEWS.d/next/Library/2022-07-11-10-41-48.gh-issue-94736.EbsgeK.rst deleted file mode 100644 index 3080672ecdfbb..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-11-10-41-48.gh-issue-94736.EbsgeK.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash when deallocating an instance of a subclass of ``_multiprocessing.SemLock``. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst b/Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst deleted file mode 100644 index bf7885aef8cbf..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-14-00-43-52.gh-issue-94821.e17ghU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix binding of unix socket to empty address on Linux to use an available -address from the abstract namespace, instead of "\0". diff --git a/Misc/NEWS.d/next/Library/2022-07-22-17-19-57.gh-issue-93157.RXByAk.rst b/Misc/NEWS.d/next/Library/2022-07-22-17-19-57.gh-issue-93157.RXByAk.rst deleted file mode 100644 index 054b318ec63f0..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-22-17-19-57.gh-issue-93157.RXByAk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`fileinput` module didn't support ``errors`` option when -``inplace`` is true. diff --git a/Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst b/Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst deleted file mode 100644 index 34b017078436d..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :meth:`concurrent.futures.Executor.map` to cancel the currently waiting on future on an error - e.g. TimeoutError or KeyboardInterrupt. diff --git a/Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst b/Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst deleted file mode 100644 index e63475f8ba96f..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst +++ /dev/null @@ -1 +0,0 @@ -Fix check for existence of :data:`os.EFD_CLOEXEC`, :data:`os.EFD_NONBLOCK` and :data:`os.EFD_SEMAPHORE` flags on older kernel versions where these flags are not present. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-07-24-09-15-35.gh-issue-95194.ERVmqG.rst b/Misc/NEWS.d/next/Library/2022-07-24-09-15-35.gh-issue-95194.ERVmqG.rst deleted file mode 100644 index c69651923b410..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-24-09-15-35.gh-issue-95194.ERVmqG.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade bundled pip to 22.2. diff --git a/Misc/NEWS.d/next/Library/2022-07-24-12-00-06.gh-issue-95199.-5A64k.rst b/Misc/NEWS.d/next/Library/2022-07-24-12-00-06.gh-issue-95199.-5A64k.rst deleted file mode 100644 index f3d9cf3306b8d..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-24-12-00-06.gh-issue-95199.-5A64k.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade bundled setuptools to 63.2.0. diff --git a/Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst b/Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst deleted file mode 100644 index 48a5c1af74907..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-24-12-59-02.gh-issue-95087.VvqXkN.rst +++ /dev/null @@ -1 +0,0 @@ -Fix IndexError in parsing invalid date in the :mod:`email` module. diff --git a/Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst b/Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst deleted file mode 100644 index d4ab325e03658..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst +++ /dev/null @@ -1 +0,0 @@ -Fix GC crash when deallocating ``_lsprof.Profiler`` by untracking it before calling any callbacks. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst b/Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst deleted file mode 100644 index 6674a4a269539..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled pip to 22.2.1. diff --git a/Misc/NEWS.d/next/Security/2022-05-19-08-53-07.gh-issue-92888.TLtR9W.rst b/Misc/NEWS.d/next/Security/2022-05-19-08-53-07.gh-issue-92888.TLtR9W.rst deleted file mode 100644 index 4841b8a90a087..0000000000000 --- a/Misc/NEWS.d/next/Security/2022-05-19-08-53-07.gh-issue-92888.TLtR9W.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``memoryview`` use after free when accessing the backing buffer in certain cases. - diff --git a/Misc/NEWS.d/next/Security/2022-06-15-20-09-23.gh-issue-87389.QVaC3f.rst b/Misc/NEWS.d/next/Security/2022-06-15-20-09-23.gh-issue-87389.QVaC3f.rst deleted file mode 100644 index 029d437190deb..0000000000000 --- a/Misc/NEWS.d/next/Security/2022-06-15-20-09-23.gh-issue-87389.QVaC3f.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`http.server`: Fix an open redirection vulnerability in the HTTP server -when an URI path starts with ``//``. Vulnerability discovered, and initial -fix proposed, by Hamza Avvan. diff --git a/Misc/NEWS.d/next/Tests/2022-03-14-23-28-17.bpo-47016.K-t2QX.rst b/Misc/NEWS.d/next/Tests/2022-03-14-23-28-17.bpo-47016.K-t2QX.rst deleted file mode 100644 index 774bfafc021ef..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-03-14-23-28-17.bpo-47016.K-t2QX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Create a GitHub Actions workflow for verifying bundled pip and setuptools. -Patch by Illia Volochii and Adam Turner. diff --git a/Misc/NEWS.d/next/Tests/2022-05-25-23-00-35.gh-issue-92886.Y-vrWj.rst b/Misc/NEWS.d/next/Tests/2022-05-25-23-00-35.gh-issue-92886.Y-vrWj.rst deleted file mode 100644 index 93c1ffe33f28a..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-05-25-23-00-35.gh-issue-92886.Y-vrWj.rst +++ /dev/null @@ -1 +0,0 @@ -Fixing tests that fail when running with optimizations (``-O``) in ``test_zipimport.py`` diff --git a/Misc/NEWS.d/next/Tests/2022-06-03-16-26-04.gh-issue-57539.HxWgYO.rst b/Misc/NEWS.d/next/Tests/2022-06-03-16-26-04.gh-issue-57539.HxWgYO.rst deleted file mode 100644 index 0734b599f4ad9..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-06-03-16-26-04.gh-issue-57539.HxWgYO.rst +++ /dev/null @@ -1 +0,0 @@ -Increase calendar test coverage for :meth:`calendar.LocaleTextCalendar.formatweekday`. diff --git a/Misc/NEWS.d/next/Tests/2022-06-17-13-55-11.gh-issue-93957.X4ovYV.rst b/Misc/NEWS.d/next/Tests/2022-06-17-13-55-11.gh-issue-93957.X4ovYV.rst deleted file mode 100644 index 2719933f6b94c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-06-17-13-55-11.gh-issue-93957.X4ovYV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Provide nicer error reporting from subprocesses in -test_venv.EnsurePipTest.test_with_pip. diff --git a/Misc/NEWS.d/next/Tests/2022-06-17-15-20-09.gh-issue-93951.CW1Vv4.rst b/Misc/NEWS.d/next/Tests/2022-06-17-15-20-09.gh-issue-93951.CW1Vv4.rst deleted file mode 100644 index b627466b4b221..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-06-17-15-20-09.gh-issue-93951.CW1Vv4.rst +++ /dev/null @@ -1 +0,0 @@ -In test_bdb.StateTestCase.test_skip, avoid including auxiliary importers. diff --git a/Misc/NEWS.d/next/Tests/2022-06-27-21-27-20.gh-issue-94208.VR6HX-.rst b/Misc/NEWS.d/next/Tests/2022-06-27-21-27-20.gh-issue-94208.VR6HX-.rst deleted file mode 100644 index d0f970ad286b1..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-06-27-21-27-20.gh-issue-94208.VR6HX-.rst +++ /dev/null @@ -1,2 +0,0 @@ -``test_ssl`` is now checking for supported TLS version and protocols in more -tests. diff --git a/Misc/NEWS.d/next/Tests/2022-07-05-17-53-13.gh-issue-91330.Qys5IL.rst b/Misc/NEWS.d/next/Tests/2022-07-05-17-53-13.gh-issue-91330.Qys5IL.rst deleted file mode 100644 index 315521102f4ec..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-07-05-17-53-13.gh-issue-91330.Qys5IL.rst +++ /dev/null @@ -1,7 +0,0 @@ -Added more tests for :mod:`dataclasses` to cover behavior with data -descriptor-based fields. - -# Write your Misc/NEWS entry below. It should be a simple ReST paragraph. # -Don't start with "- Issue #: " or "- gh-issue-: " or that sort of -stuff. -########################################################################### diff --git a/Misc/NEWS.d/next/Tests/2022-07-24-20-19-05.gh-issue-95212.fHiU4e.rst b/Misc/NEWS.d/next/Tests/2022-07-24-20-19-05.gh-issue-95212.fHiU4e.rst deleted file mode 100644 index 44cea181cc1f1..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-07-24-20-19-05.gh-issue-95212.fHiU4e.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make multiprocessing test case ``test_shared_memory_recreate`` -parallel-safe. diff --git a/Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst b/Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst deleted file mode 100644 index 523d9d5f2f8bf..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix problem with ``test_ssl`` ``test_get_ciphers`` on systems that require -perfect forward secrecy (PFS) ciphers. diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-06-29-22-47-11.gh-issue-94430.hdov8L.rst b/Misc/NEWS.d/next/Tools-Demos/2022-06-29-22-47-11.gh-issue-94430.hdov8L.rst deleted file mode 100644 index 88aa8d0866531..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2022-06-29-22-47-11.gh-issue-94430.hdov8L.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow parameters named ``module`` and ``self`` with custom C names in Argument -Clinic. Patch by Erlend E. Aasland diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-07-04-01-37-42.gh-issue-94538.1rgy1Y.rst b/Misc/NEWS.d/next/Tools-Demos/2022-07-04-01-37-42.gh-issue-94538.1rgy1Y.rst deleted file mode 100644 index e39ae3950c0fe..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2022-07-04-01-37-42.gh-issue-94538.1rgy1Y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix Argument Clinic output to custom file destinations. Patch by Erlend E. -Aasland. diff --git a/Misc/NEWS.d/next/Windows/2022-03-20-15-47-35.bpo-42658.16eXtb.rst b/Misc/NEWS.d/next/Windows/2022-03-20-15-47-35.bpo-42658.16eXtb.rst deleted file mode 100644 index 852cc77676a31..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-20-15-47-35.bpo-42658.16eXtb.rst +++ /dev/null @@ -1,3 +0,0 @@ -Support native Windows case-insensitive path comparisons by using -``LCMapStringEx`` instead of :func:`str.lower` in :func:`ntpath.normcase`. -Add ``LCMapStringEx`` to the :mod:`_winapi` module. diff --git a/Misc/NEWS.d/next/Windows/2022-05-16-11-45-06.gh-issue-92841.NQx107.rst b/Misc/NEWS.d/next/Windows/2022-05-16-11-45-06.gh-issue-92841.NQx107.rst deleted file mode 100644 index 5e1897e6ba1bc..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-05-16-11-45-06.gh-issue-92841.NQx107.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`asyncio` no longer throws ``RuntimeError: Event loop is closed`` on -interpreter exit after asynchronous socket activity. Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst b/Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst deleted file mode 100644 index 8d9e850a5b5b7..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-07-16-16-18-32.gh-issue-90844.vwITT3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow virtual environments to correctly launch when they have spaces in the -path. diff --git a/README.rst b/README.rst index 0ccd54cbed72d..c554ff6e9a42a 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.10.5 +This is Python version 3.10.6 ============================= .. image:: https://travis-ci.com/python/cpython.svg?branch=master From webhook-mailer at python.org Tue Aug 2 07:16:42 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 02 Aug 2022 11:16:42 -0000 Subject: [Python-checkins] gh-83270: Update IDLE's credits (GH-95528) (#95560) Message-ID: https://github.com/python/cpython/commit/b0c382555759e96d0e364849d8ab435e3506e502 commit: b0c382555759e96d0e364849d8ab435e3506e502 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: erlend-aasland date: 2022-08-02T13:16:33+02:00 summary: gh-83270: Update IDLE's credits (GH-95528) (#95560) Co-authored-by: Terry Jan Reedy (cherry picked from commit 698fa8bf6075c1594966ef6da8501a6f81db50f2) Co-authored-by: Erlend Egeberg Aasland files: M Lib/idlelib/CREDITS.txt diff --git a/Lib/idlelib/CREDITS.txt b/Lib/idlelib/CREDITS.txt index 3a50eb8e7f2ac..4a42af586a4a9 100644 --- a/Lib/idlelib/CREDITS.txt +++ b/Lib/idlelib/CREDITS.txt @@ -2,9 +2,10 @@ Guido van Rossum, as well as being the creator of the Python language, is the original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development was carried out in the SF IDLEfork project. The +Until Python 2.3, IDLE's development was carried out in the SF IDLEfork project. The objective was to develop a version of IDLE which had an execution environment which could be initialized prior to each run of user code. +IDLefork was merged into the Python code base in 2003. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -28,6 +29,15 @@ Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful patches. Thanks, guys! +Major contributors since 2005: + +- 2005: Tal Einat +- 2010: Terry Jan Reedy (current maintainer) +- 2013: Roger Serwys +- 2014: Saimadhav Heblikar +- 2015: Mark Roseman +- 2017: Louie Lu, Cheryl Sabella, and Serhiy Storchaka + For additional details refer to NEWS.txt and Changelog. Please contact the IDLE maintainer (kbk at shore.net) to have yourself included From webhook-mailer at python.org Tue Aug 2 07:17:54 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 02 Aug 2022 11:17:54 -0000 Subject: [Python-checkins] gh-95191: IDLE: Include prompts when saving Shell GH-95554 (#95558) Message-ID: https://github.com/python/cpython/commit/654d62adc64d0c793b1ff93ddfdc6a6986ec4a1b commit: 654d62adc64d0c793b1ff93ddfdc6a6986ec4a1b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: erlend-aasland date: 2022-08-02T13:17:50+02:00 summary: gh-95191: IDLE: Include prompts when saving Shell GH-95554 (#95558) (cherry picked from commit b85411fc5e9e223a6bd44f89f674ee3b2e29b99e) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_iomenu.py M Lib/idlelib/iomenu.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index add0d8c6bead2..999b67181319c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,8 @@ Released 2023-04-03? ========================= +gh-95191: Include prompts when saving Shell (interactive input/output). + gh-95511: Fix the Shell context menu copy-with-prompts bug of copying an extra line when one selects whole lines. diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index e338893c09e6a..2fb836dba2167 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,10 +1,12 @@ "Test , coverage 17%." -from idlelib import iomenu, util +from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk from idlelib.editor import EditorWindow +from idlelib import util +from idlelib.idle_test.mock_idle import Func class IOBindingTest(unittest.TestCase): @@ -36,9 +38,14 @@ def test_fixnewlines_end(self): io = self.io fix = io.fixnewlines text = io.editwin.text + + # Make the editor temporarily look like Shell. self.editwin.interp = None - eq(fix(), '') - del self.editwin.interp + shelltext = '>>> if 1' + self.editwin.get_prompt_text = Func(result=shelltext) + eq(fix(), shelltext) # Get... call and '\n' not added. + del self.editwin.interp, self.editwin.get_prompt_text + text.insert(1.0, 'a') eq(fix(), 'a'+io.eol_convention) eq(text.get('1.0', 'end-1c'), 'a\n') diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 327e885203c3c..af8159c2b33f5 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -251,11 +251,17 @@ def writefile(self, filename): return False def fixnewlines(self): - "Return text with final \n if needed and os eols." - if (self.text.get("end-2c") != '\n' - and not hasattr(self.editwin, "interp")): # Not shell. - self.text.insert("end-1c", "\n") - text = self.text.get("1.0", "end-1c") + """Return text with os eols. + + Add prompts if shell else final \n if missing. + """ + + if hasattr(self.editwin, "interp"): # Saving shell. + text = self.editwin.get_prompt_text('1.0', self.text.index('end-1c')) + else: + if self.text.get("end-2c") != '\n': + self.text.insert("end-1c", "\n") # Changes 'end-1c' value. + text = self.text.get('1.0', "end-1c") if self.eol_convention != "\n": text = text.replace("\n", self.eol_convention) return text diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index ba33f581ea30f..e7fef5f69daa3 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -995,6 +995,23 @@ def replace_event(self, event): def get_standard_extension_names(self): return idleConf.GetExtensions(shell_only=True) + def get_prompt_text(self, first, last): + """Return text between first and last with prompts added.""" + text = self.text.get(first, last) + lineno_range = range( + int(float(first)), + int(float(last)) + ) + prompts = [ + self.shell_sidebar.line_prompts.get(lineno) + for lineno in lineno_range + ] + return "\n".join( + line if prompt is None else f"{prompt} {line}" + for prompt, line in zip(prompts, text.splitlines()) + ) + "\n" + + def copy_with_prompts_callback(self, event=None): """Copy selected lines to the clipboard, with prompts. @@ -1011,23 +1028,9 @@ def copy_with_prompts_callback(self, event=None): sellast = text.index('sel.last') if sellast[-1] != '0': sellast = text.index("sel.last+1line linestart") - - selected_text = self.text.get(selfirst, sellast) - selection_lineno_range = range( - int(float(selfirst)), - int(float(sellast)) - ) - prompts = [ - self.shell_sidebar.line_prompts.get(lineno) - for lineno in selection_lineno_range - ] - selected_text_with_prompts = "\n".join( - line if prompt is None else f"{prompt} {line}" - for prompt, line in zip(prompts, selected_text.splitlines()) - ) + "\n" - text.clipboard_clear() - text.clipboard_append(selected_text_with_prompts) + prompt_text = self.get_prompt_text(selfirst, sellast) + text.clipboard_append(prompt_text) reading = False executing = False diff --git a/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst new file mode 100644 index 0000000000000..94d3dbbd529f0 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst @@ -0,0 +1 @@ +Include prompts when saving Shell (interactive input and output). From webhook-mailer at python.org Tue Aug 2 09:06:23 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 02 Aug 2022 13:06:23 -0000 Subject: [Python-checkins] gh-92219: Clarify that some options to the installer may break the install (GH-95548) (#95550) Message-ID: https://github.com/python/cpython/commit/8e1952aaaf381d8ce35bc95e770a9f17e3f305fb commit: 8e1952aaaf381d8ce35bc95e770a9f17e3f305fb branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: erlend-aasland date: 2022-08-02T15:06:15+02:00 summary: gh-92219: Clarify that some options to the installer may break the install (GH-95548) (#95550) (cherry picked from commit d2c1a9c76c001b18c14e50779b0ee41ea4ccf0b3) Co-authored-by: Steve Dower files: M Doc/using/windows.rst diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 992767ab1c1e0..e0da5d2d85b44 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -177,18 +177,22 @@ of available options is shown below. | Include_debug | Install debug binaries | 0 | +---------------------------+--------------------------------------+--------------------------+ | Include_dev | Install developer headers and | 1 | -| | libraries | | +| | libraries. Omitting this may lead to | | +| | an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_exe | Install :file:`python.exe` and | 1 | -| | related files | | +| | related files. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_launcher | Install :ref:`launcher`. | 1 | +---------------------------+--------------------------------------+--------------------------+ -| InstallLauncherAllUsers | Installs :ref:`launcher` for all | 1 | -| | users. | | +| InstallLauncherAllUsers | Installs the launcher for all | 1 | +| | users. Also requires | | +| | ``Include_launcher`` to be set to 1 | | +---------------------------+--------------------------------------+--------------------------+ | Include_lib | Install standard library and | 1 | -| | extension modules | | +| | extension modules. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_pip | Install bundled pip and setuptools | 1 | +---------------------------+--------------------------------------+--------------------------+ From webhook-mailer at python.org Tue Aug 2 09:06:23 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 02 Aug 2022 13:06:23 -0000 Subject: [Python-checkins] gh-95516: Add param types and clarify param descriptions of LogRecord (GH-95517) (#95565) Message-ID: https://github.com/python/cpython/commit/a1579ade9cf3b63ec6e5409599fb2dbe57e49b6c commit: a1579ade9cf3b63ec6e5409599fb2dbe57e49b6c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: erlend-aasland date: 2022-08-02T15:05:46+02:00 summary: gh-95516: Add param types and clarify param descriptions of LogRecord (GH-95517) (#95565) (cherry picked from commit 75a6441718dcbc65d993c9544e67e25bef120e82) Co-authored-by: CAM Gerlach files: M Doc/library/logging.rst diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 6885c4f86c7ef..824076f827af4 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -707,6 +707,7 @@ the :class:`LogRecord` being processed. Obviously changing the LogRecord needs to be done with some care, but it does allow the injection of contextual information into logs (see :ref:`filters-contextual`). + .. _log-record: LogRecord Objects @@ -722,32 +723,54 @@ wire). Contains all the information pertinent to the event being logged. - The primary information is passed in :attr:`msg` and :attr:`args`, which - are combined using ``msg % args`` to create the :attr:`message` field of the - record. - - :param name: The name of the logger used to log the event represented by - this LogRecord. Note that this name will always have this - value, even though it may be emitted by a handler attached to - a different (ancestor) logger. - :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) - Note that this is converted to *two* attributes of the LogRecord: - ``levelno`` for the numeric value and ``levelname`` for the - corresponding level name. - :param pathname: The full pathname of the source file where the logging call - was made. - :param lineno: The line number in the source file where the logging call was - made. - :param msg: The event description message, possibly a format string with - placeholders for variable data. - :param args: Variable data to merge into the *msg* argument to obtain the - event description. + The primary information is passed in *msg* and *args*, + which are combined using ``msg % args`` to create + the :attr:`!message` attribute of the record. + + :param name: The name of the logger used to log the event + represented by this :class:`!LogRecord`. + Note that the logger name in the :class:`!LogRecord` + will always have this value, + even though it may be emitted by a handler + attached to a different (ancestor) logger. + :type name: str + + :param level: The :ref:`numeric level ` of the logging event + (such as ``10`` for ``DEBUG``, ``20`` for ``INFO``, etc). + Note that this is converted to *two* attributes of the LogRecord: + :attr:`!levelno` for the numeric value + and :attr:`!levelname` for the corresponding level name. + :type level: int + + :param pathname: The full string path of the source file + where the logging call was made. + :type pathname: str + + :param lineno: The line number in the source file + where the logging call was made. + :type lineno: int + + :param msg: The event description message, + which can be a %-format string with placeholders for variable data. + :type msg: str + + :param args: Variable data to merge into the *msg* argument + to obtain the event description. + :type args: tuple | dict[str, typing.Any] + :param exc_info: An exception tuple with the current exception information, - or ``None`` if no exception information is available. - :param func: The name of the function or method from which the logging call - was invoked. - :param sinfo: A text string representing stack information from the base of - the stack in the current thread, up to the logging call. + as returned by :func:`sys.exc_info`, + or ``None`` if no exception information is available. + :type exc_info: tuple[type[BaseException], BaseException, types.TracebackType] | None + + :param func: The name of the function or method + from which the logging call was invoked. + :type func: str | None + + :param sinfo: A text string representing stack information + from the base of the stack in the current thread, + up to the logging call. + :type sinfo: str | None .. method:: getMessage() From webhook-mailer at python.org Tue Aug 2 11:02:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 02 Aug 2022 15:02:21 -0000 Subject: [Python-checkins] gh-95233: Correct grp.getgrgid parameter name in documentation (gid -> id) (gh-95232) Message-ID: https://github.com/python/cpython/commit/698b52c8791122e1e2a0aaa8708544c1a7cda68f commit: 698b52c8791122e1e2a0aaa8708544c1a7cda68f branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-02T08:02:14-07:00 summary: gh-95233: Correct grp.getgrgid parameter name in documentation (gid -> id) (gh-95232) (cherry picked from commit df7c8b95372169fb9d23140d35f91970ba32189d) Co-authored-by: Adam Dangoor files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index fbfb922d3e052..baa31752a2c75 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -38,7 +38,7 @@ accessible via :func:`getgrnam` or :func:`getgrgid`.) It defines the following items: -.. function:: getgrgid(gid) +.. function:: getgrgid(id) Return the group database entry for the given numeric group ID. :exc:`KeyError` is raised if the entry asked for cannot be found. From webhook-mailer at python.org Tue Aug 2 11:02:37 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 02 Aug 2022 15:02:37 -0000 Subject: [Python-checkins] gh-95233: Correct grp.getgrgid parameter name in documentation (gid -> id) (gh-95232) Message-ID: https://github.com/python/cpython/commit/8a7bf2d28cdb3579cd33a9c9deb9b5d30eacb086 commit: 8a7bf2d28cdb3579cd33a9c9deb9b5d30eacb086 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-02T08:02:33-07:00 summary: gh-95233: Correct grp.getgrgid parameter name in documentation (gid -> id) (gh-95232) (cherry picked from commit df7c8b95372169fb9d23140d35f91970ba32189d) Co-authored-by: Adam Dangoor files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index fbfb922d3e052..baa31752a2c75 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -38,7 +38,7 @@ accessible via :func:`getgrnam` or :func:`getgrgid`.) It defines the following items: -.. function:: getgrgid(gid) +.. function:: getgrgid(id) Return the group database entry for the given numeric group ID. :exc:`KeyError` is raised if the entry asked for cannot be found. From webhook-mailer at python.org Tue Aug 2 15:00:48 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 02 Aug 2022 19:00:48 -0000 Subject: [Python-checkins] gh-95451: Update docs for wasm32-emscripten and -wasi platforms (GH-95452) Message-ID: https://github.com/python/cpython/commit/e3b6ff19aaa318a813130ba9ad2ab0a332f27feb commit: e3b6ff19aaa318a813130ba9ad2ab0a332f27feb branch: main author: Christian Heimes committer: tiran date: 2022-08-02T21:00:41+02:00 summary: gh-95451: Update docs for wasm32-emscripten and -wasi platforms (GH-95452) Co-authored-by: ?ric Co-authored-by: Michael Droettboom Co-authored-by: Ezio Melotti Co-authored-by: CAM Gerlach files: A Doc/includes/wasm-notavail.rst A Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst M Doc/library/asynchat.rst M Doc/library/asyncio.rst M Doc/library/asyncore.rst M Doc/library/cgi.rst M Doc/library/compileall.rst M Doc/library/concurrent.futures.rst M Doc/library/crypt.rst M Doc/library/ensurepip.rst M Doc/library/fcntl.rst M Doc/library/ftplib.rst M Doc/library/getpass.rst M Doc/library/grp.rst M Doc/library/http.client.rst M Doc/library/http.server.rst M Doc/library/imaplib.rst M Doc/library/intro.rst M Doc/library/mmap.rst M Doc/library/multiprocessing.rst M Doc/library/nis.rst M Doc/library/nntplib.rst M Doc/library/os.rst M Doc/library/poplib.rst M Doc/library/pwd.rst M Doc/library/resource.rst M Doc/library/select.rst M Doc/library/selectors.rst M Doc/library/signal.rst M Doc/library/smtpd.rst M Doc/library/smtplib.rst M Doc/library/socket.rst M Doc/library/socketserver.rst M Doc/library/spwd.rst M Doc/library/ssl.rst M Doc/library/subprocess.rst M Doc/library/syslog.rst M Doc/library/telnetlib.rst M Doc/library/threading.rst M Doc/library/urllib.request.rst M Doc/library/venv.rst M Doc/library/webbrowser.rst M Doc/library/xmlrpc.client.rst M Doc/library/xmlrpc.server.rst M Doc/library/zoneinfo.rst M Doc/tools/extensions/pyspecific.py diff --git a/Doc/includes/wasm-notavail.rst b/Doc/includes/wasm-notavail.rst new file mode 100644 index 00000000000..e680e1f9b43 --- /dev/null +++ b/Doc/includes/wasm-notavail.rst @@ -0,0 +1,7 @@ +.. include for modules that don't work on WASM + +.. availability:: not Emscripten, not WASI. + + This module does not work or is not available on WebAssembly platforms + ``wasm32-emscripten`` and ``wasm32-wasi``. See + :ref:`wasm-availability` for more information. diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 777b7075b30..32e04ad6d19 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -34,6 +34,7 @@ Typically an :class:`asyncore.dispatcher` server channel generates new :class:`asynchat.async_chat` channel objects as it receives incoming connection requests. +.. include:: ../includes/wasm-notavail.rst .. class:: async_chat() diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 66c7c4c24a9..b71006e32b2 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -56,6 +56,7 @@ Additionally, there are **low-level** APIs for * :ref:`bridge ` callback-based libraries and code with async/await syntax. +.. include:: ../includes/wasm-notavail.rst .. We use the "rubric" directive here to avoid creating the "Reference" subsection in the TOC. diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index 0084d754419..a3a4e90d052 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -28,6 +28,8 @@ This module provides the basic infrastructure for writing asynchronous socket service clients and servers. +.. include:: ../includes/wasm-notavail.rst + There are only two ways to have a program on a single processor do "more than one thing at a time." Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index 983e412afaf..295a601a7bf 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -37,6 +37,7 @@ size of a POST request. POST requests larger than this size will result in a :exc:`ValueError` being raised during parsing. The default value of this variable is ``0``, meaning the request size is unlimited. +.. include:: ../includes/wasm-notavail.rst Introduction ------------ diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index de34664acb8..7af46cf3200 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -14,6 +14,7 @@ This module can be used to create the cached byte-code files at library installation time, which makes them available for use even by users who don't have write permission to the library directories. +.. include:: ../includes/wasm-notavail.rst Command-line use ---------------- diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index db5971e4d60..95c9e509914 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -19,6 +19,7 @@ The asynchronous execution can be performed with threads, using :class:`ProcessPoolExecutor`. Both implement the same interface, which is defined by the abstract :class:`Executor` class. +.. include:: ../includes/wasm-notavail.rst Executor Objects ---------------- diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index f585bbcbc18..740084b40c5 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -38,6 +38,8 @@ this module. .. availability:: Unix, not VxWorks. +.. include:: ../includes/wasm-notavail.rst + Hashing Methods --------------- diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index fa1b42cf484..34f45e20bae 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -36,6 +36,7 @@ when creating a virtual environment) or after explicitly uninstalling :pep:`453`: Explicit bootstrapping of pip in Python installations The original rationale and specification for this module. +.. include:: ../includes/wasm-notavail.rst Command line interface ---------------------- diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 784e7071c2b..997c7ea571f 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -18,6 +18,8 @@ interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines. For a complete description of these calls, see :manpage:`fcntl(2)` and :manpage:`ioctl(2)` Unix manual pages. +.. include:: ../includes/wasm-notavail.rst + All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by ``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 2f94ac49928..e5ba9eef407 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -21,6 +21,8 @@ as mirroring other FTP servers. It is also used by the module The default encoding is UTF-8, following :rfc:`2640`. +.. include:: ../includes/wasm-notavail.rst + Here's a sample session using the :mod:`ftplib` module:: >>> from ftplib import FTP diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index 82b11919a3d..d5bbe67fb30 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -12,8 +12,9 @@ -------------- -The :mod:`getpass` module provides two functions: +.. include:: ../includes/wasm-notavail.rst +The :mod:`getpass` module provides two functions: .. function:: getpass(prompt='Password: ', stream=None) diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index baa31752a2c..fabc22e4cf5 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -10,6 +10,8 @@ This module provides access to the Unix group database. It is available on all Unix versions. +.. include:: ../includes/wasm-notavail.rst + Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see ````): diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index e605f7b8b14..8bb3187ef51 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -28,6 +28,8 @@ HTTPS protocols. It is normally not used directly --- the module HTTPS support is only available if Python was compiled with SSL support (through the :mod:`ssl` module). +.. include:: ../includes/wasm-notavail.rst + The module provides the following classes: diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 3bb7294ebb4..48f952daae1 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -22,6 +22,8 @@ This module defines classes for implementing HTTP servers. :mod:`http.server` is not recommended for production. It only implements :ref:`basic security checks `. +.. include:: ../includes/wasm-notavail.rst + One class, :class:`HTTPServer`, is a :class:`socketserver.TCPServer` subclass. It creates and listens at the HTTP socket, dispatching the requests to a handler. Code to create and run the server looks like this:: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 65681ec0935..0c10e7afee4 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -26,6 +26,8 @@ implement a large subset of the IMAP4rev1 client protocol as defined in :rfc:`2060`. It is backward compatible with IMAP4 (:rfc:`1730`) servers, but note that the ``STATUS`` command is not supported in IMAP4. +.. include:: ../includes/wasm-notavail.rst + Three classes are provided by the :mod:`imaplib` module, :class:`IMAP4` is the base class: diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 120b174dc3b..1020924038e 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -64,3 +64,58 @@ Notes on availability libc version, then both conditions must hold. For example a feature with note *Availability: Linux >= 3.17 with glibc >= 2.27* requires both Linux 3.17 or newer and glibc 2.27 or newer. + +.. _wasm-availability: + +WebAssembly platforms +--------------------- + +The `WebAssembly`_ platforms ``wasm32-emscripten`` (`Emscripten`_) and +``wasm32-wasi`` (`WASI`_) provide a subset of POSIX APIs. WebAssembly runtimes +and browsers are sandboxed and have limited access to the host and external +resources. Any Python standard library module that uses processes, threading, +networking, signals, or other forms of inter-process communication (IPC), is +either not available or may not work as on other Unix-like systems. File I/O, +file system, and Unix permission-related functions are restricted, too. +Emscripten does not permit blocking I/O. Other blocking operations like +:func:`~time.sleep` block the browser event loop. + +The properties and behavior of Python on WebAssembly platforms depend on the +`Emscripten`_-SDK or `WASI`_-SDK version, WASM runtimes (browser, NodeJS, +`wasmtime`_), and Python build time flags. WebAssembly, Emscripten, and WASI +are evolving standards; some features like networking may be +supported in the future. + +For Python in the browser, users should consider `Pyodide`_ or `PyScript`_. +PyScript is built on top of Pyodide, which itself is built on top of +CPython and Emscripten. Pyodide provides access to browsers' JavaScript and +DOM APIs as well as limited networking capabilities with JavaScript's +``XMLHttpRequest`` and ``Fetch`` APIs. + +* Process-related APIs are not available or always fail with an error. That + includes APIs that spawn new processes (:func:`~os.fork`, + :func:`~os.execve`), wait for processes (:func:`~os.waitpid`), send signals + (:func:`~os.kill`), or otherwise interact with processes. The + :mod:`subprocess` is importable but does not work. + +* The :mod:`socket` module is available, but is limited and behaves + differently from other platforms. On Emscripten, sockets are always + non-blocking and require additional JavaScript code and helpers on the + server to proxy TCP through WebSockets; see `Emscripten Networking`_ + for more information. WASI snapshot preview 1 only permits sockets from an + existing file descriptor. + +* Some functions are stubs that either don't do anything and always return + hardcoded values. + +* Functions related to file descriptors, file permissions, file ownership, and + links are limited and don't support some operations. For example, WASI does + not permit symlinks with absolute file names. + +.. _WebAssembly: https://webassembly.org/ +.. _Emscripten: https://emscripten.org/ +.. _Emscripten Networking: https://emscripten.org/docs/porting/networking.html> +.. _WASI: https://wasi.dev/ +.. _wasmtime: https://wasmtime.dev/ +.. _Pyodide: https://pyodide.org/ +.. _PyScript: https://pyscript.net/ diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index 36c15e9d1d9..c4f8781f2ac 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -6,6 +6,8 @@ -------------- +.. include:: ../includes/wasm-notavail.rst + Memory-mapped file objects behave like both :class:`bytearray` and like :term:`file objects `. You can use mmap objects in most places where :class:`bytearray` are expected; for example, you can use the :mod:`re` diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 3eb98791726..eaa946462a1 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -8,6 +8,8 @@ -------------- +.. include:: ../includes/wasm-notavail.rst + Introduction ------------ diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index fd3c3d9293d..3fa7916c37b 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -21,6 +21,8 @@ central administration of several hosts. Because NIS exists only on Unix systems, this module is only available for Unix. +.. include:: ../includes/wasm-notavail.rst + The :mod:`nis` module defines the following functions: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index 5aad44d929e..143e4e0c427 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -38,6 +38,8 @@ the Network News Transfer Protocol. It can be used to implement a news reader or poster, or automated news processors. It is compatible with :rfc:`3977` as well as the older :rfc:`977` and :rfc:`2980`. +.. include:: ../includes/wasm-notavail.rst + Here are two small examples of how it can be used. To list some statistics about a newsgroup and print the subjects of the last 10 articles:: diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 9567dab81ff..e5555c2355f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -34,6 +34,14 @@ Notes on the availability of these functions: * On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported. +* On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, large + parts of the :mod:`os` module are not available or behave differently. API + related to processes (e.g. :func:`~os.fork`, :func:`~os.execve`), signals + (e.g. :func:`~os.kill`, :func:`~os.wait`), and resources + (e.g. :func:`~os.nice`) are not available. Others like :func:`~os.getuid` + and :func:`~os.getpid` are emulated or stubs. + + .. note:: All functions in this module raise :exc:`OSError` (or subclasses thereof) in @@ -165,7 +173,7 @@ process and user. Return the filename corresponding to the controlling terminal of the process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: environ @@ -337,7 +345,7 @@ process and user. Return the effective group id of the current process. This corresponds to the "set id" bit on the file being executed in the current process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: geteuid() @@ -346,7 +354,7 @@ process and user. Return the current process's effective user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getgid() @@ -357,6 +365,9 @@ process and user. .. availability:: Unix. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: getgrouplist(user, group) @@ -365,7 +376,7 @@ process and user. field from the password record for *user*, because that group ID will otherwise be potentially omitted. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -374,7 +385,7 @@ process and user. Return list of supplemental group ids associated with the current process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: @@ -402,7 +413,7 @@ process and user. falls back to ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the current real user id. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. function:: getpgid(pid) @@ -410,7 +421,7 @@ process and user. Return the process group id of the process with process id *pid*. If *pid* is 0, the process group id of the current process is returned. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getpgrp() @@ -418,7 +429,7 @@ process and user. Return the id of the current process group. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getpid() @@ -427,6 +438,8 @@ process and user. Return the current process id. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. .. function:: getppid() @@ -436,7 +449,7 @@ process and user. the id returned is the one of the init process (1), on Windows it is still the same id, which may be already reused by another process. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionchanged:: 3.2 Added support for Windows. @@ -454,7 +467,7 @@ process and user. (respectively) the calling process, the process group of the calling process, or the real user ID of the calling process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -465,7 +478,7 @@ process and user. Parameters for the :func:`getpriority` and :func:`setpriority` functions. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -475,7 +488,7 @@ process and user. Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -485,7 +498,7 @@ process and user. Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -498,6 +511,9 @@ process and user. .. availability:: Unix. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: initgroups(username, gid) @@ -505,7 +521,7 @@ process and user. the groups of which the specified username is a member, plus the specified group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -539,21 +555,21 @@ process and user. Set the current process's effective group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: seteuid(euid) Set the current process's effective user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setgid(gid) Set the current process' group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setgroups(groups) @@ -562,7 +578,7 @@ process and user. *groups*. *groups* must be a sequence, and each element must be an integer identifying a group. This operation is typically available only to the superuser. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: On macOS, the length of *groups* may not exceed the system-defined maximum number of effective group ids, typically 16. @@ -574,7 +590,7 @@ process and user. Call the system call :c:func:`setpgrp` or ``setpgrp(0, 0)`` depending on which version is implemented (if any). See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setpgid(pid, pgrp) @@ -583,7 +599,7 @@ process and user. process with id *pid* to the process group with id *pgrp*. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setpriority(which, who, priority) @@ -600,7 +616,7 @@ process and user. *priority* is a value in the range -20 to 19. The default priority is 0; lower priorities cause more favorable scheduling. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -609,14 +625,14 @@ process and user. Set the current process's real and effective group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setresgid(rgid, egid, sgid) Set the current process's real, effective, and saved group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -625,7 +641,7 @@ process and user. Set the current process's real, effective, and saved user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -634,21 +650,21 @@ process and user. Set the current process's real and effective user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getsid(pid) Call the system call :c:func:`getsid`. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setsid() Call the system call :c:func:`setsid`. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setuid(uid) @@ -657,7 +673,7 @@ process and user. Set the current process's user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. placed in this section since it relates to errno.... a little weak @@ -680,6 +696,9 @@ process and user. Set the current numeric umask and return the previous umask. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: uname() @@ -850,6 +869,8 @@ as internal buffering of data. 2: stderr), the new file descriptor is :ref:`inheritable `. + .. availability:: not WASI. + .. versionchanged:: 3.4 The new file descriptor is now non-inheritable. @@ -861,6 +882,8 @@ as internal buffering of data. ` by default or non-inheritable if *inheritable* is ``False``. + .. availability:: not WASI. + .. versionchanged:: 3.4 Add the optional *inheritable* parameter. @@ -878,6 +901,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: fchown(fd, uid, gid) @@ -890,6 +916,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: fdatasync(fd) @@ -978,6 +1007,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.5 @@ -1020,7 +1052,7 @@ as internal buffering of data. Make the calling process a session leader; make the tty the controlling tty, the stdin, the stdout, and the stderr of the calling process; close fd. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.11 @@ -1164,7 +1196,7 @@ or `the MSDN `_ on Windo descriptors are :ref:`non-inheritable `. For a (slightly) more portable approach, use the :mod:`pty` module. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.4 The new file descriptors are now non-inheritable. @@ -1190,7 +1222,7 @@ or `the MSDN `_ on Windo Return a pair of file descriptors ``(r, w)`` usable for reading and writing, respectively. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1200,7 +1232,7 @@ or `the MSDN `_ on Windo Ensures that enough disk space is allocated for the file specified by *fd* starting from *offset* and continuing for *len* bytes. - .. availability:: Unix. + .. availability:: Unix, not Emscripten. .. versionadded:: 3.3 @@ -1427,7 +1459,7 @@ or `the MSDN `_ on Windo Cross-platform applications should not use *headers*, *trailers* and *flags* arguments. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: @@ -1449,6 +1481,9 @@ or `the MSDN `_ on Windo .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.5 @@ -1459,7 +1494,7 @@ or `the MSDN `_ on Windo Parameters to the :func:`sendfile` function, if the implementation supports them. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1468,7 +1503,7 @@ or `the MSDN `_ on Windo Parameter to the :func:`sendfile` function, if the implementation supports it. The data won't be cached in the virtual memory and will be freed afterwards. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.11 @@ -1529,7 +1564,7 @@ or `the MSDN `_ on Windo Return the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`). - .. availability:: Unix. + .. availability:: Unix, not WASI. .. function:: tcsetpgrp(fd, pg) @@ -1537,7 +1572,7 @@ or `the MSDN `_ on Windo Set the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`) to *pg*. - .. availability:: Unix. + .. availability:: Unix, not WASI. .. function:: ttyname(fd) @@ -1645,6 +1680,9 @@ Using the :mod:`subprocess` module, all file descriptors except standard streams are closed, and inheritable handles are only inherited if the *close_fds* parameter is ``False``. +On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, the file +descriptor cannot be modified. + .. function:: get_inheritable(fd) Get the "inheritable" flag of the specified file descriptor (a boolean). @@ -1829,7 +1867,7 @@ features: .. audit-event:: os.chflags path,flags os.chflags - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *follow_symlinks* argument. @@ -1874,6 +1912,9 @@ features: read-only flag with it (via the ``stat.S_IWRITE`` and ``stat.S_IREAD`` constants or a corresponding integer value). All other bits are ignored. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. audit-event:: os.chmod path,mode,dir_fd os.chmod .. versionadded:: 3.3 @@ -1900,6 +1941,9 @@ features: .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. @@ -1912,7 +1956,7 @@ features: Change the root directory of the current process to *path*. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -1952,7 +1996,7 @@ features: .. audit-event:: os.chflags path,flags os.lchflags - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2169,7 +2213,7 @@ features: FIFO for reading, and the client opens it for writing. Note that :func:`mkfifo` doesn't open the FIFO --- it just creates the rendezvous point. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *dir_fd* argument. @@ -2191,7 +2235,7 @@ features: This function can also support :ref:`paths relative to directory descriptors `. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *dir_fd* argument. @@ -3059,6 +3103,9 @@ features: .. availability:: Unix, Windows. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionchanged:: 3.2 Added support for Windows 6.0 (Vista) symbolic links. @@ -3670,7 +3717,7 @@ to be ignored. .. audit-event:: os.exec path,args,env os.execl - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor @@ -3713,49 +3760,49 @@ written in Python, such as a mail server's external command delivery program. Exit code that means the command was used incorrectly, such as when the wrong number of arguments are given. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_DATAERR Exit code that means the input data was incorrect. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOINPUT Exit code that means an input file did not exist or was not readable. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOUSER Exit code that means a specified user did not exist. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOHOST Exit code that means a specified host did not exist. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_UNAVAILABLE Exit code that means that a required service is unavailable. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_SOFTWARE Exit code that means an internal software error was detected. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_OSERR @@ -3763,7 +3810,7 @@ written in Python, such as a mail server's external command delivery program. Exit code that means an operating system error was detected, such as the inability to fork or create a pipe. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_OSFILE @@ -3771,21 +3818,21 @@ written in Python, such as a mail server's external command delivery program. Exit code that means some system file did not exist, could not be opened, or had some other kind of error. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_CANTCREAT Exit code that means a user specified output file could not be created. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_IOERR Exit code that means that an error occurred while doing I/O on some file. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_TEMPFAIL @@ -3794,7 +3841,7 @@ written in Python, such as a mail server's external command delivery program. that may not really be an error, such as a network connection that couldn't be made during a retryable operation. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_PROTOCOL @@ -3802,7 +3849,7 @@ written in Python, such as a mail server's external command delivery program. Exit code that means that a protocol exchange was illegal, invalid, or not understood. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOPERM @@ -3810,21 +3857,21 @@ written in Python, such as a mail server's external command delivery program. Exit code that means that there were insufficient permissions to perform the operation (but not intended for file system problems). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_CONFIG Exit code that means that some kind of configuration error occurred. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOTFOUND Exit code that means something like "an entry was not found". - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: fork() @@ -3845,7 +3892,7 @@ written in Python, such as a mail server's external command delivery program. See :mod:`ssl` for applications that use the SSL module with fork(). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: forkpty() @@ -3862,7 +3909,7 @@ written in Python, such as a mail server's external command delivery program. Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: kill(pid, sig) @@ -3886,6 +3933,8 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.kill pid,sig os.kill + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionadded:: 3.2 Windows support. @@ -3900,14 +3949,14 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.killpg pgid,sig os.killpg - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: nice(increment) Add *increment* to the process's "niceness". Return the new niceness. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: pidfd_open(pid, flags=0) @@ -3937,7 +3986,7 @@ written in Python, such as a mail server's external command delivery program. Lock program segments into memory. The value of *op* (defined in ````) determines which segments are locked. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: popen(cmd, mode='r', buffering=-1) @@ -3969,6 +4018,8 @@ written in Python, such as a mail server's external command delivery program. documentation for more powerful ways to manage and communicate with subprocesses. + .. availability:: not Emscripten, not WASI. + .. note:: The :ref:`Python UTF-8 Mode ` affects encodings used for *cmd* and pipe contents. @@ -4062,7 +4113,7 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: posix_spawnp(path, argv, env, *, file_actions=None, \ setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ @@ -4078,7 +4129,7 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: POSIX + .. availability:: POSIX, not Emscripten, not WASI. See :func:`posix_spawn` documentation. @@ -4111,7 +4162,7 @@ written in Python, such as a mail server's external command delivery program. There is no way to unregister a function. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.7 @@ -4180,7 +4231,7 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.spawn mode,path,args,env os.spawnl - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and @@ -4304,7 +4355,7 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.system command os.system - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. function:: times() @@ -4345,7 +4396,7 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. seealso:: @@ -4366,7 +4417,7 @@ written in Python, such as a mail server's external command delivery program. :attr:`si_code` or ``None`` if :data:`WNOHANG` is specified and there are no children in a waitable state. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4377,7 +4428,7 @@ written in Python, such as a mail server's external command delivery program. These are the possible values for *idtype* in :func:`waitid`. They affect how *id* is interpreted. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4397,7 +4448,7 @@ written in Python, such as a mail server's external command delivery program. Flags that can be used in *options* in :func:`waitid` that specify what child signal to wait for. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4412,7 +4463,7 @@ written in Python, such as a mail server's external command delivery program. These are the possible values for :attr:`si_code` in the result returned by :func:`waitid`. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4450,6 +4501,8 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. + .. availability:: Unix, not Emscripten, not WASI. + .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an exception, the function now retries the system call instead of raising an @@ -4468,7 +4521,7 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: wait4(pid, options) @@ -4482,7 +4535,7 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: waitstatus_to_exitcode(status) @@ -4512,6 +4565,8 @@ written in Python, such as a mail server's external command delivery program. :func:`WIFEXITED`, :func:`WEXITSTATUS`, :func:`WIFSIGNALED`, :func:`WTERMSIG`, :func:`WIFSTOPPED`, :func:`WSTOPSIG` functions. + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionadded:: 3.9 @@ -4520,7 +4575,7 @@ written in Python, such as a mail server's external command delivery program. The option for :func:`waitpid` to return immediately if no child process status is available immediately. The function returns ``(0, 0)`` in this case. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: WCONTINUED @@ -4528,7 +4583,7 @@ written in Python, such as a mail server's external command delivery program. This option causes child processes to be reported if they have been continued from a job control stop since their status was last reported. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Some Unix systems. @@ -4538,7 +4593,7 @@ written in Python, such as a mail server's external command delivery program. This option causes child processes to be reported if they have been stopped but their current state has not been reported since they were stopped. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. The following functions take a process status code as returned by @@ -4552,7 +4607,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSIGNALED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFCONTINUED(status) @@ -4563,7 +4618,7 @@ used to determine the disposition of a process. See :data:`WCONTINUED` option. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFSTOPPED(status) @@ -4575,14 +4630,14 @@ used to determine the disposition of a process. done using :data:`WUNTRACED` option or when the process is being traced (see :manpage:`ptrace(2)`). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFSIGNALED(status) Return ``True`` if the process was terminated by a signal, otherwise return ``False``. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFEXITED(status) @@ -4591,7 +4646,7 @@ used to determine the disposition of a process. by calling ``exit()`` or ``_exit()``, or by returning from ``main()``; otherwise return ``False``. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WEXITSTATUS(status) @@ -4600,7 +4655,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFEXITED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WSTOPSIG(status) @@ -4609,7 +4664,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSTOPPED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WTERMSIG(status) @@ -4618,7 +4673,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSIGNALED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Interface to the scheduler diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 2f993f990de..e22a2e1455e 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -28,6 +28,8 @@ quality of POP3 servers varies widely, and too many are quite poor. If your mailserver supports IMAP, you would be better off using the :class:`imaplib.IMAP4` class, as IMAP servers tend to be better implemented. +.. include:: ../includes/wasm-notavail.rst + The :mod:`poplib` module provides two classes: diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst index 03ebb02e4e5..98f3c45e29c 100644 --- a/Doc/library/pwd.rst +++ b/Doc/library/pwd.rst @@ -10,6 +10,8 @@ This module provides access to the Unix user account and password database. It is available on all Unix versions. +.. include:: ../includes/wasm-notavail.rst + Password database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``passwd`` structure (Attribute field below, see ````): diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 7c9c5a0819b..e7bf45d7d56 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -13,6 +13,8 @@ This module provides basic mechanisms for measuring and controlling system resources utilized by a program. +.. include:: ../includes/wasm-notavail.rst + Symbolic constants are used to specify particular system resources and to request usage information about either the current process or its children. diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 1c3d10ef209..a8df81f5bd1 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -22,6 +22,7 @@ it was last read. encouraged to use the :mod:`selectors` module instead, unless they want precise control over the OS-level primitives used. +.. include:: ../includes/wasm-notavail.rst The module defines the following: diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index 6d864a836de..0deb15cf4c5 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -38,6 +38,7 @@ users. :mod:`select` Low-level I/O multiplexing module. +.. include:: ../includes/wasm-notavail.rst Classes ------- diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 72b8f03fc16..2269f50cbaf 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -24,6 +24,9 @@ explicitly reset (Python emulates the BSD style interface regardless of the underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. +On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, signals +are emulated and therefore behave differently. Several functions and signals +are not available on these platforms. Execution of Python signal handlers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 5a7e41c6d09..ac0c9aeb236 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -31,6 +31,7 @@ interaction behaviour with SMTP clients. The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` SMTPUTF8 extensions. +.. include:: ../includes/wasm-notavail.rst SMTPServer Objects ------------------ diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index aaab6b11d3b..4e50ad1568e 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -19,6 +19,7 @@ to send mail to any internet machine with an SMTP or ESMTP listener daemon. For details of SMTP and ESMTP operation, consult :rfc:`821` (Simple Mail Transfer Protocol) and :rfc:`1869` (SMTP Service Extensions). +.. include:: ../includes/wasm-notavail.rst .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 8eb254ce898..b2bb8c78867 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -16,6 +16,9 @@ all modern Unix systems, Windows, MacOS, and probably additional platforms. Some behavior may be platform dependent, since calls are made to the operating system socket APIs. + +.. include:: ../includes/wasm-notavail.rst + .. index:: object: socket The Python interface is a straightforward transliteration of the Unix system @@ -918,6 +921,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyname hostname socket.gethostbyname + .. availability:: not WASI. + .. function:: gethostbyname_ex(hostname) @@ -932,6 +937,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyname hostname socket.gethostbyname_ex + .. availability:: not WASI. + .. function:: gethostname() @@ -943,6 +950,8 @@ The :mod:`socket` module also offers various network-related services: Note: :func:`gethostname` doesn't always return the fully qualified domain name; use :func:`getfqdn` for that. + .. availability:: not WASI. + .. function:: gethostbyaddr(ip_address) @@ -956,6 +965,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyaddr ip_address socket.gethostbyaddr + .. availability:: not WASI. + .. function:: getnameinfo(sockaddr, flags) @@ -971,6 +982,9 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getnameinfo sockaddr socket.getnameinfo + .. availability:: not WASI. + + .. function:: getprotobyname(protocolname) Translate an internet protocol name (for example, ``'icmp'``) to a constant @@ -979,6 +993,8 @@ The :mod:`socket` module also offers various network-related services: (:const:`SOCK_RAW`); for the normal socket modes, the correct protocol is chosen automatically if the protocol is omitted or zero. + .. availability:: not WASI. + .. function:: getservbyname(servicename[, protocolname]) @@ -988,6 +1004,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getservbyname servicename,protocolname socket.getservbyname + .. availability:: not WASI. + .. function:: getservbyport(port[, protocolname]) @@ -997,6 +1015,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getservbyport port,protocolname socket.getservbyport + .. availability:: not WASI. + .. function:: ntohl(x) @@ -1130,7 +1150,7 @@ The :mod:`socket` module also offers various network-related services: buffer. Raises :exc:`OverflowError` if *length* is outside the permissible range of values. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Most Unix platforms. @@ -1153,7 +1173,7 @@ The :mod:`socket` module also offers various network-related services: amount of ancillary data that can be received, since additional data may be able to fit into the padding area. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. most Unix platforms. @@ -1193,7 +1213,7 @@ The :mod:`socket` module also offers various network-related services: (index int, name string) tuples. :exc:`OSError` if the system call fails. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1220,7 +1240,7 @@ The :mod:`socket` module also offers various network-related services: interface name. :exc:`OSError` if no interface with the given name exists. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1237,7 +1257,7 @@ The :mod:`socket` module also offers various network-related services: interface index number. :exc:`OSError` if no interface with the given index exists. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1254,7 +1274,7 @@ The :mod:`socket` module also offers various network-related services: The *fds* parameter is a sequence of file descriptors. Consult :meth:`sendmsg` for the documentation of these parameters. - .. availability:: Unix. + .. availability:: Unix, Windows, not Emscripten, not WASI. Unix platforms supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. @@ -1268,7 +1288,7 @@ The :mod:`socket` module also offers various network-related services: Return ``(msg, list(fds), flags, addr)``. Consult :meth:`recvmsg` for the documentation of these parameters. - .. availability:: Unix. + .. availability:: Unix, Windows, not Emscripten, not WASI. Unix platforms supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. @@ -1319,6 +1339,9 @@ to sockets. .. audit-event:: socket.bind self,address socket.socket.bind + .. availability:: not WASI. + + .. method:: socket.close() Mark the socket closed. The underlying system resource (e.g. a file @@ -1363,6 +1386,8 @@ to sockets. signal, the signal handler doesn't raise an exception and the socket is blocking or has a timeout (see the :pep:`475` for the rationale). + .. availability:: not WASI. + .. method:: socket.connect_ex(address) @@ -1375,6 +1400,8 @@ to sockets. .. audit-event:: socket.connect self,address socket.socket.connect_ex + .. availability:: not WASI. + .. method:: socket.detach() Put the socket object into closed state without actually closing the @@ -1393,6 +1420,8 @@ to sockets. .. versionchanged:: 3.4 The socket is now non-inheritable. + .. availability:: not WASI. + .. method:: socket.fileno() @@ -1438,6 +1467,8 @@ to sockets. contents of the buffer (see the optional built-in module :mod:`struct` for a way to decode C structures encoded as byte strings). + .. availability:: not WASI. + .. method:: socket.getblocking() @@ -1481,9 +1512,12 @@ to sockets. unaccepted connections that the system will allow before refusing new connections. If not specified, a default reasonable value is chosen. + .. availability:: not WASI. + .. versionchanged:: 3.5 The *backlog* parameter is now optional. + .. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, \ errors=None, newline=None) @@ -1758,7 +1792,7 @@ to sockets. def send_fds(sock, msg, fds): return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))]) - .. availability:: Unix. + .. availability:: Unix, not WASI. Most Unix platforms. @@ -1854,13 +1888,14 @@ to sockets. *optlen* argument is required. It's equivalent to call :c:func:`setsockopt` C function with ``optval=NULL`` and ``optlen=optlen``. - .. versionchanged:: 3.5 Writable :term:`bytes-like object` is now accepted. .. versionchanged:: 3.6 setsockopt(level, optname, None, optlen: int) form added. + .. availability:: not WASI. + .. method:: socket.shutdown(how) @@ -1869,6 +1904,8 @@ to sockets. are disallowed. If *how* is :const:`SHUT_RDWR`, further sends and receives are disallowed. + .. availability:: not WASI. + .. method:: socket.share(process_id) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index b65a3e8fb2b..70d56a1dad9 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -10,6 +10,8 @@ The :mod:`socketserver` module simplifies the task of writing network servers. +.. include:: ../includes/wasm-notavail.rst + There are four basic concrete server classes: diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index 87e09167ada..d1693ea67f0 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -15,6 +15,8 @@ This module provides access to the Unix shadow password database. It is available on various Unix versions. +.. include:: ../includes/wasm-notavail.rst + You must have enough privileges to access the shadow password database (this usually means you have to be root). diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index e6e9a08e0a7..f5d5a7c4d28 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -33,6 +33,7 @@ probably additional platforms, as long as OpenSSL is installed on that platform. may lead to a false sense of security, as the default settings of the ssl module are not necessarily appropriate for your application. +.. include:: ../includes/wasm-notavail.rst This section documents the objects and functions in the ``ssl`` module; for more general information about TLS, SSL, and certificates, the reader is referred to diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index fae81f8ac28..43d6ffceee8 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -25,6 +25,7 @@ modules and functions can be found in the following sections. :pep:`324` -- PEP proposing the subprocess module +.. include:: ../includes/wasm-notavail.rst Using the :mod:`subprocess` Module ---------------------------------- diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index ce51856ab7b..766ff57cc66 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -15,6 +15,8 @@ This module wraps the system ``syslog`` family of routines. A pure Python library that can speak to a syslog server is available in the :mod:`logging.handlers` module as :class:`SysLogHandler`. +.. include:: ../includes/wasm-notavail.rst + The module defines the following functions: diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 70b8c7d1511..5a993dc42a5 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -30,6 +30,7 @@ SE (Subnegotiation End), NOP (No Operation), DM (Data Mark), BRK (Break), IP (Interrupt process), AO (Abort output), AYT (Are You There), EC (Erase Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin). +.. include:: ../includes/wasm-notavail.rst .. class:: Telnet(host=None, port=0[, timeout]) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 8e69c2c404f..a8851dd1505 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -33,6 +33,7 @@ level :mod:`_thread` module. See also the :mod:`queue` module. However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously. +.. include:: ../includes/wasm-notavail.rst This module defines the following functions: diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 542db1b5e2a..59e1f2da828 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -21,6 +21,7 @@ authentication, redirections, cookies and more. The `Requests package `_ is recommended for a higher-level HTTP client interface. +.. include:: ../includes/wasm-notavail.rst The :mod:`urllib.request` module defines the following functions: diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 513a982c6ed..06810612acb 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -29,6 +29,7 @@ See :pep:`405` for more information about Python virtual environments. `Python Packaging User Guide: Creating and using virtual environments `__ +.. include:: ../includes/wasm-notavail.rst Creating virtual environments ----------------------------- diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 1dc59306164..734b6321e5a 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -41,6 +41,8 @@ naturally, mutually exclusive. Usage example:: python -m webbrowser -t "https://www.python.org" +.. include:: ../includes/wasm-notavail.rst + The following exception is defined: diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 0d9bfd51f1e..9f5ba46934b 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -32,6 +32,8 @@ between conformable Python objects and XML on the wire. For HTTPS URIs, :mod:`xmlrpc.client` now performs all the necessary certificate and hostname checks by default. +.. include:: ../includes/wasm-notavail.rst + .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \ allow_none=False, use_datetime=False, \ use_builtin_types=False, *, headers=(), context=None) diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 7d561e2303f..9778a859da1 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -23,6 +23,7 @@ servers written in Python. Servers can either be free standing, using constructed data. If you need to parse untrusted or unauthenticated data see :ref:`xml-vulnerabilities`. +.. include:: ../includes/wasm-notavail.rst .. class:: SimpleXMLRPCServer(addr, requestHandler=SimpleXMLRPCRequestHandler,\ logRequests=True, allow_none=False, encoding=None,\ diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index 1b2ba2af2ae..2f1879dc056 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -27,6 +27,7 @@ first-party `tzdata`_ package available on PyPI. First-party package maintained by the CPython core developers to supply time zone data via PyPI. +.. include:: ../includes/wasm-notavail.rst Using ``ZoneInfo`` ------------------ diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 20c372e2495..da15abdf637 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -143,11 +143,11 @@ class Availability(Directive): known_platforms = frozenset({ "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", "Unix", "VxWorks", - "WASI", "Windows", "macOS", - # libc - "BSD libc", "glibc", "musl", - # POSIX platforms with pthreads - "pthreads", + "WASI", "Windows", "macOS", + # libc + "BSD libc", "glibc", "musl", + # POSIX platforms with pthreads + "pthreads", }) def run(self): @@ -159,9 +159,7 @@ def run(self): n, m = self.state.inline_text(self.arguments[0], self.lineno) pnode.extend(n + m) if self.content: - content = " " + " ".join(self.content) - n, m = self.state.inline_text(content, self.content_offset) - pnode.extend(n + m) + self.state.nested_parse(self.content, self.content_offset, pnode) self.parse_platforms() diff --git a/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst b/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst new file mode 100644 index 00000000000..3a7b8a122b7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst @@ -0,0 +1,3 @@ +Update library documentation with +:ref:`availability information ` +on WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``. From webhook-mailer at python.org Tue Aug 2 15:04:16 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 02 Aug 2022 19:04:16 -0000 Subject: [Python-checkins] gh-91207: Override stylesheet fingerprinting when building for HTML Help (GH-95556) Message-ID: https://github.com/python/cpython/commit/7c5f13f391ad9112bb238f2bbccca749f4b7923d commit: 7c5f13f391ad9112bb238f2bbccca749f4b7923d branch: 3.10 author: CAM Gerlach committer: zooba date: 2022-08-02T20:04:12+01:00 summary: gh-91207: Override stylesheet fingerprinting when building for HTML Help (GH-95556) files: A Misc/NEWS.d/next/Documentation/2022-08-01-23-17-04.gh-issue-91207._P8i0B.rst M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index 01243de7805..8fdff7965d9 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -74,6 +74,11 @@ 'root_include_title': False # We use the version switcher instead. } +# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207 +# https://github.com/python/cpython/issues/91207 +if any('htmlhelp' in arg for arg in sys.argv): + html_style = 'pydoctheme.css' + # Short title used e.g. for HTML tags. html_short_title = '%s Documentation' % release diff --git a/Misc/NEWS.d/next/Documentation/2022-08-01-23-17-04.gh-issue-91207._P8i0B.rst b/Misc/NEWS.d/next/Documentation/2022-08-01-23-17-04.gh-issue-91207._P8i0B.rst new file mode 100644 index 00000000000..d71de3ed2f9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-01-23-17-04.gh-issue-91207._P8i0B.rst @@ -0,0 +1,2 @@ +Fix stylesheet not working in Windows CHM htmlhelp docs. +Contributed by C.A.M. Gerlach. From webhook-mailer at python.org Tue Aug 2 15:13:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 02 Aug 2022 19:13:16 -0000 Subject: [Python-checkins] gh-95451: Update docs for wasm32-emscripten and -wasi platforms (GH-95452) Message-ID: <mailman.442.1659467597.3313.python-checkins@python.org> https://github.com/python/cpython/commit/72cad6cfe5e8d0b424bdd224feee6a22631ec3e6 commit: 72cad6cfe5e8d0b424bdd224feee6a22631ec3e6 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-02T12:13:07-07:00 summary: gh-95451: Update docs for wasm32-emscripten and -wasi platforms (GH-95452) Co-authored-by: ?ric <merwok at netwok.org> Co-authored-by: Michael Droettboom <mdboom at gmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> (cherry picked from commit e3b6ff19aaa318a813130ba9ad2ab0a332f27feb) Co-authored-by: Christian Heimes <christian at python.org> files: A Doc/includes/wasm-notavail.rst A Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst M Doc/library/asynchat.rst M Doc/library/asyncio.rst M Doc/library/asyncore.rst M Doc/library/cgi.rst M Doc/library/compileall.rst M Doc/library/concurrent.futures.rst M Doc/library/crypt.rst M Doc/library/ensurepip.rst M Doc/library/fcntl.rst M Doc/library/ftplib.rst M Doc/library/getpass.rst M Doc/library/grp.rst M Doc/library/http.client.rst M Doc/library/http.server.rst M Doc/library/imaplib.rst M Doc/library/intro.rst M Doc/library/mmap.rst M Doc/library/multiprocessing.rst M Doc/library/nis.rst M Doc/library/nntplib.rst M Doc/library/os.rst M Doc/library/poplib.rst M Doc/library/pwd.rst M Doc/library/resource.rst M Doc/library/select.rst M Doc/library/selectors.rst M Doc/library/signal.rst M Doc/library/smtpd.rst M Doc/library/smtplib.rst M Doc/library/socket.rst M Doc/library/socketserver.rst M Doc/library/spwd.rst M Doc/library/ssl.rst M Doc/library/subprocess.rst M Doc/library/syslog.rst M Doc/library/telnetlib.rst M Doc/library/threading.rst M Doc/library/urllib.request.rst M Doc/library/venv.rst M Doc/library/webbrowser.rst M Doc/library/xmlrpc.client.rst M Doc/library/xmlrpc.server.rst M Doc/library/zoneinfo.rst M Doc/tools/extensions/pyspecific.py diff --git a/Doc/includes/wasm-notavail.rst b/Doc/includes/wasm-notavail.rst new file mode 100644 index 00000000000..e680e1f9b43 --- /dev/null +++ b/Doc/includes/wasm-notavail.rst @@ -0,0 +1,7 @@ +.. include for modules that don't work on WASM + +.. availability:: not Emscripten, not WASI. + + This module does not work or is not available on WebAssembly platforms + ``wasm32-emscripten`` and ``wasm32-wasi``. See + :ref:`wasm-availability` for more information. diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 777b7075b30..32e04ad6d19 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -34,6 +34,7 @@ Typically an :class:`asyncore.dispatcher` server channel generates new :class:`asynchat.async_chat` channel objects as it receives incoming connection requests. +.. include:: ../includes/wasm-notavail.rst .. class:: async_chat() diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 66c7c4c24a9..b71006e32b2 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -56,6 +56,7 @@ Additionally, there are **low-level** APIs for * :ref:`bridge <asyncio-futures>` callback-based libraries and code with async/await syntax. +.. include:: ../includes/wasm-notavail.rst .. We use the "rubric" directive here to avoid creating the "Reference" subsection in the TOC. diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index 0084d754419..a3a4e90d052 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -28,6 +28,8 @@ This module provides the basic infrastructure for writing asynchronous socket service clients and servers. +.. include:: ../includes/wasm-notavail.rst + There are only two ways to have a program on a single processor do "more than one thing at a time." Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index 983e412afaf..295a601a7bf 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -37,6 +37,7 @@ size of a POST request. POST requests larger than this size will result in a :exc:`ValueError` being raised during parsing. The default value of this variable is ``0``, meaning the request size is unlimited. +.. include:: ../includes/wasm-notavail.rst Introduction ------------ diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index de34664acb8..7af46cf3200 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -14,6 +14,7 @@ This module can be used to create the cached byte-code files at library installation time, which makes them available for use even by users who don't have write permission to the library directories. +.. include:: ../includes/wasm-notavail.rst Command-line use ---------------- diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index db5971e4d60..95c9e509914 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -19,6 +19,7 @@ The asynchronous execution can be performed with threads, using :class:`ProcessPoolExecutor`. Both implement the same interface, which is defined by the abstract :class:`Executor` class. +.. include:: ../includes/wasm-notavail.rst Executor Objects ---------------- diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index f585bbcbc18..740084b40c5 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -38,6 +38,8 @@ this module. .. availability:: Unix, not VxWorks. +.. include:: ../includes/wasm-notavail.rst + Hashing Methods --------------- diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index fa1b42cf484..34f45e20bae 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -36,6 +36,7 @@ when creating a virtual environment) or after explicitly uninstalling :pep:`453`: Explicit bootstrapping of pip in Python installations The original rationale and specification for this module. +.. include:: ../includes/wasm-notavail.rst Command line interface ---------------------- diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 1ecd552fbd0..c5a7ba0150e 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -18,6 +18,8 @@ interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines. For a complete description of these calls, see :manpage:`fcntl(2)` and :manpage:`ioctl(2)` Unix manual pages. +.. include:: ../includes/wasm-notavail.rst + All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by ``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 2f94ac49928..e5ba9eef407 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -21,6 +21,8 @@ as mirroring other FTP servers. It is also used by the module The default encoding is UTF-8, following :rfc:`2640`. +.. include:: ../includes/wasm-notavail.rst + Here's a sample session using the :mod:`ftplib` module:: >>> from ftplib import FTP diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index 82b11919a3d..d5bbe67fb30 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -12,8 +12,9 @@ -------------- -The :mod:`getpass` module provides two functions: +.. include:: ../includes/wasm-notavail.rst +The :mod:`getpass` module provides two functions: .. function:: getpass(prompt='Password: ', stream=None) diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index baa31752a2c..fabc22e4cf5 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -10,6 +10,8 @@ This module provides access to the Unix group database. It is available on all Unix versions. +.. include:: ../includes/wasm-notavail.rst + Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see ``<grp.h>``): diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index e605f7b8b14..8bb3187ef51 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -28,6 +28,8 @@ HTTPS protocols. It is normally not used directly --- the module HTTPS support is only available if Python was compiled with SSL support (through the :mod:`ssl` module). +.. include:: ../includes/wasm-notavail.rst + The module provides the following classes: diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 3bb7294ebb4..48f952daae1 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -22,6 +22,8 @@ This module defines classes for implementing HTTP servers. :mod:`http.server` is not recommended for production. It only implements :ref:`basic security checks <http.server-security>`. +.. include:: ../includes/wasm-notavail.rst + One class, :class:`HTTPServer`, is a :class:`socketserver.TCPServer` subclass. It creates and listens at the HTTP socket, dispatching the requests to a handler. Code to create and run the server looks like this:: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 65681ec0935..0c10e7afee4 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -26,6 +26,8 @@ implement a large subset of the IMAP4rev1 client protocol as defined in :rfc:`2060`. It is backward compatible with IMAP4 (:rfc:`1730`) servers, but note that the ``STATUS`` command is not supported in IMAP4. +.. include:: ../includes/wasm-notavail.rst + Three classes are provided by the :mod:`imaplib` module, :class:`IMAP4` is the base class: diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 120b174dc3b..1020924038e 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -64,3 +64,58 @@ Notes on availability libc version, then both conditions must hold. For example a feature with note *Availability: Linux >= 3.17 with glibc >= 2.27* requires both Linux 3.17 or newer and glibc 2.27 or newer. + +.. _wasm-availability: + +WebAssembly platforms +--------------------- + +The `WebAssembly`_ platforms ``wasm32-emscripten`` (`Emscripten`_) and +``wasm32-wasi`` (`WASI`_) provide a subset of POSIX APIs. WebAssembly runtimes +and browsers are sandboxed and have limited access to the host and external +resources. Any Python standard library module that uses processes, threading, +networking, signals, or other forms of inter-process communication (IPC), is +either not available or may not work as on other Unix-like systems. File I/O, +file system, and Unix permission-related functions are restricted, too. +Emscripten does not permit blocking I/O. Other blocking operations like +:func:`~time.sleep` block the browser event loop. + +The properties and behavior of Python on WebAssembly platforms depend on the +`Emscripten`_-SDK or `WASI`_-SDK version, WASM runtimes (browser, NodeJS, +`wasmtime`_), and Python build time flags. WebAssembly, Emscripten, and WASI +are evolving standards; some features like networking may be +supported in the future. + +For Python in the browser, users should consider `Pyodide`_ or `PyScript`_. +PyScript is built on top of Pyodide, which itself is built on top of +CPython and Emscripten. Pyodide provides access to browsers' JavaScript and +DOM APIs as well as limited networking capabilities with JavaScript's +``XMLHttpRequest`` and ``Fetch`` APIs. + +* Process-related APIs are not available or always fail with an error. That + includes APIs that spawn new processes (:func:`~os.fork`, + :func:`~os.execve`), wait for processes (:func:`~os.waitpid`), send signals + (:func:`~os.kill`), or otherwise interact with processes. The + :mod:`subprocess` is importable but does not work. + +* The :mod:`socket` module is available, but is limited and behaves + differently from other platforms. On Emscripten, sockets are always + non-blocking and require additional JavaScript code and helpers on the + server to proxy TCP through WebSockets; see `Emscripten Networking`_ + for more information. WASI snapshot preview 1 only permits sockets from an + existing file descriptor. + +* Some functions are stubs that either don't do anything and always return + hardcoded values. + +* Functions related to file descriptors, file permissions, file ownership, and + links are limited and don't support some operations. For example, WASI does + not permit symlinks with absolute file names. + +.. _WebAssembly: https://webassembly.org/ +.. _Emscripten: https://emscripten.org/ +.. _Emscripten Networking: https://emscripten.org/docs/porting/networking.html> +.. _WASI: https://wasi.dev/ +.. _wasmtime: https://wasmtime.dev/ +.. _Pyodide: https://pyodide.org/ +.. _PyScript: https://pyscript.net/ diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index 36c15e9d1d9..c4f8781f2ac 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -6,6 +6,8 @@ -------------- +.. include:: ../includes/wasm-notavail.rst + Memory-mapped file objects behave like both :class:`bytearray` and like :term:`file objects <file object>`. You can use mmap objects in most places where :class:`bytearray` are expected; for example, you can use the :mod:`re` diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 3eb98791726..eaa946462a1 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -8,6 +8,8 @@ -------------- +.. include:: ../includes/wasm-notavail.rst + Introduction ------------ diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index fd3c3d9293d..3fa7916c37b 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -21,6 +21,8 @@ central administration of several hosts. Because NIS exists only on Unix systems, this module is only available for Unix. +.. include:: ../includes/wasm-notavail.rst + The :mod:`nis` module defines the following functions: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index 2a996e451bf..a36c8a5dcce 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -21,6 +21,8 @@ the Network News Transfer Protocol. It can be used to implement a news reader or poster, or automated news processors. It is compatible with :rfc:`3977` as well as the older :rfc:`977` and :rfc:`2980`. +.. include:: ../includes/wasm-notavail.rst + Here are two small examples of how it can be used. To list some statistics about a newsgroup and print the subjects of the last 10 articles:: diff --git a/Doc/library/os.rst b/Doc/library/os.rst index de6f27c5d32..8fccef2c2cf 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -34,6 +34,14 @@ Notes on the availability of these functions: * On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported. +* On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, large + parts of the :mod:`os` module are not available or behave differently. API + related to processes (e.g. :func:`~os.fork`, :func:`~os.execve`), signals + (e.g. :func:`~os.kill`, :func:`~os.wait`), and resources + (e.g. :func:`~os.nice`) are not available. Others like :func:`~os.getuid` + and :func:`~os.getpid` are emulated or stubs. + + .. note:: All functions in this module raise :exc:`OSError` (or subclasses thereof) in @@ -165,7 +173,7 @@ process and user. Return the filename corresponding to the controlling terminal of the process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: environ @@ -337,7 +345,7 @@ process and user. Return the effective group id of the current process. This corresponds to the "set id" bit on the file being executed in the current process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: geteuid() @@ -346,7 +354,7 @@ process and user. Return the current process's effective user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getgid() @@ -357,6 +365,9 @@ process and user. .. availability:: Unix. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: getgrouplist(user, group) @@ -365,7 +376,7 @@ process and user. field from the password record for *user*, because that group ID will otherwise be potentially omitted. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -374,7 +385,7 @@ process and user. Return list of supplemental group ids associated with the current process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: @@ -402,7 +413,7 @@ process and user. falls back to ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the current real user id. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. function:: getpgid(pid) @@ -410,7 +421,7 @@ process and user. Return the process group id of the process with process id *pid*. If *pid* is 0, the process group id of the current process is returned. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getpgrp() @@ -418,7 +429,7 @@ process and user. Return the id of the current process group. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getpid() @@ -427,6 +438,8 @@ process and user. Return the current process id. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. .. function:: getppid() @@ -436,7 +449,7 @@ process and user. the id returned is the one of the init process (1), on Windows it is still the same id, which may be already reused by another process. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionchanged:: 3.2 Added support for Windows. @@ -454,7 +467,7 @@ process and user. (respectively) the calling process, the process group of the calling process, or the real user ID of the calling process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -465,7 +478,7 @@ process and user. Parameters for the :func:`getpriority` and :func:`setpriority` functions. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -475,7 +488,7 @@ process and user. Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -485,7 +498,7 @@ process and user. Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -498,6 +511,9 @@ process and user. .. availability:: Unix. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: initgroups(username, gid) @@ -505,7 +521,7 @@ process and user. the groups of which the specified username is a member, plus the specified group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -539,21 +555,21 @@ process and user. Set the current process's effective group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: seteuid(euid) Set the current process's effective user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setgid(gid) Set the current process' group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setgroups(groups) @@ -562,7 +578,7 @@ process and user. *groups*. *groups* must be a sequence, and each element must be an integer identifying a group. This operation is typically available only to the superuser. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: On macOS, the length of *groups* may not exceed the system-defined maximum number of effective group ids, typically 16. @@ -574,7 +590,7 @@ process and user. Call the system call :c:func:`setpgrp` or ``setpgrp(0, 0)`` depending on which version is implemented (if any). See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setpgid(pid, pgrp) @@ -583,7 +599,7 @@ process and user. process with id *pid* to the process group with id *pgrp*. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setpriority(which, who, priority) @@ -600,7 +616,7 @@ process and user. *priority* is a value in the range -20 to 19. The default priority is 0; lower priorities cause more favorable scheduling. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -609,14 +625,14 @@ process and user. Set the current process's real and effective group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setresgid(rgid, egid, sgid) Set the current process's real, effective, and saved group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -625,7 +641,7 @@ process and user. Set the current process's real, effective, and saved user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -634,21 +650,21 @@ process and user. Set the current process's real and effective user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getsid(pid) Call the system call :c:func:`getsid`. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setsid() Call the system call :c:func:`setsid`. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setuid(uid) @@ -657,7 +673,7 @@ process and user. Set the current process's user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. placed in this section since it relates to errno.... a little weak @@ -680,6 +696,9 @@ process and user. Set the current numeric umask and return the previous umask. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: uname() @@ -836,6 +855,8 @@ as internal buffering of data. 2: stderr), the new file descriptor is :ref:`inheritable <fd_inheritance>`. + .. availability:: not WASI. + .. versionchanged:: 3.4 The new file descriptor is now non-inheritable. @@ -847,6 +868,8 @@ as internal buffering of data. <fd_inheritance>` by default or non-inheritable if *inheritable* is ``False``. + .. availability:: not WASI. + .. versionchanged:: 3.4 Add the optional *inheritable* parameter. @@ -864,6 +887,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: fchown(fd, uid, gid) @@ -876,6 +902,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: fdatasync(fd) @@ -964,6 +993,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.5 @@ -1006,7 +1038,7 @@ as internal buffering of data. Make the calling process a session leader; make the tty the controlling tty, the stdin, the stdout, and the stderr of the calling process; close fd. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.11 @@ -1150,7 +1182,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo descriptors are :ref:`non-inheritable <fd_inheritance>`. For a (slightly) more portable approach, use the :mod:`pty` module. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.4 The new file descriptors are now non-inheritable. @@ -1176,7 +1208,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Return a pair of file descriptors ``(r, w)`` usable for reading and writing, respectively. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1186,7 +1218,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Ensures that enough disk space is allocated for the file specified by *fd* starting from *offset* and continuing for *len* bytes. - .. availability:: Unix. + .. availability:: Unix, not Emscripten. .. versionadded:: 3.3 @@ -1413,7 +1445,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Cross-platform applications should not use *headers*, *trailers* and *flags* arguments. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: @@ -1435,6 +1467,9 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.5 @@ -1445,7 +1480,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Parameters to the :func:`sendfile` function, if the implementation supports them. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1454,7 +1489,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Parameter to the :func:`sendfile` function, if the implementation supports it. The data won't be cached in the virtual memory and will be freed afterwards. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.11 @@ -1515,7 +1550,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Return the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`). - .. availability:: Unix. + .. availability:: Unix, not WASI. .. function:: tcsetpgrp(fd, pg) @@ -1523,7 +1558,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Set the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`) to *pg*. - .. availability:: Unix. + .. availability:: Unix, not WASI. .. function:: ttyname(fd) @@ -1631,6 +1666,9 @@ Using the :mod:`subprocess` module, all file descriptors except standard streams are closed, and inheritable handles are only inherited if the *close_fds* parameter is ``False``. +On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, the file +descriptor cannot be modified. + .. function:: get_inheritable(fd) Get the "inheritable" flag of the specified file descriptor (a boolean). @@ -1815,7 +1853,7 @@ features: .. audit-event:: os.chflags path,flags os.chflags - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *follow_symlinks* argument. @@ -1860,6 +1898,9 @@ features: read-only flag with it (via the ``stat.S_IWRITE`` and ``stat.S_IREAD`` constants or a corresponding integer value). All other bits are ignored. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. audit-event:: os.chmod path,mode,dir_fd os.chmod .. versionadded:: 3.3 @@ -1886,6 +1927,9 @@ features: .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. @@ -1898,7 +1942,7 @@ features: Change the root directory of the current process to *path*. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -1938,7 +1982,7 @@ features: .. audit-event:: os.chflags path,flags os.lchflags - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2155,7 +2199,7 @@ features: FIFO for reading, and the client opens it for writing. Note that :func:`mkfifo` doesn't open the FIFO --- it just creates the rendezvous point. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *dir_fd* argument. @@ -2177,7 +2221,7 @@ features: This function can also support :ref:`paths relative to directory descriptors <dir_fd>`. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *dir_fd* argument. @@ -3045,6 +3089,9 @@ features: .. availability:: Unix, Windows. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionchanged:: 3.2 Added support for Windows 6.0 (Vista) symbolic links. @@ -3656,7 +3703,7 @@ to be ignored. .. audit-event:: os.exec path,args,env os.execl - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor @@ -3699,49 +3746,49 @@ written in Python, such as a mail server's external command delivery program. Exit code that means the command was used incorrectly, such as when the wrong number of arguments are given. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_DATAERR Exit code that means the input data was incorrect. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOINPUT Exit code that means an input file did not exist or was not readable. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOUSER Exit code that means a specified user did not exist. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOHOST Exit code that means a specified host did not exist. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_UNAVAILABLE Exit code that means that a required service is unavailable. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_SOFTWARE Exit code that means an internal software error was detected. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_OSERR @@ -3749,7 +3796,7 @@ written in Python, such as a mail server's external command delivery program. Exit code that means an operating system error was detected, such as the inability to fork or create a pipe. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_OSFILE @@ -3757,21 +3804,21 @@ written in Python, such as a mail server's external command delivery program. Exit code that means some system file did not exist, could not be opened, or had some other kind of error. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_CANTCREAT Exit code that means a user specified output file could not be created. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_IOERR Exit code that means that an error occurred while doing I/O on some file. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_TEMPFAIL @@ -3780,7 +3827,7 @@ written in Python, such as a mail server's external command delivery program. that may not really be an error, such as a network connection that couldn't be made during a retryable operation. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_PROTOCOL @@ -3788,7 +3835,7 @@ written in Python, such as a mail server's external command delivery program. Exit code that means that a protocol exchange was illegal, invalid, or not understood. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOPERM @@ -3796,21 +3843,21 @@ written in Python, such as a mail server's external command delivery program. Exit code that means that there were insufficient permissions to perform the operation (but not intended for file system problems). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_CONFIG Exit code that means that some kind of configuration error occurred. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOTFOUND Exit code that means something like "an entry was not found". - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: fork() @@ -3831,7 +3878,7 @@ written in Python, such as a mail server's external command delivery program. See :mod:`ssl` for applications that use the SSL module with fork(). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: forkpty() @@ -3848,7 +3895,7 @@ written in Python, such as a mail server's external command delivery program. Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: kill(pid, sig) @@ -3872,6 +3919,8 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.kill pid,sig os.kill + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionadded:: 3.2 Windows support. @@ -3886,14 +3935,14 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.killpg pgid,sig os.killpg - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: nice(increment) Add *increment* to the process's "niceness". Return the new niceness. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: pidfd_open(pid, flags=0) @@ -3914,7 +3963,7 @@ written in Python, such as a mail server's external command delivery program. Lock program segments into memory. The value of *op* (defined in ``<sys/lock.h>``) determines which segments are locked. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: popen(cmd, mode='r', buffering=-1) @@ -3946,6 +3995,8 @@ written in Python, such as a mail server's external command delivery program. documentation for more powerful ways to manage and communicate with subprocesses. + .. availability:: not Emscripten, not WASI. + .. note:: The :ref:`Python UTF-8 Mode <utf8-mode>` affects encodings used for *cmd* and pipe contents. @@ -4039,7 +4090,7 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: posix_spawnp(path, argv, env, *, file_actions=None, \ setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ @@ -4055,7 +4106,7 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: POSIX + .. availability:: POSIX, not Emscripten, not WASI. See :func:`posix_spawn` documentation. @@ -4088,7 +4139,7 @@ written in Python, such as a mail server's external command delivery program. There is no way to unregister a function. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.7 @@ -4157,7 +4208,7 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.spawn mode,path,args,env os.spawnl - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and @@ -4281,7 +4332,7 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.system command os.system - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. function:: times() @@ -4322,7 +4373,7 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. seealso:: @@ -4343,7 +4394,7 @@ written in Python, such as a mail server's external command delivery program. :attr:`si_code` or ``None`` if :data:`WNOHANG` is specified and there are no children in a waitable state. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4354,7 +4405,7 @@ written in Python, such as a mail server's external command delivery program. These are the possible values for *idtype* in :func:`waitid`. They affect how *id* is interpreted. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4374,7 +4425,7 @@ written in Python, such as a mail server's external command delivery program. Flags that can be used in *options* in :func:`waitid` that specify what child signal to wait for. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4389,7 +4440,7 @@ written in Python, such as a mail server's external command delivery program. These are the possible values for :attr:`si_code` in the result returned by :func:`waitid`. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -4427,6 +4478,8 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. + .. availability:: Unix, not Emscripten, not WASI. + .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an exception, the function now retries the system call instead of raising an @@ -4445,7 +4498,7 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: wait4(pid, options) @@ -4459,7 +4512,7 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: waitstatus_to_exitcode(status) @@ -4489,6 +4542,8 @@ written in Python, such as a mail server's external command delivery program. :func:`WIFEXITED`, :func:`WEXITSTATUS`, :func:`WIFSIGNALED`, :func:`WTERMSIG`, :func:`WIFSTOPPED`, :func:`WSTOPSIG` functions. + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionadded:: 3.9 @@ -4497,7 +4552,7 @@ written in Python, such as a mail server's external command delivery program. The option for :func:`waitpid` to return immediately if no child process status is available immediately. The function returns ``(0, 0)`` in this case. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: WCONTINUED @@ -4505,7 +4560,7 @@ written in Python, such as a mail server's external command delivery program. This option causes child processes to be reported if they have been continued from a job control stop since their status was last reported. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Some Unix systems. @@ -4515,7 +4570,7 @@ written in Python, such as a mail server's external command delivery program. This option causes child processes to be reported if they have been stopped but their current state has not been reported since they were stopped. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. The following functions take a process status code as returned by @@ -4529,7 +4584,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSIGNALED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFCONTINUED(status) @@ -4540,7 +4595,7 @@ used to determine the disposition of a process. See :data:`WCONTINUED` option. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFSTOPPED(status) @@ -4552,14 +4607,14 @@ used to determine the disposition of a process. done using :data:`WUNTRACED` option or when the process is being traced (see :manpage:`ptrace(2)`). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFSIGNALED(status) Return ``True`` if the process was terminated by a signal, otherwise return ``False``. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFEXITED(status) @@ -4568,7 +4623,7 @@ used to determine the disposition of a process. by calling ``exit()`` or ``_exit()``, or by returning from ``main()``; otherwise return ``False``. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WEXITSTATUS(status) @@ -4577,7 +4632,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFEXITED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WSTOPSIG(status) @@ -4586,7 +4641,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSTOPPED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WTERMSIG(status) @@ -4595,7 +4650,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSIGNALED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Interface to the scheduler diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 2f993f990de..e22a2e1455e 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -28,6 +28,8 @@ quality of POP3 servers varies widely, and too many are quite poor. If your mailserver supports IMAP, you would be better off using the :class:`imaplib.IMAP4` class, as IMAP servers tend to be better implemented. +.. include:: ../includes/wasm-notavail.rst + The :mod:`poplib` module provides two classes: diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst index 03ebb02e4e5..98f3c45e29c 100644 --- a/Doc/library/pwd.rst +++ b/Doc/library/pwd.rst @@ -10,6 +10,8 @@ This module provides access to the Unix user account and password database. It is available on all Unix versions. +.. include:: ../includes/wasm-notavail.rst + Password database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``passwd`` structure (Attribute field below, see ``<pwd.h>``): diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 7c9c5a0819b..e7bf45d7d56 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -13,6 +13,8 @@ This module provides basic mechanisms for measuring and controlling system resources utilized by a program. +.. include:: ../includes/wasm-notavail.rst + Symbolic constants are used to specify particular system resources and to request usage information about either the current process or its children. diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 1c3d10ef209..a8df81f5bd1 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -22,6 +22,7 @@ it was last read. encouraged to use the :mod:`selectors` module instead, unless they want precise control over the OS-level primitives used. +.. include:: ../includes/wasm-notavail.rst The module defines the following: diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index 6d864a836de..0deb15cf4c5 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -38,6 +38,7 @@ users. :mod:`select` Low-level I/O multiplexing module. +.. include:: ../includes/wasm-notavail.rst Classes ------- diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 72b8f03fc16..2269f50cbaf 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -24,6 +24,9 @@ explicitly reset (Python emulates the BSD style interface regardless of the underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. +On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, signals +are emulated and therefore behave differently. Several functions and signals +are not available on these platforms. Execution of Python signal handlers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 5a7e41c6d09..ac0c9aeb236 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -31,6 +31,7 @@ interaction behaviour with SMTP clients. The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` SMTPUTF8 extensions. +.. include:: ../includes/wasm-notavail.rst SMTPServer Objects ------------------ diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index aaab6b11d3b..4e50ad1568e 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -19,6 +19,7 @@ to send mail to any internet machine with an SMTP or ESMTP listener daemon. For details of SMTP and ESMTP operation, consult :rfc:`821` (Simple Mail Transfer Protocol) and :rfc:`1869` (SMTP Service Extensions). +.. include:: ../includes/wasm-notavail.rst .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index f35df364a34..c4bf3dcf32a 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -16,6 +16,9 @@ all modern Unix systems, Windows, MacOS, and probably additional platforms. Some behavior may be platform dependent, since calls are made to the operating system socket APIs. + +.. include:: ../includes/wasm-notavail.rst + .. index:: object: socket The Python interface is a straightforward transliteration of the Unix system @@ -871,6 +874,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyname hostname socket.gethostbyname + .. availability:: not WASI. + .. function:: gethostbyname_ex(hostname) @@ -885,6 +890,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyname hostname socket.gethostbyname_ex + .. availability:: not WASI. + .. function:: gethostname() @@ -896,6 +903,8 @@ The :mod:`socket` module also offers various network-related services: Note: :func:`gethostname` doesn't always return the fully qualified domain name; use :func:`getfqdn` for that. + .. availability:: not WASI. + .. function:: gethostbyaddr(ip_address) @@ -909,6 +918,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyaddr ip_address socket.gethostbyaddr + .. availability:: not WASI. + .. function:: getnameinfo(sockaddr, flags) @@ -924,6 +935,9 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getnameinfo sockaddr socket.getnameinfo + .. availability:: not WASI. + + .. function:: getprotobyname(protocolname) Translate an internet protocol name (for example, ``'icmp'``) to a constant @@ -932,6 +946,8 @@ The :mod:`socket` module also offers various network-related services: (:const:`SOCK_RAW`); for the normal socket modes, the correct protocol is chosen automatically if the protocol is omitted or zero. + .. availability:: not WASI. + .. function:: getservbyname(servicename[, protocolname]) @@ -941,6 +957,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getservbyname servicename,protocolname socket.getservbyname + .. availability:: not WASI. + .. function:: getservbyport(port[, protocolname]) @@ -950,6 +968,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getservbyport port,protocolname socket.getservbyport + .. availability:: not WASI. + .. function:: ntohl(x) @@ -1083,7 +1103,7 @@ The :mod:`socket` module also offers various network-related services: buffer. Raises :exc:`OverflowError` if *length* is outside the permissible range of values. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Most Unix platforms. @@ -1106,7 +1126,7 @@ The :mod:`socket` module also offers various network-related services: amount of ancillary data that can be received, since additional data may be able to fit into the padding area. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. most Unix platforms. @@ -1146,7 +1166,7 @@ The :mod:`socket` module also offers various network-related services: (index int, name string) tuples. :exc:`OSError` if the system call fails. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1173,7 +1193,7 @@ The :mod:`socket` module also offers various network-related services: interface name. :exc:`OSError` if no interface with the given name exists. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1190,7 +1210,7 @@ The :mod:`socket` module also offers various network-related services: interface index number. :exc:`OSError` if no interface with the given index exists. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1207,7 +1227,7 @@ The :mod:`socket` module also offers various network-related services: The *fds* parameter is a sequence of file descriptors. Consult :meth:`sendmsg` for the documentation of these parameters. - .. availability:: Unix. + .. availability:: Unix, Windows, not Emscripten, not WASI. Unix platforms supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. @@ -1221,7 +1241,7 @@ The :mod:`socket` module also offers various network-related services: Return ``(msg, list(fds), flags, addr)``. Consult :meth:`recvmsg` for the documentation of these parameters. - .. availability:: Unix. + .. availability:: Unix, Windows, not Emscripten, not WASI. Unix platforms supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. @@ -1272,6 +1292,9 @@ to sockets. .. audit-event:: socket.bind self,address socket.socket.bind + .. availability:: not WASI. + + .. method:: socket.close() Mark the socket closed. The underlying system resource (e.g. a file @@ -1316,6 +1339,8 @@ to sockets. signal, the signal handler doesn't raise an exception and the socket is blocking or has a timeout (see the :pep:`475` for the rationale). + .. availability:: not WASI. + .. method:: socket.connect_ex(address) @@ -1328,6 +1353,8 @@ to sockets. .. audit-event:: socket.connect self,address socket.socket.connect_ex + .. availability:: not WASI. + .. method:: socket.detach() Put the socket object into closed state without actually closing the @@ -1346,6 +1373,8 @@ to sockets. .. versionchanged:: 3.4 The socket is now non-inheritable. + .. availability:: not WASI. + .. method:: socket.fileno() @@ -1391,6 +1420,8 @@ to sockets. contents of the buffer (see the optional built-in module :mod:`struct` for a way to decode C structures encoded as byte strings). + .. availability:: not WASI. + .. method:: socket.getblocking() @@ -1434,9 +1465,12 @@ to sockets. unaccepted connections that the system will allow before refusing new connections. If not specified, a default reasonable value is chosen. + .. availability:: not WASI. + .. versionchanged:: 3.5 The *backlog* parameter is now optional. + .. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, \ errors=None, newline=None) @@ -1711,7 +1745,7 @@ to sockets. def send_fds(sock, msg, fds): return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))]) - .. availability:: Unix. + .. availability:: Unix, not WASI. Most Unix platforms. @@ -1807,13 +1841,14 @@ to sockets. *optlen* argument is required. It's equivalent to call :c:func:`setsockopt` C function with ``optval=NULL`` and ``optlen=optlen``. - .. versionchanged:: 3.5 Writable :term:`bytes-like object` is now accepted. .. versionchanged:: 3.6 setsockopt(level, optname, None, optlen: int) form added. + .. availability:: not WASI. + .. method:: socket.shutdown(how) @@ -1822,6 +1857,8 @@ to sockets. are disallowed. If *how* is :const:`SHUT_RDWR`, further sends and receives are disallowed. + .. availability:: not WASI. + .. method:: socket.share(process_id) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index b65a3e8fb2b..70d56a1dad9 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -10,6 +10,8 @@ The :mod:`socketserver` module simplifies the task of writing network servers. +.. include:: ../includes/wasm-notavail.rst + There are four basic concrete server classes: diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index 87e09167ada..d1693ea67f0 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -15,6 +15,8 @@ This module provides access to the Unix shadow password database. It is available on various Unix versions. +.. include:: ../includes/wasm-notavail.rst + You must have enough privileges to access the shadow password database (this usually means you have to be root). diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index dd6d243734a..a0aa45e9008 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -33,6 +33,7 @@ probably additional platforms, as long as OpenSSL is installed on that platform. may lead to a false sense of security, as the default settings of the ssl module are not necessarily appropriate for your application. +.. include:: ../includes/wasm-notavail.rst This section documents the objects and functions in the ``ssl`` module; for more general information about TLS, SSL, and certificates, the reader is referred to diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index fae81f8ac28..43d6ffceee8 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -25,6 +25,7 @@ modules and functions can be found in the following sections. :pep:`324` -- PEP proposing the subprocess module +.. include:: ../includes/wasm-notavail.rst Using the :mod:`subprocess` Module ---------------------------------- diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index d264a3340c9..16093d5aac7 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -15,6 +15,8 @@ This module wraps the system ``syslog`` family of routines. A pure Python library that can speak to a syslog server is available in the :mod:`logging.handlers` module as :class:`SysLogHandler`. +.. include:: ../includes/wasm-notavail.rst + The module defines the following functions: diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 70b8c7d1511..5a993dc42a5 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -30,6 +30,7 @@ SE (Subnegotiation End), NOP (No Operation), DM (Data Mark), BRK (Break), IP (Interrupt process), AO (Abort output), AYT (Are You There), EC (Erase Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin). +.. include:: ../includes/wasm-notavail.rst .. class:: Telnet(host=None, port=0[, timeout]) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index cc266fa323b..9511eaebf15 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -33,6 +33,7 @@ level :mod:`_thread` module. See also the :mod:`queue` module. However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously. +.. include:: ../includes/wasm-notavail.rst This module defines the following functions: diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 542db1b5e2a..59e1f2da828 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -21,6 +21,7 @@ authentication, redirections, cookies and more. The `Requests package <https://requests.readthedocs.io/en/master/>`_ is recommended for a higher-level HTTP client interface. +.. include:: ../includes/wasm-notavail.rst The :mod:`urllib.request` module defines the following functions: diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index b40bd4102c2..3fa1046ae97 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -29,6 +29,7 @@ See :pep:`405` for more information about Python virtual environments. `Python Packaging User Guide: Creating and using virtual environments <https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment>`__ +.. include:: ../includes/wasm-notavail.rst Creating virtual environments ----------------------------- diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 1dc59306164..734b6321e5a 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -41,6 +41,8 @@ naturally, mutually exclusive. Usage example:: python -m webbrowser -t "https://www.python.org" +.. include:: ../includes/wasm-notavail.rst + The following exception is defined: diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 0d9bfd51f1e..9f5ba46934b 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -32,6 +32,8 @@ between conformable Python objects and XML on the wire. For HTTPS URIs, :mod:`xmlrpc.client` now performs all the necessary certificate and hostname checks by default. +.. include:: ../includes/wasm-notavail.rst + .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \ allow_none=False, use_datetime=False, \ use_builtin_types=False, *, headers=(), context=None) diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 7d561e2303f..9778a859da1 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -23,6 +23,7 @@ servers written in Python. Servers can either be free standing, using constructed data. If you need to parse untrusted or unauthenticated data see :ref:`xml-vulnerabilities`. +.. include:: ../includes/wasm-notavail.rst .. class:: SimpleXMLRPCServer(addr, requestHandler=SimpleXMLRPCRequestHandler,\ logRequests=True, allow_none=False, encoding=None,\ diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index 1b2ba2af2ae..2f1879dc056 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -27,6 +27,7 @@ first-party `tzdata`_ package available on PyPI. First-party package maintained by the CPython core developers to supply time zone data via PyPI. +.. include:: ../includes/wasm-notavail.rst Using ``ZoneInfo`` ------------------ diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index a795e05b8b9..f326e77b263 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -144,11 +144,11 @@ class Availability(Directive): known_platforms = frozenset({ "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", "Unix", "VxWorks", - "WASI", "Windows", "macOS", - # libc - "BSD libc", "glibc", "musl", - # POSIX platforms with pthreads - "pthreads", + "WASI", "Windows", "macOS", + # libc + "BSD libc", "glibc", "musl", + # POSIX platforms with pthreads + "pthreads", }) def run(self): @@ -160,9 +160,7 @@ def run(self): n, m = self.state.inline_text(self.arguments[0], self.lineno) pnode.extend(n + m) if self.content: - content = " " + " ".join(self.content) - n, m = self.state.inline_text(content, self.content_offset) - pnode.extend(n + m) + self.state.nested_parse(self.content, self.content_offset, pnode) self.parse_platforms() diff --git a/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst b/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst new file mode 100644 index 00000000000..3a7b8a122b7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst @@ -0,0 +1,3 @@ +Update library documentation with +:ref:`availability information <wasm-availability>` +on WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``. From webhook-mailer at python.org Tue Aug 2 18:17:19 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 02 Aug 2022 22:17:19 -0000 Subject: [Python-checkins] Docs: fix incorrect formatting in sqlite3 CLI docs (#95581) Message-ID: <mailman.443.1659478639.3313.python-checkins@python.org> https://github.com/python/cpython/commit/89f52293281b6efc4ef666ef25e677683821f4b9 commit: 89f52293281b6efc4ef666ef25e677683821f4b9 branch: main author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-03T00:17:09+02:00 summary: Docs: fix incorrect formatting in sqlite3 CLI docs (#95581) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 28bd7ce900b..303be626076 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1454,10 +1454,12 @@ Type ``.quit`` or CTRL-D to exit the shell. .. program:: python -m sqlite3 [-h] [-v] [filename] [sql] .. option:: -h, --help - Print CLI help. + + Print CLI help. .. option:: -v, --version - Print underlying SQLite library version. + + Print underlying SQLite library version. .. versionadded:: 3.12 From webhook-mailer at python.org Wed Aug 3 13:56:46 2022 From: webhook-mailer at python.org (markshannon) Date: Wed, 03 Aug 2022 17:56:46 -0000 Subject: [Python-checkins] GH-92678: Fix tp_dictoffset inheritance. (GH-95596) Message-ID: <mailman.444.1659549407.3313.python-checkins@python.org> https://github.com/python/cpython/commit/906e4509328917fe9951f85457897f6a841e0529 commit: 906e4509328917fe9951f85457897f6a841e0529 branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-03T18:56:24+01:00 summary: GH-92678: Fix tp_dictoffset inheritance. (GH-95596) * Add test for inheriting explicit __dict__ and weakref. * Restore 3.10 behavior for multiple inheritance of C extension classes that store their dictionary at the end of the struct. files: A Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst M Lib/test/test_capi.py M Modules/_testcapi/heaptype.c M Objects/typeobject.c diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index a88a17d3c55..013229a6cdc 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -619,6 +619,25 @@ def test_heaptype_with_custom_metaclass(self): with self.assertRaisesRegex(TypeError, msg): t = _testcapi.pytype_fromspec_meta(_testcapi.HeapCTypeMetaclassCustomNew) + def test_multiple_inheritance_ctypes_with_weakref_or_dict(self): + + class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + pass + class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + pass + + for cls in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, + _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): + for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, + _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): + if cls is not cls2: + class S(cls, cls2): + pass + class B1(Both1, cls): + pass + class B2(Both1, cls): + pass + def test_pytype_fromspec_with_repeated_slots(self): for variant in range(2): with self.subTest(variant=variant): diff --git a/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst b/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst new file mode 100644 index 00000000000..6bf3d4b1abb --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst @@ -0,0 +1,2 @@ +Restore the 3.10 behavior for multiple inheritance of C extension classes +that store their dictionary at the end of the struct. diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index 9fb0051ca12..12889e825d5 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -737,6 +737,14 @@ static PyType_Spec HeapCTypeWithDict_spec = { HeapCTypeWithDict_slots }; +static PyType_Spec HeapCTypeWithDict2_spec = { + "_testcapi.HeapCTypeWithDict2", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + static struct PyMemberDef heapctypewithnegativedict_members[] = { {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, @@ -796,6 +804,14 @@ static PyType_Spec HeapCTypeWithWeakref_spec = { HeapCTypeWithWeakref_slots }; +static PyType_Spec HeapCTypeWithWeakref2_spec = { + "_testcapi.HeapCTypeWithWeakref2", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + PyDoc_STRVAR(heapctypesetattr__doc__, "A heap type without GC, but with overridden __setattr__.\n\n" "The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); @@ -919,6 +935,12 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { } PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); + PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); + if (HeapCTypeWithDict2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); + PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); if (HeapCTypeWithNegativeDict == NULL) { return -1; @@ -931,6 +953,12 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { } PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); + PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); + if (HeapCTypeWithWeakref2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); + PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); if (HeapCTypeWithBuffer == NULL) { return -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d33befc05d7..1980fcbf932 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2316,6 +2316,11 @@ best_base(PyObject *bases) return base; } +#define ADDED_FIELD_AT_OFFSET(name, offset) \ + (type->tp_ ## name && (base->tp_ ##name == 0) && \ + type->tp_ ## name + sizeof(PyObject *) == (offset) && \ + type->tp_flags & Py_TPFLAGS_HEAPTYPE) + static int extra_ivars(PyTypeObject *type, PyTypeObject *base) { @@ -2328,10 +2333,18 @@ extra_ivars(PyTypeObject *type, PyTypeObject *base) return t_size != b_size || type->tp_itemsize != base->tp_itemsize; } - if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 && - type->tp_weaklistoffset + sizeof(PyObject *) == t_size && - type->tp_flags & Py_TPFLAGS_HEAPTYPE) + /* Check for __dict__ and __weakrefs__ slots in either order */ + if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { + t_size -= sizeof(PyObject *); + } + if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0 && + ADDED_FIELD_AT_OFFSET(dictoffset, t_size)) { t_size -= sizeof(PyObject *); + } + /* Check __weakrefs__ again, in case it precedes __dict__ */ + if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { + t_size -= sizeof(PyObject *); + } return t_size != b_size; } From webhook-mailer at python.org Wed Aug 3 15:23:32 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 03 Aug 2022 19:23:32 -0000 Subject: [Python-checkins] gh-91207: Fix CSS bug in Windows CHM help file and add deprecation message (GH-95607) Message-ID: <mailman.445.1659554613.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ac3bf6155f8addc62f9a9c48f07eef8c3a6f71b2 commit: ac3bf6155f8addc62f9a9c48f07eef8c3a6f71b2 branch: main author: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> committer: zooba <steve.dower at microsoft.com> date: 2022-08-03T20:23:20+01:00 summary: gh-91207: Fix CSS bug in Windows CHM help file and add deprecation message (GH-95607) files: A Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index bf0af6a663c..0a436d7affc 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -79,6 +79,13 @@ 'root_include_title': False # We use the version switcher instead. } +# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207 +# https://github.com/python/cpython/issues/91207 +if any('htmlhelp' in arg for arg in sys.argv): + html_style = 'pydoctheme.css' + print("\nWARNING: Windows CHM Help is no longer supported.") + print("It may be removed in the future\n") + # Short title used e.g. for <title> HTML tags. html_short_title = '%s Documentation' % release diff --git a/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst b/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst new file mode 100644 index 00000000000..8c7391f7edf --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst @@ -0,0 +1,3 @@ +Fix stylesheet not working in Windows CHM htmlhelp docs +and add warning that they are deprecated. +Contributed by C.A.M. Gerlach. From webhook-mailer at python.org Wed Aug 3 15:27:00 2022 From: webhook-mailer at python.org (pfmoore) Date: Wed, 03 Aug 2022 19:27:00 -0000 Subject: [Python-checkins] gh-95609: update bundled pip to 22.2.2 (gh-95610) Message-ID: <mailman.446.1659554821.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3d9d45b22cb1e90bca2901eade4b3125aeadb8c9 commit: 3d9d45b22cb1e90bca2901eade4b3125aeadb8c9 branch: main author: St?phane Bidoul <stephane.bidoul at gmail.com> committer: pfmoore <p.f.moore at gmail.com> date: 2022-08-03T20:26:51+01:00 summary: gh-95609: update bundled pip to 22.2.2 (gh-95610) files: A Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst D Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 885a1edf4b3..33c91801b0a 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,7 +11,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "63.2.0" -_PIP_VERSION = "22.2.1" +_PIP_VERSION = "22.2.2" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl similarity index 94% rename from Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl index 4654c00136c..03099718b0b 100644 Binary files a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl and b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst new file mode 100644 index 00000000000..81c02ae900f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst @@ -0,0 +1 @@ +Update bundled pip to 22.2.2. From webhook-mailer at python.org Wed Aug 3 15:52:46 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 19:52:46 -0000 Subject: [Python-checkins] gh-95609: update bundled pip to 22.2.2 (gh-95610) Message-ID: <mailman.447.1659556367.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5bc2c3a6d04a3475d6a72544fec3a9e313ebc436 commit: 5bc2c3a6d04a3475d6a72544fec3a9e313ebc436 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T12:52:38-07:00 summary: gh-95609: update bundled pip to 22.2.2 (gh-95610) (cherry picked from commit 3d9d45b22cb1e90bca2901eade4b3125aeadb8c9) Co-authored-by: St?phane Bidoul <stephane.bidoul at gmail.com> files: A Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst D Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 885a1edf4b3..33c91801b0a 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,7 +11,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "63.2.0" -_PIP_VERSION = "22.2.1" +_PIP_VERSION = "22.2.2" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl similarity index 94% rename from Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl index 4654c00136c..03099718b0b 100644 Binary files a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl and b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst new file mode 100644 index 00000000000..81c02ae900f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst @@ -0,0 +1 @@ +Update bundled pip to 22.2.2. From webhook-mailer at python.org Wed Aug 3 16:11:51 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 20:11:51 -0000 Subject: [Python-checkins] gh-95609: update bundled pip to 22.2.2 (gh-95610) Message-ID: <mailman.448.1659557513.3313.python-checkins@python.org> https://github.com/python/cpython/commit/72e4afdc8ace8c39c1fb89c50b7e47dc8cc27c44 commit: 72e4afdc8ace8c39c1fb89c50b7e47dc8cc27c44 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T13:11:41-07:00 summary: gh-95609: update bundled pip to 22.2.2 (gh-95610) (cherry picked from commit 3d9d45b22cb1e90bca2901eade4b3125aeadb8c9) Co-authored-by: St?phane Bidoul <stephane.bidoul at gmail.com> files: A Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst D Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index b6973dbad3f..1826cdcf91a 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -12,7 +12,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "63.2.0" -_PIP_VERSION = "22.2.1" +_PIP_VERSION = "22.2.2" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl similarity index 94% rename from Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl index 4654c00136c..03099718b0b 100644 Binary files a/Lib/ensurepip/_bundled/pip-22.2.1-py3-none-any.whl and b/Lib/ensurepip/_bundled/pip-22.2.2-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst new file mode 100644 index 00000000000..81c02ae900f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst @@ -0,0 +1 @@ +Update bundled pip to 22.2.2. From webhook-mailer at python.org Wed Aug 3 16:21:31 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 03 Aug 2022 20:21:31 -0000 Subject: [Python-checkins] gh-95273: Align sqlite3 const doc refs with the devguide recommendations (#95525) Message-ID: <mailman.449.1659558093.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4d02572f8c39b16c83c0883917db4e31efc1048e commit: 4d02572f8c39b16c83c0883917db4e31efc1048e branch: main author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-03T22:21:15+02:00 summary: gh-95273: Align sqlite3 const doc refs with the devguide recommendations (#95525) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 303be626076..3fade30c256 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -322,13 +322,13 @@ Module functions and constants The :attr:`~Connection.isolation_level` of the connection, controlling whether and how transactions are implicitly opened. Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``; - or :const:`None` to disable opening transactions implicitly. + or ``None`` to disable opening transactions implicitly. See :ref:`sqlite3-controlling-transactions` for more. - :type isolation_level: str | :const:`None` + :type isolation_level: str | None :param check_same_thread: - If :const:`True` (default), only the creating thread may use the connection. - If :const:`False`, the connection may be shared across multiple threads; + If ``True`` (default), only the creating thread may use the connection. + If ``False``, the connection may be shared across multiple threads; if so, write operations should be serialized by the user to avoid data corruption. :type check_same_thread: bool @@ -345,7 +345,7 @@ Module functions and constants :type cached_statements: int :param uri: - If set to :const:`True`, *database* is interpreted as a + If set to ``True``, *database* is interpreted as a :abbr:`URI (Uniform Resource Identifier)` with a file path and an optional query string. The scheme part *must* be ``"file:"``, @@ -394,7 +394,7 @@ Module functions and constants .. function:: complete_statement(statement) - Returns :const:`True` if the string *statement* contains one or more complete SQL + Returns ``True`` if the string *statement* contains one or more complete SQL statements terminated by semicolons. It does not verify that the SQL is syntactically correct, only that there are no unclosed string literals and the statement is terminated by a semicolon. @@ -410,8 +410,8 @@ Module functions and constants Enable or disable callback tracebacks. By default you will not get any tracebacks in user-defined functions, aggregates, converters, authorizer callbacks etc. If you want to debug them, - you can call this function with *flag* set to :const:`True`. Afterwards, you - will get tracebacks from callbacks on :data:`sys.stderr`. Use :const:`False` + you can call this function with *flag* set to ``True``. Afterwards, you + will get tracebacks from callbacks on :data:`sys.stderr`. Use ``False`` to disable the feature again. Register an :func:`unraisable hook handler <sys.unraisablehook>` for an @@ -456,7 +456,7 @@ Connection objects This attribute controls the :ref:`transaction handling <sqlite3-controlling-transactions>` performed by ``sqlite3``. - If set to :const:`None`, transactions are never implicitly opened. + If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, implicit :ref:`transaction management @@ -470,8 +470,8 @@ Connection objects This read-only attribute corresponds to the low-level SQLite `autocommit mode`_. - :const:`True` if a transaction is active (there are uncommitted changes), - :const:`False` otherwise. + ``True`` if a transaction is active (there are uncommitted changes), + ``False`` otherwise. .. versionadded:: 3.2 @@ -500,9 +500,9 @@ Connection objects :type row: str :param readonly: - Set to :const:`True` if the blob should be opened without write + Set to ``True`` if the blob should be opened without write permissions. - Defaults to :const:`False`. + Defaults to ``False``. :type readonly: bool :param name: @@ -574,11 +574,11 @@ Connection objects A callable that is called when the SQL function is invoked. The callable must return :ref:`a type natively supported by SQLite <sqlite3-types>`. - Set to :const:`None` to remove an existing SQL function. - :type func: :term:`callback` | :const:`None` + Set to ``None`` to remove an existing SQL function. + :type func: :term:`callback` | None :param deterministic: - If :const:`True`, the created SQL function is marked as + If ``True``, the created SQL function is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which allows SQLite to perform additional optimizations. :type deterministic: bool @@ -617,8 +617,8 @@ Connection objects The number of arguments that the ``step()`` method must accept is controlled by *n_arg*. - Set to :const:`None` to remove an existing SQL aggregate function. - :type aggregate_class: :term:`class` | :const:`None` + Set to ``None`` to remove an existing SQL aggregate function. + :type aggregate_class: :term:`class` | None Example: @@ -650,13 +650,13 @@ Connection objects The number of arguments that the ``step()`` and ``value()`` methods must accept is controlled by *num_params*. - Set to :const:`None` to remove an existing SQL aggregate window function. + Set to ``None`` to remove an existing SQL aggregate window function. :raises NotSupportedError: If used with a version of SQLite older than 3.25.0, which does not support aggregate window functions. - :type aggregate_class: :term:`class` | :const:`None` + :type aggregate_class: :term:`class` | None .. versionadded:: 3.11 @@ -679,7 +679,7 @@ Connection objects .. literalinclude:: ../includes/sqlite3/collation_reverse.py - Remove a collation function by setting *callable* to :const:`None`. + Remove a collation function by setting *callable* to ``None``. .. versionchanged:: 3.11 The collation name can contain any Unicode character. Earlier, only @@ -703,20 +703,20 @@ Connection objects :mod:`sqlite3` module. The first argument to the callback signifies what kind of operation is to be - authorized. The second and third argument will be arguments or :const:`None` + authorized. The second and third argument will be arguments or ``None`` depending on the first argument. The 4th argument is the name of the database ("main", "temp", etc.) if applicable. The 5th argument is the name of the inner-most trigger or view that is responsible for the access attempt or - :const:`None` if this access attempt is directly from input SQL code. + ``None`` if this access attempt is directly from input SQL code. Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first one. All necessary constants are available in the :mod:`sqlite3` module. - Passing :const:`None` as *authorizer_callback* will disable the authorizer. + Passing ``None`` as *authorizer_callback* will disable the authorizer. .. versionchanged:: 3.11 - Added support for disabling the authorizer using :const:`None`. + Added support for disabling the authorizer using ``None``. .. method:: set_progress_handler(progress_handler, n) @@ -727,7 +727,7 @@ Connection objects a GUI. If you want to clear any previously installed progress handler, call the - method with :const:`None` for *progress_handler*. + method with ``None`` for *progress_handler*. Returning a non-zero value from the handler function will terminate the currently executing query and cause it to raise a :exc:`DatabaseError` @@ -747,7 +747,7 @@ Connection objects sqlite3 module and the execution of triggers defined in the current database. - Passing :const:`None` as *trace_callback* will disable the trace callback. + Passing ``None`` as *trace_callback* will disable the trace callback. .. note:: Exceptions raised in the trace callback are not propagated. As a @@ -761,7 +761,7 @@ Connection objects .. method:: enable_load_extension(enabled, /) Enable the SQLite engine to load SQLite extensions from shared libraries - if *enabled* is :const:`True`; + if *enabled* is ``True``; else, disallow loading SQLite extensions. SQLite extensions can define new functions, aggregates or whole new virtual table implementations. One well-known @@ -879,8 +879,8 @@ Connection objects the *status* of the last iteration, the *remaining* number of pages still to be copied, and the *total* number of pages. - Defaults to :const:`None`. - :type progress: :term:`callback` |?:const:`None` + Defaults to ``None``. + :type progress: :term:`callback` |?None :param name: The name of the database to back up. @@ -1034,7 +1034,7 @@ Cursor objects :meth:`executescript` if you want to execute multiple SQL statements with one call. - If :attr:`~Connection.isolation_level` is not :const:`None`, + If :attr:`~Connection.isolation_level` is not ``None``, *sql* is an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement, and there is no open transaction, a transaction is implicitly opened before executing *sql*. @@ -1082,7 +1082,7 @@ Cursor objects .. method:: fetchone() Fetch the next row of a query result set as a :class:`tuple`. - Return :const:`None` if no more data is available. + Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) @@ -1138,7 +1138,7 @@ Cursor objects using the :meth:`execute` method. For other statements, after :meth:`executemany` or :meth:`executescript`, or if the insertion failed, the value of ``lastrowid`` is left unchanged. The initial value of - ``lastrowid`` is :const:`None`. + ``lastrowid`` is ``None``. .. note:: Inserts into ``WITHOUT ROWID`` tables are not recorded. @@ -1155,7 +1155,7 @@ Cursor objects Read-only attribute that provides the column names of the last query. To remain compatible with the Python DB API, it returns a 7-tuple for each - column where the last six items of each tuple are :const:`None`. + column where the last six items of each tuple are ``None``. It is set for ``SELECT`` statements without any matching rows as well. @@ -1388,7 +1388,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Exception raised in case a method or database API is not supported by the underlying SQLite library. For example, setting *deterministic* to - :const:`True` in :meth:`~Connection.create_function`, if the underlying SQLite library + ``True`` in :meth:`~Connection.create_function`, if the underlying SQLite library does not support deterministic functions. ``NotSupportedError`` is a subclass of :exc:`DatabaseError`. @@ -1406,7 +1406,7 @@ The following Python types can thus be sent to SQLite without any problem: +-------------------------------+-------------+ | Python type | SQLite type | +===============================+=============+ -| :const:`None` | ``NULL`` | +| ``None`` | ``NULL`` | +-------------------------------+-------------+ | :class:`int` | ``INTEGER`` | +-------------------------------+-------------+ @@ -1423,7 +1423,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ | SQLite type | Python type | +=============+==============================================+ -| ``NULL`` | :const:`None` | +| ``NULL`` | ``None`` | +-------------+----------------------------------------------+ | ``INTEGER`` | :class:`int` | +-------------+----------------------------------------------+ @@ -1736,7 +1736,7 @@ The ``sqlite3`` module does not adhere to the transaction handling recommended by :pep:`249`. If the connection attribute :attr:`~Connection.isolation_level` -is not :const:`None`, +is not ``None``, new transactions are implicitly opened before :meth:`~Cursor.execute` and :meth:`~Cursor.executemany` executes ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statements. @@ -1747,7 +1747,7 @@ that is, whether and what type of ``BEGIN`` statements ``sqlite3`` implicitly executes ? via the :attr:`~Connection.isolation_level` attribute. -If :attr:`~Connection.isolation_level` is set to :const:`None`, +If :attr:`~Connection.isolation_level` is set to ``None``, no transactions are implicitly opened at all. This leaves the underlying SQLite library in `autocommit mode`_, but also allows the user to perform their own transaction handling From webhook-mailer at python.org Wed Aug 3 16:29:00 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 20:29:00 -0000 Subject: [Python-checkins] gh-95273: Align sqlite3 const doc refs with the devguide recommendations (GH-95525) Message-ID: <mailman.450.1659558542.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8d096260668b97fcfdc3b17e36074162505b3212 commit: 8d096260668b97fcfdc3b17e36074162505b3212 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T13:28:38-07:00 summary: gh-95273: Align sqlite3 const doc refs with the devguide recommendations (GH-95525) (cherry picked from commit 4d02572f8c39b16c83c0883917db4e31efc1048e) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e150baad3ef..892daf1660c 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -312,13 +312,13 @@ Module functions and constants The :attr:`~Connection.isolation_level` of the connection, controlling whether and how transactions are implicitly opened. Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``; - or :const:`None` to disable opening transactions implicitly. + or ``None`` to disable opening transactions implicitly. See :ref:`sqlite3-controlling-transactions` for more. - :type isolation_level: str | :const:`None` + :type isolation_level: str | None :param check_same_thread: - If :const:`True` (default), only the creating thread may use the connection. - If :const:`False`, the connection may be shared across multiple threads; + If ``True`` (default), only the creating thread may use the connection. + If ``False``, the connection may be shared across multiple threads; if so, write operations should be serialized by the user to avoid data corruption. :type check_same_thread: bool @@ -335,7 +335,7 @@ Module functions and constants :type cached_statements: int :param uri: - If set to :const:`True`, *database* is interpreted as a + If set to ``True``, *database* is interpreted as a :abbr:`URI (Uniform Resource Identifier)` with a file path and an optional query string. The scheme part *must* be ``"file:"``, @@ -384,7 +384,7 @@ Module functions and constants .. function:: complete_statement(statement) - Returns :const:`True` if the string *statement* contains one or more complete SQL + Returns ``True`` if the string *statement* contains one or more complete SQL statements terminated by semicolons. It does not verify that the SQL is syntactically correct, only that there are no unclosed string literals and the statement is terminated by a semicolon. @@ -400,8 +400,8 @@ Module functions and constants Enable or disable callback tracebacks. By default you will not get any tracebacks in user-defined functions, aggregates, converters, authorizer callbacks etc. If you want to debug them, - you can call this function with *flag* set to :const:`True`. Afterwards, you - will get tracebacks from callbacks on :data:`sys.stderr`. Use :const:`False` + you can call this function with *flag* set to ``True``. Afterwards, you + will get tracebacks from callbacks on :data:`sys.stderr`. Use ``False`` to disable the feature again. Register an :func:`unraisable hook handler <sys.unraisablehook>` for an @@ -446,7 +446,7 @@ Connection objects This attribute controls the :ref:`transaction handling <sqlite3-controlling-transactions>` performed by ``sqlite3``. - If set to :const:`None`, transactions are never implicitly opened. + If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, implicit :ref:`transaction management @@ -460,8 +460,8 @@ Connection objects This read-only attribute corresponds to the low-level SQLite `autocommit mode`_. - :const:`True` if a transaction is active (there are uncommitted changes), - :const:`False` otherwise. + ``True`` if a transaction is active (there are uncommitted changes), + ``False`` otherwise. .. versionadded:: 3.2 @@ -490,9 +490,9 @@ Connection objects :type row: str :param readonly: - Set to :const:`True` if the blob should be opened without write + Set to ``True`` if the blob should be opened without write permissions. - Defaults to :const:`False`. + Defaults to ``False``. :type readonly: bool :param name: @@ -564,11 +564,11 @@ Connection objects A callable that is called when the SQL function is invoked. The callable must return :ref:`a type natively supported by SQLite <sqlite3-types>`. - Set to :const:`None` to remove an existing SQL function. - :type func: :term:`callback` | :const:`None` + Set to ``None`` to remove an existing SQL function. + :type func: :term:`callback` | None :param deterministic: - If :const:`True`, the created SQL function is marked as + If ``True``, the created SQL function is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which allows SQLite to perform additional optimizations. :type deterministic: bool @@ -607,8 +607,8 @@ Connection objects The number of arguments that the ``step()`` method must accept is controlled by *n_arg*. - Set to :const:`None` to remove an existing SQL aggregate function. - :type aggregate_class: :term:`class` | :const:`None` + Set to ``None`` to remove an existing SQL aggregate function. + :type aggregate_class: :term:`class` | None Example: @@ -640,13 +640,13 @@ Connection objects The number of arguments that the ``step()`` and ``value()`` methods must accept is controlled by *num_params*. - Set to :const:`None` to remove an existing SQL aggregate window function. + Set to ``None`` to remove an existing SQL aggregate window function. :raises NotSupportedError: If used with a version of SQLite older than 3.25.0, which does not support aggregate window functions. - :type aggregate_class: :term:`class` | :const:`None` + :type aggregate_class: :term:`class` | None .. versionadded:: 3.11 @@ -669,7 +669,7 @@ Connection objects .. literalinclude:: ../includes/sqlite3/collation_reverse.py - Remove a collation function by setting *callable* to :const:`None`. + Remove a collation function by setting *callable* to ``None``. .. versionchanged:: 3.11 The collation name can contain any Unicode character. Earlier, only @@ -693,20 +693,20 @@ Connection objects :mod:`sqlite3` module. The first argument to the callback signifies what kind of operation is to be - authorized. The second and third argument will be arguments or :const:`None` + authorized. The second and third argument will be arguments or ``None`` depending on the first argument. The 4th argument is the name of the database ("main", "temp", etc.) if applicable. The 5th argument is the name of the inner-most trigger or view that is responsible for the access attempt or - :const:`None` if this access attempt is directly from input SQL code. + ``None`` if this access attempt is directly from input SQL code. Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first one. All necessary constants are available in the :mod:`sqlite3` module. - Passing :const:`None` as *authorizer_callback* will disable the authorizer. + Passing ``None`` as *authorizer_callback* will disable the authorizer. .. versionchanged:: 3.11 - Added support for disabling the authorizer using :const:`None`. + Added support for disabling the authorizer using ``None``. .. method:: set_progress_handler(progress_handler, n) @@ -717,7 +717,7 @@ Connection objects a GUI. If you want to clear any previously installed progress handler, call the - method with :const:`None` for *progress_handler*. + method with ``None`` for *progress_handler*. Returning a non-zero value from the handler function will terminate the currently executing query and cause it to raise an :exc:`OperationalError` @@ -737,7 +737,7 @@ Connection objects sqlite3 module and the execution of triggers defined in the current database. - Passing :const:`None` as *trace_callback* will disable the trace callback. + Passing ``None`` as *trace_callback* will disable the trace callback. .. note:: Exceptions raised in the trace callback are not propagated. As a @@ -751,7 +751,7 @@ Connection objects .. method:: enable_load_extension(enabled, /) Enable the SQLite engine to load SQLite extensions from shared libraries - if *enabled* is :const:`True`; + if *enabled* is ``True``; else, disallow loading SQLite extensions. SQLite extensions can define new functions, aggregates or whole new virtual table implementations. One well-known @@ -869,8 +869,8 @@ Connection objects the *status* of the last iteration, the *remaining* number of pages still to be copied, and the *total* number of pages. - Defaults to :const:`None`. - :type progress: :term:`callback` |?:const:`None` + Defaults to ``None``. + :type progress: :term:`callback` |?None :param name: The name of the database to back up. @@ -1024,7 +1024,7 @@ Cursor objects :meth:`executescript` if you want to execute multiple SQL statements with one call. - If :attr:`~Connection.isolation_level` is not :const:`None`, + If :attr:`~Connection.isolation_level` is not ``None``, *sql* is an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement, and there is no open transaction, a transaction is implicitly opened before executing *sql*. @@ -1072,7 +1072,7 @@ Cursor objects .. method:: fetchone() Fetch the next row of a query result set as a :class:`tuple`. - Return :const:`None` if no more data is available. + Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) @@ -1128,7 +1128,7 @@ Cursor objects using the :meth:`execute` method. For other statements, after :meth:`executemany` or :meth:`executescript`, or if the insertion failed, the value of ``lastrowid`` is left unchanged. The initial value of - ``lastrowid`` is :const:`None`. + ``lastrowid`` is ``None``. .. note:: Inserts into ``WITHOUT ROWID`` tables are not recorded. @@ -1145,7 +1145,7 @@ Cursor objects Read-only attribute that provides the column names of the last query. To remain compatible with the Python DB API, it returns a 7-tuple for each - column where the last six items of each tuple are :const:`None`. + column where the last six items of each tuple are ``None``. It is set for ``SELECT`` statements without any matching rows as well. @@ -1378,7 +1378,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Exception raised in case a method or database API is not supported by the underlying SQLite library. For example, setting *deterministic* to - :const:`True` in :meth:`~Connection.create_function`, if the underlying SQLite library + ``True`` in :meth:`~Connection.create_function`, if the underlying SQLite library does not support deterministic functions. ``NotSupportedError`` is a subclass of :exc:`DatabaseError`. @@ -1396,7 +1396,7 @@ The following Python types can thus be sent to SQLite without any problem: +-------------------------------+-------------+ | Python type | SQLite type | +===============================+=============+ -| :const:`None` | ``NULL`` | +| ``None`` | ``NULL`` | +-------------------------------+-------------+ | :class:`int` | ``INTEGER`` | +-------------------------------+-------------+ @@ -1413,7 +1413,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ | SQLite type | Python type | +=============+==============================================+ -| ``NULL`` | :const:`None` | +| ``NULL`` | ``None`` | +-------------+----------------------------------------------+ | ``INTEGER`` | :class:`int` | +-------------+----------------------------------------------+ @@ -1699,7 +1699,7 @@ The ``sqlite3`` module does not adhere to the transaction handling recommended by :pep:`249`. If the connection attribute :attr:`~Connection.isolation_level` -is not :const:`None`, +is not ``None``, new transactions are implicitly opened before :meth:`~Cursor.execute` and :meth:`~Cursor.executemany` executes ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statements. @@ -1710,7 +1710,7 @@ that is, whether and what type of ``BEGIN`` statements ``sqlite3`` implicitly executes ? via the :attr:`~Connection.isolation_level` attribute. -If :attr:`~Connection.isolation_level` is set to :const:`None`, +If :attr:`~Connection.isolation_level` is set to ``None``, no transactions are implicitly opened at all. This leaves the underlying SQLite library in `autocommit mode`_, but also allows the user to perform their own transaction handling From webhook-mailer at python.org Wed Aug 3 16:43:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 20:43:34 -0000 Subject: [Python-checkins] gh-91207: Fix CSS bug in Windows CHM help file and add deprecation message (GH-95607) Message-ID: <mailman.451.1659559415.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a591c4701ce707531775be8557a96376e7b57f8b commit: a591c4701ce707531775be8557a96376e7b57f8b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T13:43:14-07:00 summary: gh-91207: Fix CSS bug in Windows CHM help file and add deprecation message (GH-95607) (cherry picked from commit ac3bf6155f8addc62f9a9c48f07eef8c3a6f71b2) Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> files: A Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst M Doc/conf.py diff --git a/Doc/conf.py b/Doc/conf.py index 0c7deb59d13..2e670e5a856 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -74,6 +74,13 @@ 'root_include_title': False # We use the version switcher instead. } +# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207 +# https://github.com/python/cpython/issues/91207 +if any('htmlhelp' in arg for arg in sys.argv): + html_style = 'pydoctheme.css' + print("\nWARNING: Windows CHM Help is no longer supported.") + print("It may be removed in the future\n") + # Short title used e.g. for <title> HTML tags. html_short_title = '%s Documentation' % release diff --git a/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst b/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst new file mode 100644 index 00000000000..8c7391f7edf --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst @@ -0,0 +1,3 @@ +Fix stylesheet not working in Windows CHM htmlhelp docs +and add warning that they are deprecated. +Contributed by C.A.M. Gerlach. From webhook-mailer at python.org Wed Aug 3 16:55:16 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 03 Aug 2022 20:55:16 -0000 Subject: [Python-checkins] gh-95423: Update winreg.DeleteKeyEx documentation and remove dynamic function load (GH-95521) Message-ID: <mailman.452.1659560117.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ebd660156d80bbb17899ca393731da5548100fc1 commit: ebd660156d80bbb17899ca393731da5548100fc1 branch: main author: Derek Kim <ddkim1024 at gmail.com> committer: zooba <steve.dower at microsoft.com> date: 2022-08-03T21:55:03+01:00 summary: gh-95423: Update winreg.DeleteKeyEx documentation and remove dynamic function load (GH-95521) files: M Doc/library/winreg.rst M Misc/ACKS M PC/clinic/winreg.c.h M PC/winreg.c diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 487856a3ac6c..4ab671817710 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -144,12 +144,6 @@ This module offers the following functions: Deletes the specified key. - .. note:: - The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx - Windows API function, which is specific to 64-bit versions of Windows. - See the `RegDeleteKeyEx documentation - <https://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__. - *key* is an already open key, or one of the predefined :ref:`HKEY_* constants <hkey-constants>`. @@ -159,9 +153,10 @@ This module offers the following functions: *reserved* is a reserved integer, and must be zero. The default is zero. - *access* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_WOW64_64KEY`. See - :ref:`Access Rights <access-rights>` for other allowed values. + *access* is an integer that specifies an access mask that describes the + desired security access for the key. Default is :const:`KEY_WOW64_64KEY`. + On 32-bit Windows, the WOW64 constants are ignored. + See :ref:`Access Rights <access-rights>` for other allowed values. *This method can not delete keys with subkeys.* @@ -658,13 +653,12 @@ For more information, see `Accessing an Alternate Registry View .. data:: KEY_WOW64_64KEY Indicates that an application on 64-bit Windows should operate on - the 64-bit registry view. + the 64-bit registry view. On 32-bit Windows, this constant is ignored. .. data:: KEY_WOW64_32KEY Indicates that an application on 64-bit Windows should operate on - the 32-bit registry view. - + the 32-bit registry view. On 32-bit Windows, this constant is ignored. .. _value-types: diff --git a/Misc/ACKS b/Misc/ACKS index 32475f874c36..b18fabe09ef4 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -917,6 +917,7 @@ Sanyam Khurana Tyler Kieft Mads Kiilerich Jason Killen +Derek D. Kim Jan Kim Taek Joo Kim Sam Kimbrel diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 1e64b1eedeb3..7b0624919212 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -405,7 +405,7 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved=0)\n" "--\n" "\n" -"Deletes the specified key (64-bit OS only).\n" +"Deletes the specified key (intended for 64-bit OS).\n" "\n" " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" @@ -419,6 +419,9 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved\n" " A reserved integer, and must be zero. Default is zero.\n" "\n" +"While this function is intended to be used for 64-bit OS, it is also\n" +" available on 32-bit systems.\n" +"\n" "This method can not delete keys with subkeys.\n" "\n" "If the function succeeds, the entire key, including all of its values,\n" @@ -1455,4 +1458,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=504fc17ae25a7c75 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3faa63af6fd1653c input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index b326c3dfd2c7..6ae0d8169cc5 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -979,7 +979,9 @@ winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key) (Py_ssize_t)0) < 0) { return NULL; } - rc = RegDeleteKeyW(key, sub_key ); + Py_BEGIN_ALLOW_THREADS + rc = RegDeleteKeyW(key, sub_key); + Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); Py_RETURN_NONE; @@ -1000,7 +1002,10 @@ winreg.DeleteKeyEx reserved: int = 0 A reserved integer, and must be zero. Default is zero. -Deletes the specified key (64-bit OS only). +Deletes the specified key (intended for 64-bit OS). + +While this function is intended to be used for 64-bit OS, it is also + available on 32-bit systems. This method can not delete keys with subkeys. @@ -1013,34 +1018,17 @@ static PyObject * winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, REGSAM access, int reserved) -/*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/ +/*[clinic end generated code: output=52a1c8b374ebc003 input=a3186db079b3bf85]*/ { - HMODULE hMod; - typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int); - RDKEFunc pfn = NULL; long rc; - if (PySys_Audit("winreg.DeleteKey", "nun", (Py_ssize_t)key, sub_key, (Py_ssize_t)access) < 0) { return NULL; } - /* Only available on 64bit platforms, so we must load it - dynamically. */ Py_BEGIN_ALLOW_THREADS - hMod = GetModuleHandleW(L"advapi32.dll"); - if (hMod) - pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW"); + rc = RegDeleteKeyExW(key, sub_key, access, reserved); Py_END_ALLOW_THREADS - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(key, sub_key, access, reserved); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx"); Py_RETURN_NONE; From webhook-mailer at python.org Wed Aug 3 17:04:49 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 03 Aug 2022 21:04:49 -0000 Subject: [Python-checkins] [3.10] gh-95273: Align sqlite3 const doc refs with the devguide recommendations (GH-95525). (#95618) Message-ID: <mailman.453.1659560690.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ac005ea8606e34c71b9a6a84ff4fd5d688422bd0 commit: ac005ea8606e34c71b9a6a84ff4fd5d688422bd0 branch: 3.10 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-03T23:04:35+02:00 summary: [3.10] gh-95273: Align sqlite3 const doc refs with the devguide recommendations (GH-95525). (#95618) (cherry picked from commit 4d02572f8c39b16c83c0883917db4e31efc1048e) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 2b08040a00e..b1c8166a64b 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -294,13 +294,13 @@ Module functions and constants The :attr:`~Connection.isolation_level` of the connection, controlling whether and how transactions are implicitly opened. Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``; - or :const:`None` to disable opening transactions implicitly. + or ``None`` to disable opening transactions implicitly. See :ref:`sqlite3-controlling-transactions` for more. - :type isolation_level: str | :const:`None` + :type isolation_level: str | None :param check_same_thread: - If :const:`True` (default), only the creating thread may use the connection. - If :const:`False`, the connection may be shared across multiple threads; + If ``True`` (default), only the creating thread may use the connection. + If ``False``, the connection may be shared across multiple threads; if so, write operations should be serialized by the user to avoid data corruption. :type check_same_thread: bool @@ -317,7 +317,7 @@ Module functions and constants :type cached_statements: int :param uri: - If set to :const:`True`, *database* is interpreted as a + If set to ``True``, *database* is interpreted as a :abbr:`URI (Uniform Resource Identifier)` with a file path and an optional query string. The scheme part *must* be ``"file:"``, @@ -366,7 +366,7 @@ Module functions and constants .. function:: complete_statement(statement) - Returns :const:`True` if the string *statement* contains one or more complete SQL + Returns ``True`` if the string *statement* contains one or more complete SQL statements terminated by semicolons. It does not verify that the SQL is syntactically correct, only that there are no unclosed string literals and the statement is terminated by a semicolon. @@ -383,7 +383,7 @@ Module functions and constants By default you will not get any tracebacks in user-defined functions, aggregates, converters, authorizer callbacks etc. If you want to debug them, you can call this function with *flag* set to ``True``. Afterwards, you will - get tracebacks from callbacks on ``sys.stderr``. Use :const:`False` to + get tracebacks from callbacks on ``sys.stderr``. Use ``False`` to disable the feature again. @@ -410,7 +410,7 @@ Connection objects This attribute controls the :ref:`transaction handling <sqlite3-controlling-transactions>` performed by ``sqlite3``. - If set to :const:`None`, transactions are never implicitly opened. + If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, implicit :ref:`transaction management @@ -424,8 +424,8 @@ Connection objects This read-only attribute corresponds to the low-level SQLite `autocommit mode`_. - :const:`True` if a transaction is active (there are uncommitted changes), - :const:`False` otherwise. + ``True`` if a transaction is active (there are uncommitted changes), + ``False`` otherwise. .. versionadded:: 3.2 @@ -488,11 +488,11 @@ Connection objects A callable that is called when the SQL function is invoked. The callable must return :ref:`a type natively supported by SQLite <sqlite3-types>`. - Set to :const:`None` to remove an existing SQL function. - :type func: :term:`callback` | :const:`None` + Set to ``None`` to remove an existing SQL function. + :type func: :term:`callback` | None :param deterministic: - If :const:`True`, the created SQL function is marked as + If ``True``, the created SQL function is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which allows SQLite to perform additional optimizations. :type deterministic: bool @@ -531,8 +531,8 @@ Connection objects The number of arguments that the ``step()`` method must accept is controlled by *n_arg*. - Set to :const:`None` to remove an existing SQL aggregate function. - :type aggregate_class: :term:`class` | :const:`None` + Set to ``None`` to remove an existing SQL aggregate function. + :type aggregate_class: :term:`class` | None Example: @@ -553,7 +553,7 @@ Connection objects .. literalinclude:: ../includes/sqlite3/collation_reverse.py - Remove a collation function by setting *callable* to :const:`None`. + Remove a collation function by setting *callable* to ``None``. .. method:: interrupt() @@ -573,11 +573,11 @@ Connection objects :mod:`sqlite3` module. The first argument to the callback signifies what kind of operation is to be - authorized. The second and third argument will be arguments or :const:`None` + authorized. The second and third argument will be arguments or ``None`` depending on the first argument. The 4th argument is the name of the database ("main", "temp", etc.) if applicable. The 5th argument is the name of the inner-most trigger or view that is responsible for the access attempt or - :const:`None` if this access attempt is directly from input SQL code. + ``None`` if this access attempt is directly from input SQL code. Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first @@ -592,7 +592,7 @@ Connection objects a GUI. If you want to clear any previously installed progress handler, call the - method with :const:`None` for *progress_handler*. + method with ``None`` for *progress_handler*. Returning a non-zero value from the handler function will terminate the currently executing query and cause it to raise an :exc:`OperationalError` @@ -612,7 +612,7 @@ Connection objects sqlite3 module and the execution of triggers defined in the current database. - Passing :const:`None` as *trace_callback* will disable the trace callback. + Passing ``None`` as *trace_callback* will disable the trace callback. .. note:: Exceptions raised in the trace callback are not propagated. As a @@ -626,7 +626,7 @@ Connection objects .. method:: enable_load_extension(enabled, /) Enable the SQLite engine to load SQLite extensions from shared libraries - if *enabled* is :const:`True`; + if *enabled* is ``True``; else, disallow loading SQLite extensions. SQLite extensions can define new functions, aggregates or whole new virtual table implementations. One well-known @@ -744,8 +744,8 @@ Connection objects the *status* of the last iteration, the *remaining* number of pages still to be copied, and the *total* number of pages. - Defaults to :const:`None`. - :type progress: :term:`callback` |?:const:`None` + Defaults to ``None``. + :type progress: :term:`callback` |?None :param name: The name of the database to back up. @@ -825,7 +825,7 @@ Cursor objects :meth:`executescript` if you want to execute multiple SQL statements with one call. - If :attr:`~Connection.isolation_level` is not :const:`None`, + If :attr:`~Connection.isolation_level` is not ``None``, *sql* is an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement, and there is no open transaction, a transaction is implicitly opened before executing *sql*. @@ -873,7 +873,7 @@ Cursor objects .. method:: fetchone() Fetch the next row of a query result set as a :class:`tuple`. - Return :const:`None` if no more data is available. + Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) @@ -929,7 +929,7 @@ Cursor objects using the :meth:`execute` method. For other statements, after :meth:`executemany` or :meth:`executescript`, or if the insertion failed, the value of ``lastrowid`` is left unchanged. The initial value of - ``lastrowid`` is :const:`None`. + ``lastrowid`` is ``None``. .. note:: Inserts into ``WITHOUT ROWID`` tables are not recorded. @@ -946,7 +946,7 @@ Cursor objects Read-only attribute that provides the column names of the last query. To remain compatible with the Python DB API, it returns a 7-tuple for each - column where the last six items of each tuple are :const:`None`. + column where the last six items of each tuple are ``None``. It is set for ``SELECT`` statements without any matching rows as well. @@ -1107,7 +1107,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Exception raised in case a method or database API is not supported by the underlying SQLite library. For example, setting *deterministic* to - :const:`True` in :meth:`~Connection.create_function`, if the underlying SQLite library + ``True`` in :meth:`~Connection.create_function`, if the underlying SQLite library does not support deterministic functions. ``NotSupportedError`` is a subclass of :exc:`DatabaseError`. @@ -1125,7 +1125,7 @@ The following Python types can thus be sent to SQLite without any problem: +-------------------------------+-------------+ | Python type | SQLite type | +===============================+=============+ -| :const:`None` | ``NULL`` | +| ``None`` | ``NULL`` | +-------------------------------+-------------+ | :class:`int` | ``INTEGER`` | +-------------------------------+-------------+ @@ -1142,7 +1142,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ | SQLite type | Python type | +=============+==============================================+ -| ``NULL`` | :const:`None` | +| ``NULL`` | ``None`` | +-------------+----------------------------------------------+ | ``INTEGER`` | :class:`int` | +-------------+----------------------------------------------+ @@ -1428,7 +1428,7 @@ The ``sqlite3`` module does not adhere to the transaction handling recommended by :pep:`249`. If the connection attribute :attr:`~Connection.isolation_level` -is not :const:`None`, +is not ``None``, new transactions are implicitly opened before :meth:`~Cursor.execute` and :meth:`~Cursor.executemany` executes ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statements. @@ -1439,7 +1439,7 @@ that is, whether and what type of ``BEGIN`` statements ``sqlite3`` implicitly executes ? via the :attr:`~Connection.isolation_level` attribute. -If :attr:`~Connection.isolation_level` is set to :const:`None`, +If :attr:`~Connection.isolation_level` is set to ``None``, no transactions are implicitly opened at all. This leaves the underlying SQLite library in `autocommit mode`_, but also allows the user to perform their own transaction handling From webhook-mailer at python.org Wed Aug 3 17:11:27 2022 From: webhook-mailer at python.org (ethanfurman) Date: Wed, 03 Aug 2022 21:11:27 -0000 Subject: [Python-checkins] [Enum] add whatsnew entries (GH-95455) Message-ID: <mailman.454.1659561088.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6bde34000d70dfefafa71e54c8cb5672f423073c commit: 6bde34000d70dfefafa71e54c8cb5672f423073c branch: main author: Ethan Furman <ethan at stoneleaf.us> committer: ethanfurman <ethan at stoneleaf.us> date: 2022-08-03T14:11:20-07:00 summary: [Enum] add whatsnew entries (GH-95455) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 1b3a685dbac..d10d9f15a5f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -471,6 +471,49 @@ datetime formats (barring only those that support fractional hours and minutes). (Contributed by Paul Ganssle in :gh:`80010`.) +enum +---- + +* ``EnumMeta`` renamed to ``EnumType`` (``EnumMeta`` kept as alias). + +* ``StrEnum`` added -- enum members are and must be strings. + +* ``ReprEnum`` added -- causes only the ``__repr__`` to be modified, not the + ``__str__`` nor the ``__format__``. + +* ``FlagBoundary`` added -- controls behavior when invalid values are given to + a flag. + +* ``EnumCheck`` added -- used by ``verify`` to ensure various constraints. + +* ``verify`` added -- function to ensure given ``EnumCheck`` constraints. + +* ``member`` added -- decorator to ensure given object is converted to an enum + member. + +* ``nonmember`` added -- decorator to ensure given object is not converted to + an enum member. + +* ``property`` added -- use instead of ``types.DynamicClassAttribute``. + +* ``global_enum`` added -- enum decorator to adjust ``__repr__`` and ``__str__`` + to show members in the global context -- see ``re.RegexFlag`` for an example. + +* ``Flag`` enhancements: members support length, iteration, and containment + checks. + +* ``Enum``/``Flag`` fixes: members are now defined before ``__init_subclass__`` + is called; ``dir()`` now includes methods, etc., from mixed-in data types. + +* ``Flag`` fixes: only primary values (power of two) are considered canonical + while composite values (3, 6, 10, etc.) are considered aliases; inverted + flags are coerced to their positive equivalent. + +* ``IntEnum`` / ``IntFlag`` / ``StrEnum`` fixes: these now inherit from + ``ReprEnum`` so the ``str()`` output now matches ``format()`` output, + which is the data types' (so both ``str(AnIntEnum.ONE)`` and + ``format(AnIntEnum.ONE)`` is equal to ``'1'``). + fractions --------- From webhook-mailer at python.org Wed Aug 3 17:16:28 2022 From: webhook-mailer at python.org (terryjreedy) Date: Wed, 03 Aug 2022 21:16:28 -0000 Subject: [Python-checkins] gh-95597: Fix typo in Lib directory files (#95599) Message-ID: <mailman.455.1659561390.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b53aed76d26419fc7449c358c6035c9afe055e16 commit: b53aed76d26419fc7449c358c6035c9afe055e16 branch: main author: Jo, Yunjin <black33jo at gmail.com> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-03T17:16:15-04:00 summary: gh-95597: Fix typo in Lib directory files (#95599) files: M Lib/idlelib/config.py M Lib/test/test_asyncio/test_unix_events.py diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 5ce5f4a4f7bd..2b09d79470b4 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -578,7 +578,7 @@ def IsCoreBinding(self, virtualEvent): """ return ('<<'+virtualEvent+'>>') in self.GetCoreKeys() -# TODO make keyBindins a file or class attribute used for test above +# TODO make keyBindings a file or class attribute used for test above # and copied in function below. former_extension_events = { # Those with user-configurable keys. diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 9918165909f7..5bad21ecbae4 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1531,7 +1531,7 @@ def test_sigchld_child_reaped_elsewhere(self, m_waitpid): self.watcher._sig_chld() if isinstance(self.watcher, asyncio.FastChildWatcher): - # here the FastChildWatche enters a deadlock + # here the FastChildWatcher enters a deadlock # (there is no way to prevent it) self.assertFalse(callback.called) else: From webhook-mailer at python.org Wed Aug 3 17:19:06 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 03 Aug 2022 21:19:06 -0000 Subject: [Python-checkins] gh-94399: Restore PATH search behaviour of py.exe launcher for '/usr/bin/env' shebang lines (GH-95582) Message-ID: <mailman.456.1659561547.3313.python-checkins@python.org> https://github.com/python/cpython/commit/67840edb2851c6d4ca65d8389327d8a6dc06255a commit: 67840edb2851c6d4ca65d8389327d8a6dc06255a branch: main author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-03T22:18:51+01:00 summary: gh-94399: Restore PATH search behaviour of py.exe launcher for '/usr/bin/env' shebang lines (GH-95582) files: A Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst M Doc/using/windows.rst M Lib/test/test_launcher.py M PC/launcher2.c diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 2db73c8c5b9c..a289435a2f51 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -868,6 +868,11 @@ The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the executable :envvar:`PATH` for a Python executable. This corresponds to the behaviour of the Unix ``env`` program, which performs a :envvar:`PATH` search. +If an executable matching the first argument after the ``env`` command cannot +be found, it will be handled as described below. Additionally, the environment +variable :envvar:`PYLAUNCHER_NO_SEARCH_PATH` may be set (to any value) to skip +this additional search. + Arguments in shebang lines -------------------------- diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index c8ea4f62170e..835a51e3b6e0 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -187,6 +187,11 @@ def find_py(cls): ) return py_exe + def get_py_exe(self): + if not self.py_exe: + self.py_exe = self.find_py() + return self.py_exe + def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=None): if not self.py_exe: self.py_exe = self.find_py() @@ -194,9 +199,9 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non ignore = {"VIRTUAL_ENV", "PY_PYTHON", "PY_PYTHON2", "PY_PYTHON3"} env = { **{k.upper(): v for k, v in os.environ.items() if k.upper() not in ignore}, - **{k.upper(): v for k, v in (env or {}).items()}, "PYLAUNCHER_DEBUG": "1", "PYLAUNCHER_DRYRUN": "1", + **{k.upper(): v for k, v in (env or {}).items()}, } if not argv: argv = [self.py_exe, *args] @@ -496,7 +501,7 @@ def test_virtualenv_with_env(self): def test_py_shebang(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python -prearg") as script: + with self.script("#! /usr/bin/python -prearg") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) @@ -504,7 +509,7 @@ def test_py_shebang(self): def test_py2_shebang(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python2 -prearg") as script: + with self.script("#! /usr/bin/python2 -prearg") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-32", data["SearchInfo.tag"]) @@ -512,7 +517,7 @@ def test_py2_shebang(self): def test_py3_shebang(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python3 -prearg") as script: + with self.script("#! /usr/bin/python3 -prearg") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) @@ -520,7 +525,7 @@ def test_py3_shebang(self): def test_py_shebang_nl(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python -prearg\n") as script: + with self.script("#! /usr/bin/python -prearg\n") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) @@ -528,7 +533,7 @@ def test_py_shebang_nl(self): def test_py2_shebang_nl(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python2 -prearg\n") as script: + with self.script("#! /usr/bin/python2 -prearg\n") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-32", data["SearchInfo.tag"]) @@ -536,7 +541,7 @@ def test_py2_shebang_nl(self): def test_py3_shebang_nl(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python3 -prearg\n") as script: + with self.script("#! /usr/bin/python3 -prearg\n") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) @@ -544,13 +549,45 @@ def test_py3_shebang_nl(self): def test_py_shebang_short_argv0(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python -prearg") as script: + with self.script("#! /usr/bin/python -prearg") as script: # Override argv to only pass "py.exe" as the command data = self.run_py([script, "-postarg"], argv=f'"py.exe" "{script}" -postarg') self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) self.assertEqual(f'X.Y.exe -prearg "{script}" -postarg', data["stdout"].strip()) + def test_search_path(self): + stem = Path(sys.executable).stem + with self.py_ini(TEST_PY_COMMANDS): + with self.script(f"#! /usr/bin/env {stem} -prearg") as script: + data = self.run_py( + [script, "-postarg"], + env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, + ) + self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) + + def test_search_path_exe(self): + # Leave the .exe on the name to ensure we don't add it a second time + name = Path(sys.executable).name + with self.py_ini(TEST_PY_COMMANDS): + with self.script(f"#! /usr/bin/env {name} -prearg") as script: + data = self.run_py( + [script, "-postarg"], + env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, + ) + self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) + + def test_recursive_search_path(self): + stem = self.get_py_exe().stem + with self.py_ini(TEST_PY_COMMANDS): + with self.script(f"#! /usr/bin/env {stem}") as script: + data = self.run_py( + [script], + env={"PATH": f"{self.get_py_exe().parent};{os.getenv('PATH')}"}, + ) + # The recursive search is ignored and we get normal "py" behavior + self.assertEqual(f"X.Y.exe {script}", data["stdout"].strip()) + def test_install(self): data = self.run_py(["-V:3.10"], env={"PYLAUNCHER_ALWAYS_INSTALL": "1"}, expect_returncode=111) cmd = data["stdout"].strip() diff --git a/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst b/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst new file mode 100644 index 000000000000..a49e99ca2665 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst @@ -0,0 +1,3 @@ +Restores the behaviour of :ref:`launcher` for ``/usr/bin/env`` shebang +lines, which will now search :envvar:`PATH` for an executable matching the +given command. If none is found, the usual search process is used. diff --git a/PC/launcher2.c b/PC/launcher2.c index 033218ee2f40..a5dfd25f7d52 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -36,6 +36,7 @@ #define RC_DUPLICATE_ITEM 110 #define RC_INSTALLING 111 #define RC_NO_PYTHON_AT_ALL 112 +#define RC_NO_SHEBANG 113 static FILE * log_fp = NULL; @@ -750,6 +751,88 @@ _shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefi } +int +searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength) +{ + if (isEnvVarSet(L"PYLAUNCHER_NO_SEARCH_PATH")) { + return RC_NO_SHEBANG; + } + + wchar_t *command; + if (!_shebangStartsWith(shebang, shebangLength, L"/usr/bin/env ", &command)) { + return RC_NO_SHEBANG; + } + + wchar_t filename[MAXLEN]; + int lastDot = 0; + int commandLength = 0; + while (commandLength < MAXLEN && command[commandLength] && !isspace(command[commandLength])) { + if (command[commandLength] == L'.') { + lastDot = commandLength; + } + filename[commandLength] = command[commandLength]; + commandLength += 1; + } + + if (!commandLength || commandLength == MAXLEN) { + return RC_BAD_VIRTUAL_PATH; + } + + filename[commandLength] = L'\0'; + + const wchar_t *ext = L".exe"; + // If the command already has an extension, we do not want to add it again + if (!lastDot || _comparePath(&filename[lastDot], -1, ext, -1)) { + if (wcscat_s(filename, MAXLEN, L".exe")) { + return RC_BAD_VIRTUAL_PATH; + } + } + + wchar_t pathVariable[MAXLEN]; + int n = GetEnvironmentVariableW(L"PATH", pathVariable, MAXLEN); + if (!n) { + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + return RC_NO_SHEBANG; + } + winerror(0, L"Failed to read PATH\n", filename); + return RC_INTERNAL_ERROR; + } + + wchar_t buffer[MAXLEN]; + n = SearchPathW(pathVariable, filename, NULL, MAXLEN, buffer, NULL); + if (!n) { + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find %s on PATH\n", filename); + // If we didn't find it on PATH, let normal handling take over + return RC_NO_SHEBANG; + } + // Other errors should cause us to break + winerror(0, L"Failed to find %s on PATH\n", filename); + return RC_BAD_VIRTUAL_PATH; + } + + // Check that we aren't going to call ourselves again + // If we are, pretend there was no shebang and let normal handling take over + if (GetModuleFileNameW(NULL, filename, MAXLEN) && + 0 == _comparePath(filename, -1, buffer, -1)) { + debug(L"# ignoring recursive shebang command\n"); + return RC_NO_SHEBANG; + } + + wchar_t *buf = allocSearchInfoBuffer(search, n + 1); + if (!buf || wcscpy_s(buf, n + 1, buffer)) { + return RC_NO_MEMORY; + } + + search->executablePath = buf; + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Found %s on PATH\n", buf); + + return 0; +} + + int _readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, int bufferLength) { @@ -885,6 +968,12 @@ checkShebang(SearchInfo *search) } debug(L"Shebang: %s\n", shebang); + // Handle shebangs that we should search PATH for + exitCode = searchPath(search, shebang, shebangLength); + if (exitCode != RC_NO_SHEBANG) { + return exitCode; + } + // Handle some known, case-sensitive shebang templates const wchar_t *command; int commandLength; @@ -895,6 +984,7 @@ checkShebang(SearchInfo *search) L"", NULL }; + for (const wchar_t **tmpl = shebangTemplates; *tmpl; ++tmpl) { if (_shebangStartsWith(shebang, shebangLength, *tmpl, &command)) { commandLength = 0; @@ -910,6 +1000,22 @@ checkShebang(SearchInfo *search) } else if (_shebangStartsWith(command, commandLength, L"python", NULL)) { search->tag = &command[6]; search->tagLength = commandLength - 6; + // If we had 'python3.12.exe' then we want to strip the suffix + // off of the tag + if (search->tagLength > 4) { + const wchar_t *suffix = &search->tag[search->tagLength - 4]; + if (0 == _comparePath(suffix, 4, L".exe", -1)) { + search->tagLength -= 4; + } + } + // If we had 'python3_d' then we want to strip the '_d' (any + // '.exe' is already gone) + if (search->tagLength > 2) { + const wchar_t *suffix = &search->tag[search->tagLength - 2]; + if (0 == _comparePath(suffix, 2, L"_d", -1)) { + search->tagLength -= 2; + } + } search->oldStyleTag = true; search->executableArgs = &command[commandLength]; search->executableArgsLength = shebangLength - commandLength; From webhook-mailer at python.org Wed Aug 3 17:25:52 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 03 Aug 2022 21:25:52 -0000 Subject: [Python-checkins] gh-95423: Update winreg.DeleteKeyEx documentation and remove dynamic function load (GH-95521) Message-ID: <mailman.457.1659561953.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1016df0a23f185bb107d6ee0e4700c4f93f49042 commit: 1016df0a23f185bb107d6ee0e4700c4f93f49042 branch: 3.11 author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-03T22:25:47+01:00 summary: gh-95423: Update winreg.DeleteKeyEx documentation and remove dynamic function load (GH-95521) Co-authored-by: Derek Kim <ddkim1024 at gmail.com> files: M Doc/library/winreg.rst M Misc/ACKS M PC/clinic/winreg.c.h M PC/winreg.c diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 487856a3ac6..4ab67181771 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -144,12 +144,6 @@ This module offers the following functions: Deletes the specified key. - .. note:: - The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx - Windows API function, which is specific to 64-bit versions of Windows. - See the `RegDeleteKeyEx documentation - <https://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__. - *key* is an already open key, or one of the predefined :ref:`HKEY_* constants <hkey-constants>`. @@ -159,9 +153,10 @@ This module offers the following functions: *reserved* is a reserved integer, and must be zero. The default is zero. - *access* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_WOW64_64KEY`. See - :ref:`Access Rights <access-rights>` for other allowed values. + *access* is an integer that specifies an access mask that describes the + desired security access for the key. Default is :const:`KEY_WOW64_64KEY`. + On 32-bit Windows, the WOW64 constants are ignored. + See :ref:`Access Rights <access-rights>` for other allowed values. *This method can not delete keys with subkeys.* @@ -658,13 +653,12 @@ For more information, see `Accessing an Alternate Registry View .. data:: KEY_WOW64_64KEY Indicates that an application on 64-bit Windows should operate on - the 64-bit registry view. + the 64-bit registry view. On 32-bit Windows, this constant is ignored. .. data:: KEY_WOW64_32KEY Indicates that an application on 64-bit Windows should operate on - the 32-bit registry view. - + the 32-bit registry view. On 32-bit Windows, this constant is ignored. .. _value-types: diff --git a/Misc/ACKS b/Misc/ACKS index fdcc7ee514d..4beb4fd6b3d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -917,6 +917,7 @@ Sanyam Khurana Tyler Kieft Mads Kiilerich Jason Killen +Derek D. Kim Jan Kim Taek Joo Kim Sam Kimbrel diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 8bcb290ecd3..2507e46e263 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -390,7 +390,7 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved=0)\n" "--\n" "\n" -"Deletes the specified key (64-bit OS only).\n" +"Deletes the specified key (intended for 64-bit OS).\n" "\n" " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" @@ -404,6 +404,9 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved\n" " A reserved integer, and must be zero. Default is zero.\n" "\n" +"While this function is intended to be used for 64-bit OS, it is also\n" +" available on 32-bit systems.\n" +"\n" "This method can not delete keys with subkeys.\n" "\n" "If the function succeeds, the entire key, including all of its values,\n" @@ -1346,4 +1349,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=c3454803528f6e97 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7ad1db69bc42cab4 input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index 2d44c82000c..817717a50b3 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -991,7 +991,9 @@ winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key) (Py_ssize_t)0) < 0) { return NULL; } - rc = RegDeleteKeyW(key, sub_key ); + Py_BEGIN_ALLOW_THREADS + rc = RegDeleteKeyW(key, sub_key); + Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); Py_RETURN_NONE; @@ -1012,7 +1014,10 @@ winreg.DeleteKeyEx reserved: int = 0 A reserved integer, and must be zero. Default is zero. -Deletes the specified key (64-bit OS only). +Deletes the specified key (intended for 64-bit OS). + +While this function is intended to be used for 64-bit OS, it is also + available on 32-bit systems. This method can not delete keys with subkeys. @@ -1025,34 +1030,17 @@ static PyObject * winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, REGSAM access, int reserved) -/*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/ +/*[clinic end generated code: output=52a1c8b374ebc003 input=a3186db079b3bf85]*/ { - HMODULE hMod; - typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int); - RDKEFunc pfn = NULL; long rc; - if (PySys_Audit("winreg.DeleteKey", "nun", (Py_ssize_t)key, sub_key, (Py_ssize_t)access) < 0) { return NULL; } - /* Only available on 64bit platforms, so we must load it - dynamically. */ Py_BEGIN_ALLOW_THREADS - hMod = GetModuleHandleW(L"advapi32.dll"); - if (hMod) - pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW"); + rc = RegDeleteKeyExW(key, sub_key, access, reserved); Py_END_ALLOW_THREADS - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(key, sub_key, access, reserved); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx"); Py_RETURN_NONE; From webhook-mailer at python.org Wed Aug 3 17:43:11 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 21:43:11 -0000 Subject: [Python-checkins] gh-95597: Fix typo in Lib directory files (GH-95599) Message-ID: <mailman.458.1659562991.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1ed023b7c09efe339817f0a0effca6a605f5d0a3 commit: 1ed023b7c09efe339817f0a0effca6a605f5d0a3 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T14:43:01-07:00 summary: gh-95597: Fix typo in Lib directory files (GH-95599) (cherry picked from commit b53aed76d26419fc7449c358c6035c9afe055e16) Co-authored-by: Jo, Yunjin <black33jo at gmail.com> files: M Lib/idlelib/config.py M Lib/test/test_asyncio/test_unix_events.py diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 5ce5f4a4f7bd..2b09d79470b4 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -578,7 +578,7 @@ def IsCoreBinding(self, virtualEvent): """ return ('<<'+virtualEvent+'>>') in self.GetCoreKeys() -# TODO make keyBindins a file or class attribute used for test above +# TODO make keyBindings a file or class attribute used for test above # and copied in function below. former_extension_events = { # Those with user-configurable keys. diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 2f68459d30cd..1d922783ce3b 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1530,7 +1530,7 @@ def test_sigchld_child_reaped_elsewhere(self, m_waitpid): self.watcher._sig_chld() if isinstance(self.watcher, asyncio.FastChildWatcher): - # here the FastChildWatche enters a deadlock + # here the FastChildWatcher enters a deadlock # (there is no way to prevent it) self.assertFalse(callback.called) else: From webhook-mailer at python.org Wed Aug 3 17:47:27 2022 From: webhook-mailer at python.org (vstinner) Date: Wed, 03 Aug 2022 21:47:27 -0000 Subject: [Python-checkins] gh-90817: Use .. deprecated-removed:: when removal version known (#94960) Message-ID: <mailman.459.1659563249.3313.python-checkins@python.org> https://github.com/python/cpython/commit/dc2757accd8413abfc24d7acf06d8bf233d01534 commit: dc2757accd8413abfc24d7acf06d8bf233d01534 branch: main author: Hugo van Kemenade <hugovk at users.noreply.github.com> committer: vstinner <vstinner at python.org> date: 2022-08-03T23:47:20+02:00 summary: gh-90817: Use .. deprecated-removed:: when removal version known (#94960) files: M Doc/library/locale.rst diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 24270ed4b6d..5bb09b68ca1 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -301,7 +301,7 @@ The :mod:`locale` module defines the following exception and functions: *language code* and *encoding* may be ``None`` if their values cannot be determined. - .. deprecated:: 3.11 3.13 + .. deprecated-removed:: 3.11 3.13 .. function:: getlocale(category=LC_CTYPE) @@ -375,7 +375,7 @@ The :mod:`locale` module defines the following exception and functions: The default setting is determined by calling :func:`getdefaultlocale`. *category* defaults to :const:`LC_ALL`. - .. deprecated:: 3.11 3.13 + .. deprecated-removed:: 3.11 3.13 .. function:: strcoll(string1, string2) From webhook-mailer at python.org Wed Aug 3 17:50:20 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 21:50:20 -0000 Subject: [Python-checkins] gh-95597: Fix typo in Lib directory files (GH-95599) Message-ID: <mailman.460.1659563421.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f6c46b4852cbf351e3aaa67ce9edcfb17803562e commit: f6c46b4852cbf351e3aaa67ce9edcfb17803562e branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T14:50:10-07:00 summary: gh-95597: Fix typo in Lib directory files (GH-95599) (cherry picked from commit b53aed76d26419fc7449c358c6035c9afe055e16) Co-authored-by: Jo, Yunjin <black33jo at gmail.com> files: M Lib/idlelib/config.py M Lib/test/test_asyncio/test_unix_events.py diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 04444a3bf20b..376c6ee624d3 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -578,7 +578,7 @@ def IsCoreBinding(self, virtualEvent): """ return ('<<'+virtualEvent+'>>') in self.GetCoreKeys() -# TODO make keyBindins a file or class attribute used for test above +# TODO make keyBindings a file or class attribute used for test above # and copied in function below. former_extension_events = { # Those with user-configurable keys. diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 2f68459d30cd..1d922783ce3b 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1530,7 +1530,7 @@ def test_sigchld_child_reaped_elsewhere(self, m_waitpid): self.watcher._sig_chld() if isinstance(self.watcher, asyncio.FastChildWatcher): - # here the FastChildWatche enters a deadlock + # here the FastChildWatcher enters a deadlock # (there is no way to prevent it) self.assertFalse(callback.called) else: From webhook-mailer at python.org Wed Aug 3 17:52:19 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 03 Aug 2022 21:52:19 -0000 Subject: [Python-checkins] gh-95423: Update winreg.DeleteKeyEx documentation and remove dynamic function load (GH-95521) Message-ID: <mailman.461.1659563540.3313.python-checkins@python.org> https://github.com/python/cpython/commit/76d29a8ae81452291539ae39e791b0446e56d31b commit: 76d29a8ae81452291539ae39e791b0446e56d31b branch: 3.10 author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-03T22:52:15+01:00 summary: gh-95423: Update winreg.DeleteKeyEx documentation and remove dynamic function load (GH-95521) Co-authored-by: Derek Kim <ddkim1024 at gmail.com> files: M Doc/library/winreg.rst M Misc/ACKS M PC/clinic/winreg.c.h M PC/winreg.c diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 487856a3ac6c..4ab671817710 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -144,12 +144,6 @@ This module offers the following functions: Deletes the specified key. - .. note:: - The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx - Windows API function, which is specific to 64-bit versions of Windows. - See the `RegDeleteKeyEx documentation - <https://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx>`__. - *key* is an already open key, or one of the predefined :ref:`HKEY_* constants <hkey-constants>`. @@ -159,9 +153,10 @@ This module offers the following functions: *reserved* is a reserved integer, and must be zero. The default is zero. - *access* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_WOW64_64KEY`. See - :ref:`Access Rights <access-rights>` for other allowed values. + *access* is an integer that specifies an access mask that describes the + desired security access for the key. Default is :const:`KEY_WOW64_64KEY`. + On 32-bit Windows, the WOW64 constants are ignored. + See :ref:`Access Rights <access-rights>` for other allowed values. *This method can not delete keys with subkeys.* @@ -658,13 +653,12 @@ For more information, see `Accessing an Alternate Registry View .. data:: KEY_WOW64_64KEY Indicates that an application on 64-bit Windows should operate on - the 64-bit registry view. + the 64-bit registry view. On 32-bit Windows, this constant is ignored. .. data:: KEY_WOW64_32KEY Indicates that an application on 64-bit Windows should operate on - the 32-bit registry view. - + the 32-bit registry view. On 32-bit Windows, this constant is ignored. .. _value-types: diff --git a/Misc/ACKS b/Misc/ACKS index f356d029f327..8726c0f6e628 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -911,6 +911,7 @@ Sanyam Khurana Tyler Kieft Mads Kiilerich Jason Killen +Derek D. Kim Jan Kim Taek Joo Kim Sam Kimbrel diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 183301f06186..3051bcccf0db 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -390,7 +390,7 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved=0)\n" "--\n" "\n" -"Deletes the specified key (64-bit OS only).\n" +"Deletes the specified key (intended for 64-bit OS).\n" "\n" " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" @@ -404,6 +404,9 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved\n" " A reserved integer, and must be zero. Default is zero.\n" "\n" +"While this function is intended to be used for 64-bit OS, it is also\n" +" available on 32-bit systems.\n" +"\n" "This method can not delete keys with subkeys.\n" "\n" "If the function succeeds, the entire key, including all of its values,\n" @@ -1346,4 +1349,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=497a2e804821d5c9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8ce6fb3b6cd46242 input=a9049054013a1b77]*/ diff --git a/PC/winreg.c b/PC/winreg.c index 004a89a5355f..4fefcdcc942f 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -991,7 +991,9 @@ winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key) (Py_ssize_t)0) < 0) { return NULL; } - rc = RegDeleteKeyW(key, sub_key ); + Py_BEGIN_ALLOW_THREADS + rc = RegDeleteKeyW(key, sub_key); + Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); Py_RETURN_NONE; @@ -1012,7 +1014,10 @@ winreg.DeleteKeyEx reserved: int = 0 A reserved integer, and must be zero. Default is zero. -Deletes the specified key (64-bit OS only). +Deletes the specified key (intended for 64-bit OS). + +While this function is intended to be used for 64-bit OS, it is also + available on 32-bit systems. This method can not delete keys with subkeys. @@ -1025,34 +1030,17 @@ static PyObject * winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, REGSAM access, int reserved) -/*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/ +/*[clinic end generated code: output=52a1c8b374ebc003 input=a3186db079b3bf85]*/ { - HMODULE hMod; - typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int); - RDKEFunc pfn = NULL; long rc; - if (PySys_Audit("winreg.DeleteKey", "nun", (Py_ssize_t)key, sub_key, (Py_ssize_t)access) < 0) { return NULL; } - /* Only available on 64bit platforms, so we must load it - dynamically. */ Py_BEGIN_ALLOW_THREADS - hMod = GetModuleHandleW(L"advapi32.dll"); - if (hMod) - pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW"); + rc = RegDeleteKeyExW(key, sub_key, access, reserved); Py_END_ALLOW_THREADS - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(key, sub_key, access, reserved); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx"); Py_RETURN_NONE; From webhook-mailer at python.org Wed Aug 3 17:56:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 21:56:34 -0000 Subject: [Python-checkins] gh-90817: Use .. deprecated-removed:: when removal version known (GH-94960) Message-ID: <mailman.462.1659563795.3313.python-checkins@python.org> https://github.com/python/cpython/commit/450ee4f791a06b69398e812e74dfffd1edc12779 commit: 450ee4f791a06b69398e812e74dfffd1edc12779 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T14:56:16-07:00 summary: gh-90817: Use .. deprecated-removed:: when removal version known (GH-94960) (cherry picked from commit dc2757accd8413abfc24d7acf06d8bf233d01534) Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com> files: M Doc/library/locale.rst diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 112f0bae78d..6abad5ca5ad 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -301,7 +301,7 @@ The :mod:`locale` module defines the following exception and functions: *language code* and *encoding* may be ``None`` if their values cannot be determined. - .. deprecated:: 3.11 3.13 + .. deprecated-removed:: 3.11 3.13 .. function:: getlocale(category=LC_CTYPE) @@ -375,7 +375,7 @@ The :mod:`locale` module defines the following exception and functions: The default setting is determined by calling :func:`getdefaultlocale`. *category* defaults to :const:`LC_ALL`. - .. deprecated:: 3.11 3.13 + .. deprecated-removed:: 3.11 3.13 .. function:: strcoll(string1, string2) From webhook-mailer at python.org Wed Aug 3 18:01:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 22:01:18 -0000 Subject: [Python-checkins] gh-94399: Restore PATH search behaviour of py.exe launcher for '/usr/bin/env' shebang lines (GH-95582) Message-ID: <mailman.463.1659564080.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2c0017b5e610d196ccec125f8fb76bb746964a32 commit: 2c0017b5e610d196ccec125f8fb76bb746964a32 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T15:00:46-07:00 summary: gh-94399: Restore PATH search behaviour of py.exe launcher for '/usr/bin/env' shebang lines (GH-95582) (cherry picked from commit 67840edb2851c6d4ca65d8389327d8a6dc06255a) Co-authored-by: Steve Dower <steve.dower at python.org> files: A Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst M Doc/using/windows.rst M Lib/test/test_launcher.py M PC/launcher2.c diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 076679bdba6..210920d4f70 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -855,6 +855,11 @@ The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the executable :envvar:`PATH` for a Python executable. This corresponds to the behaviour of the Unix ``env`` program, which performs a :envvar:`PATH` search. +If an executable matching the first argument after the ``env`` command cannot +be found, it will be handled as described below. Additionally, the environment +variable :envvar:`PYLAUNCHER_NO_SEARCH_PATH` may be set (to any value) to skip +this additional search. + Arguments in shebang lines -------------------------- diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index e47078dc9f7..4ff84773727 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -188,6 +188,11 @@ def find_py(cls): ) return py_exe + def get_py_exe(self): + if not self.py_exe: + self.py_exe = self.find_py() + return self.py_exe + def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=None): if not self.py_exe: self.py_exe = self.find_py() @@ -195,9 +200,9 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non ignore = {"VIRTUAL_ENV", "PY_PYTHON", "PY_PYTHON2", "PY_PYTHON3"} env = { **{k.upper(): v for k, v in os.environ.items() if k.upper() not in ignore}, - **{k.upper(): v for k, v in (env or {}).items()}, "PYLAUNCHER_DEBUG": "1", "PYLAUNCHER_DRYRUN": "1", + **{k.upper(): v for k, v in (env or {}).items()}, } if not argv: argv = [self.py_exe, *args] @@ -497,7 +502,7 @@ def test_virtualenv_with_env(self): def test_py_shebang(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python -prearg") as script: + with self.script("#! /usr/bin/python -prearg") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) @@ -505,7 +510,7 @@ def test_py_shebang(self): def test_py2_shebang(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python2 -prearg") as script: + with self.script("#! /usr/bin/python2 -prearg") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-32", data["SearchInfo.tag"]) @@ -513,7 +518,7 @@ def test_py2_shebang(self): def test_py3_shebang(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python3 -prearg") as script: + with self.script("#! /usr/bin/python3 -prearg") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) @@ -521,7 +526,7 @@ def test_py3_shebang(self): def test_py_shebang_nl(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python -prearg\n") as script: + with self.script("#! /usr/bin/python -prearg\n") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) @@ -529,7 +534,7 @@ def test_py_shebang_nl(self): def test_py2_shebang_nl(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python2 -prearg\n") as script: + with self.script("#! /usr/bin/python2 -prearg\n") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-32", data["SearchInfo.tag"]) @@ -537,7 +542,7 @@ def test_py2_shebang_nl(self): def test_py3_shebang_nl(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python3 -prearg\n") as script: + with self.script("#! /usr/bin/python3 -prearg\n") as script: data = self.run_py([script, "-postarg"]) self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) @@ -545,13 +550,45 @@ def test_py3_shebang_nl(self): def test_py_shebang_short_argv0(self): with self.py_ini(TEST_PY_COMMANDS): - with self.script("#! /usr/bin/env python -prearg") as script: + with self.script("#! /usr/bin/python -prearg") as script: # Override argv to only pass "py.exe" as the command data = self.run_py([script, "-postarg"], argv=f'"py.exe" "{script}" -postarg') self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) self.assertEqual(f'X.Y.exe -prearg "{script}" -postarg', data["stdout"].strip()) + def test_search_path(self): + stem = Path(sys.executable).stem + with self.py_ini(TEST_PY_COMMANDS): + with self.script(f"#! /usr/bin/env {stem} -prearg") as script: + data = self.run_py( + [script, "-postarg"], + env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, + ) + self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) + + def test_search_path_exe(self): + # Leave the .exe on the name to ensure we don't add it a second time + name = Path(sys.executable).name + with self.py_ini(TEST_PY_COMMANDS): + with self.script(f"#! /usr/bin/env {name} -prearg") as script: + data = self.run_py( + [script, "-postarg"], + env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, + ) + self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) + + def test_recursive_search_path(self): + stem = self.get_py_exe().stem + with self.py_ini(TEST_PY_COMMANDS): + with self.script(f"#! /usr/bin/env {stem}") as script: + data = self.run_py( + [script], + env={"PATH": f"{self.get_py_exe().parent};{os.getenv('PATH')}"}, + ) + # The recursive search is ignored and we get normal "py" behavior + self.assertEqual(f"X.Y.exe {script}", data["stdout"].strip()) + def test_install(self): data = self.run_py(["-V:3.10"], env={"PYLAUNCHER_ALWAYS_INSTALL": "1"}, expect_returncode=111) cmd = data["stdout"].strip() diff --git a/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst b/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst new file mode 100644 index 00000000000..a49e99ca266 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst @@ -0,0 +1,3 @@ +Restores the behaviour of :ref:`launcher` for ``/usr/bin/env`` shebang +lines, which will now search :envvar:`PATH` for an executable matching the +given command. If none is found, the usual search process is used. diff --git a/PC/launcher2.c b/PC/launcher2.c index 033218ee2f4..a5dfd25f7d5 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -36,6 +36,7 @@ #define RC_DUPLICATE_ITEM 110 #define RC_INSTALLING 111 #define RC_NO_PYTHON_AT_ALL 112 +#define RC_NO_SHEBANG 113 static FILE * log_fp = NULL; @@ -750,6 +751,88 @@ _shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefi } +int +searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength) +{ + if (isEnvVarSet(L"PYLAUNCHER_NO_SEARCH_PATH")) { + return RC_NO_SHEBANG; + } + + wchar_t *command; + if (!_shebangStartsWith(shebang, shebangLength, L"/usr/bin/env ", &command)) { + return RC_NO_SHEBANG; + } + + wchar_t filename[MAXLEN]; + int lastDot = 0; + int commandLength = 0; + while (commandLength < MAXLEN && command[commandLength] && !isspace(command[commandLength])) { + if (command[commandLength] == L'.') { + lastDot = commandLength; + } + filename[commandLength] = command[commandLength]; + commandLength += 1; + } + + if (!commandLength || commandLength == MAXLEN) { + return RC_BAD_VIRTUAL_PATH; + } + + filename[commandLength] = L'\0'; + + const wchar_t *ext = L".exe"; + // If the command already has an extension, we do not want to add it again + if (!lastDot || _comparePath(&filename[lastDot], -1, ext, -1)) { + if (wcscat_s(filename, MAXLEN, L".exe")) { + return RC_BAD_VIRTUAL_PATH; + } + } + + wchar_t pathVariable[MAXLEN]; + int n = GetEnvironmentVariableW(L"PATH", pathVariable, MAXLEN); + if (!n) { + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + return RC_NO_SHEBANG; + } + winerror(0, L"Failed to read PATH\n", filename); + return RC_INTERNAL_ERROR; + } + + wchar_t buffer[MAXLEN]; + n = SearchPathW(pathVariable, filename, NULL, MAXLEN, buffer, NULL); + if (!n) { + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find %s on PATH\n", filename); + // If we didn't find it on PATH, let normal handling take over + return RC_NO_SHEBANG; + } + // Other errors should cause us to break + winerror(0, L"Failed to find %s on PATH\n", filename); + return RC_BAD_VIRTUAL_PATH; + } + + // Check that we aren't going to call ourselves again + // If we are, pretend there was no shebang and let normal handling take over + if (GetModuleFileNameW(NULL, filename, MAXLEN) && + 0 == _comparePath(filename, -1, buffer, -1)) { + debug(L"# ignoring recursive shebang command\n"); + return RC_NO_SHEBANG; + } + + wchar_t *buf = allocSearchInfoBuffer(search, n + 1); + if (!buf || wcscpy_s(buf, n + 1, buffer)) { + return RC_NO_MEMORY; + } + + search->executablePath = buf; + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Found %s on PATH\n", buf); + + return 0; +} + + int _readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, int bufferLength) { @@ -885,6 +968,12 @@ checkShebang(SearchInfo *search) } debug(L"Shebang: %s\n", shebang); + // Handle shebangs that we should search PATH for + exitCode = searchPath(search, shebang, shebangLength); + if (exitCode != RC_NO_SHEBANG) { + return exitCode; + } + // Handle some known, case-sensitive shebang templates const wchar_t *command; int commandLength; @@ -895,6 +984,7 @@ checkShebang(SearchInfo *search) L"", NULL }; + for (const wchar_t **tmpl = shebangTemplates; *tmpl; ++tmpl) { if (_shebangStartsWith(shebang, shebangLength, *tmpl, &command)) { commandLength = 0; @@ -910,6 +1000,22 @@ checkShebang(SearchInfo *search) } else if (_shebangStartsWith(command, commandLength, L"python", NULL)) { search->tag = &command[6]; search->tagLength = commandLength - 6; + // If we had 'python3.12.exe' then we want to strip the suffix + // off of the tag + if (search->tagLength > 4) { + const wchar_t *suffix = &search->tag[search->tagLength - 4]; + if (0 == _comparePath(suffix, 4, L".exe", -1)) { + search->tagLength -= 4; + } + } + // If we had 'python3_d' then we want to strip the '_d' (any + // '.exe' is already gone) + if (search->tagLength > 2) { + const wchar_t *suffix = &search->tag[search->tagLength - 2]; + if (0 == _comparePath(suffix, 2, L"_d", -1)) { + search->tagLength -= 2; + } + } search->oldStyleTag = true; search->executableArgs = &command[commandLength]; search->executableArgsLength = shebangLength - commandLength; From webhook-mailer at python.org Wed Aug 3 18:40:01 2022 From: webhook-mailer at python.org (ezio-melotti) Date: Wed, 03 Aug 2022 22:40:01 -0000 Subject: [Python-checkins] [3.10] gh-91423: Remove bugs.python.org from bugs.rst (GH-91425) (#95615) Message-ID: <mailman.464.1659566402.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a05dae23480761cf106caadbb7a3ba9d4cb262e0 commit: a05dae23480761cf106caadbb7a3ba9d4cb262e0 branch: 3.10 author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: ezio-melotti <ezio.melotti at gmail.com> date: 2022-08-04T00:39:51+02:00 summary: [3.10] gh-91423: Remove bugs.python.org from bugs.rst (GH-91425) (#95615) * Remove bugs.python.org from bugs.rst * Update bugs.rst to the github issue tracker * reflow * Fix a typo and rephrase a sentence. Co-authored-by: Inada Naoki <songofacandy at gmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit df81d2892eed3a256eb61ce59304f2173fb0c945) Co-authored-by: roy reznik <royreznik at gmail.com> Co-authored-by: roy reznik <royreznik at gmail.com> files: M Doc/bugs.rst diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 0feddeb5793..69d7c27410d 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -44,38 +44,39 @@ though it may take a while to be processed. Using the Python issue tracker ============================== -Bug reports for Python itself should be submitted via the Python Bug Tracker -(https://bugs.python.org/). The bug tracker offers a web form which allows -pertinent information to be entered and submitted to the developers. +Issue reports for Python itself should be submitted via the GitHub issues +tracker (https://github.com/python/cpython/issues). +The GitHub issues tracker offers a web form which allows pertinent information +to be entered and submitted to the developers. The first step in filing a report is to determine whether the problem has already been reported. The advantage in doing so, aside from saving the -developers time, is that you learn what has been done to fix it; it may be that +developers' time, is that you learn what has been done to fix it; it may be that the problem has already been fixed for the next release, or additional information is needed (in which case you are welcome to provide it if you can!). -To do this, search the bug database using the search box on the top of the page. +To do this, search the tracker using the search box at the top of the page. -If the problem you're reporting is not already in the bug tracker, go back to -the Python Bug Tracker and log in. If you don't already have a tracker account, -select the "Register" link or, if you use OpenID, one of the OpenID provider -logos in the sidebar. It is not possible to submit a bug report anonymously. +If the problem you're reporting is not already in the list, log in to GitHub. +If you don't already have a GitHub account, create a new account using the +"Sign up" link. +It is not possible to submit a bug report anonymously. -Being now logged in, you can submit a bug. Select the "Create New" link in the -sidebar to open the bug reporting form. +Being now logged in, you can submit an issue. +Click on the "New issue" button in the top bar to report a new issue. -The submission form has a number of fields. For the "Title" field, enter a -*very* short description of the problem; less than ten words is good. In the -"Type" field, select the type of your problem; also select the "Component" and -"Versions" to which the bug relates. +The submission form has two fields, "Title" and "Comment". + +For the "Title" field, enter a *very* short description of the problem; +less than ten words is good. In the "Comment" field, describe the problem in detail, including what you expected to happen and what did happen. Be sure to include whether any extension modules were involved, and what hardware and software platform you were using (including version information as appropriate). -Each bug report will be assigned to a developer who will determine what needs to -be done to correct the problem. You will receive an update each time action is -taken on the bug. +Each issue report will be reviewed by a developer who will determine what needs to +be done to correct the problem. You will receive an update each time an action is +taken on the issue. .. seealso:: @@ -99,6 +100,6 @@ patching Python in the `Python Developer's Guide`_. If you have questions, the `core-mentorship mailing list`_ is a friendly place to get answers to any and all questions pertaining to the process of fixing issues in Python. -.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity +.. _Documentation bugs: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs .. _Python Developer's Guide: https://devguide.python.org/ .. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/ From webhook-mailer at python.org Wed Aug 3 19:20:06 2022 From: webhook-mailer at python.org (gpshead) Date: Wed, 03 Aug 2022 23:20:06 -0000 Subject: [Python-checkins] gh-94675: Add a regression test for rjsmin re slowdown (GH-94685) Message-ID: <mailman.465.1659568807.3313.python-checkins@python.org> https://github.com/python/cpython/commit/fe23c0061d9c72527ad57a8c965d8161b00f500e commit: fe23c0061d9c72527ad57a8c965d8161b00f500e branch: main author: Miro Hron?ok <miro at hroncok.cz> committer: gpshead <greg at krypto.org> date: 2022-08-03T16:19:36-07:00 summary: gh-94675: Add a regression test for rjsmin re slowdown (GH-94685) Adds a regression test for an re slowdown observed by rjsmin. Uses multiprocessing to kill the test after SHORT_TIMEOUT. Co-authored-by: Oleg Iarygin <dralife at yandex.ru> Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst M Lib/test/test_re.py diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 9f734d47c54..3f0f84ea8ce 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,6 +1,7 @@ from test.support import (gc_collect, bigmemtest, _2G, cpython_only, captured_stdout, - check_disallow_instantiation, is_emscripten, is_wasi) + check_disallow_instantiation, is_emscripten, is_wasi, + SHORT_TIMEOUT) import locale import re import string @@ -11,6 +12,14 @@ from re import Scanner from weakref import proxy +# some platforms lack working multiprocessing +try: + import _multiprocessing +except ImportError: + multiprocessing = None +else: + import multiprocessing + # Misc tests from Tim Peters' re.doc # WARNING: Don't change details in these tests if you don't know @@ -2407,6 +2416,26 @@ def test_template_function_and_flag_is_deprecated(self): self.assertTrue(template_re1.match('ahoy')) self.assertFalse(template_re1.match('nope')) + @unittest.skipIf(multiprocessing is None, 'test requires multiprocessing') + def test_regression_gh94675(self): + pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*' + r'((/[^/\[\n]*(([^\n]|(\[\n]*(]*)*\]))' + r'[^/\[]*)*/))((((//[^\n]*)?[\n])' + r'([\000-\040]|(/\*[^*]*\*+' + r'([^/*]\*+)*/))*)+(?=[^\000-\040);\]}]))') + input_js = '''a(function() { + /////////////////////////////////////////////////////////////////// + });''' + p = multiprocessing.Process(target=pattern.sub, args=('', input_js)) + p.start() + p.join(SHORT_TIMEOUT) + try: + self.assertFalse(p.is_alive(), 'pattern.sub() timed out') + finally: + if p.is_alive(): + p.terminate() + p.join() + def get_debug_out(pat): with captured_stdout() as out: diff --git a/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst b/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst new file mode 100644 index 00000000000..d0005d9f601 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst @@ -0,0 +1 @@ +Add a regression test for :mod:`re` exponentional slowdown when using rjsmin. From webhook-mailer at python.org Wed Aug 3 19:42:21 2022 From: webhook-mailer at python.org (ethanfurman) Date: Wed, 03 Aug 2022 23:42:21 -0000 Subject: [Python-checkins] [3.11] [Enum] add whatsnew entries (GH-95455) (GH-95620) Message-ID: <mailman.466.1659570142.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3132318ce3577fbd8f324f8ce124dba3e209f945 commit: 3132318ce3577fbd8f324f8ce124dba3e209f945 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ethanfurman <ethan at stoneleaf.us> date: 2022-08-03T16:42:12-07:00 summary: [3.11] [Enum] add whatsnew entries (GH-95455) (GH-95620) (cherry picked from commit 6bde34000d70dfefafa71e54c8cb5672f423073c) Co-authored-by: Ethan Furman <ethan at stoneleaf.us> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 7b01fe2d963..428c190e41e 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -471,6 +471,49 @@ datetime formats (barring only those that support fractional hours and minutes). (Contributed by Paul Ganssle in :gh:`80010`.) +enum +---- + +* ``EnumMeta`` renamed to ``EnumType`` (``EnumMeta`` kept as alias). + +* ``StrEnum`` added -- enum members are and must be strings. + +* ``ReprEnum`` added -- causes only the ``__repr__`` to be modified, not the + ``__str__`` nor the ``__format__``. + +* ``FlagBoundary`` added -- controls behavior when invalid values are given to + a flag. + +* ``EnumCheck`` added -- used by ``verify`` to ensure various constraints. + +* ``verify`` added -- function to ensure given ``EnumCheck`` constraints. + +* ``member`` added -- decorator to ensure given object is converted to an enum + member. + +* ``nonmember`` added -- decorator to ensure given object is not converted to + an enum member. + +* ``property`` added -- use instead of ``types.DynamicClassAttribute``. + +* ``global_enum`` added -- enum decorator to adjust ``__repr__`` and ``__str__`` + to show members in the global context -- see ``re.RegexFlag`` for an example. + +* ``Flag`` enhancements: members support length, iteration, and containment + checks. + +* ``Enum``/``Flag`` fixes: members are now defined before ``__init_subclass__`` + is called; ``dir()`` now includes methods, etc., from mixed-in data types. + +* ``Flag`` fixes: only primary values (power of two) are considered canonical + while composite values (3, 6, 10, etc.) are considered aliases; inverted + flags are coerced to their positive equivalent. + +* ``IntEnum`` / ``IntFlag`` / ``StrEnum`` fixes: these now inherit from + ``ReprEnum`` so the ``str()`` output now matches ``format()`` output, + which is the data types' (so both ``str(AnIntEnum.ONE)`` and + ``format(AnIntEnum.ONE)`` is equal to ``'1'``). + fractions --------- From webhook-mailer at python.org Wed Aug 3 19:45:26 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 03 Aug 2022 23:45:26 -0000 Subject: [Python-checkins] gh-94675: Add a regression test for rjsmin re slowdown (GH-94685) Message-ID: <mailman.467.1659570327.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1bd1e379de49363003028ea90335ee619896c9ed commit: 1bd1e379de49363003028ea90335ee619896c9ed branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T16:45:19-07:00 summary: gh-94675: Add a regression test for rjsmin re slowdown (GH-94685) Adds a regression test for an re slowdown observed by rjsmin. Uses multiprocessing to kill the test after SHORT_TIMEOUT. Co-authored-by: Oleg Iarygin <dralife at yandex.ru> Co-authored-by: Christian Heimes <christian at python.org> (cherry picked from commit fe23c0061d9c72527ad57a8c965d8161b00f500e) Co-authored-by: Miro Hron?ok <miro at hroncok.cz> files: A Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst M Lib/test/test_re.py diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index ab980793fa7..5d946370ee1 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,6 +1,7 @@ from test.support import (gc_collect, bigmemtest, _2G, cpython_only, captured_stdout, - check_disallow_instantiation, is_emscripten, is_wasi) + check_disallow_instantiation, is_emscripten, is_wasi, + SHORT_TIMEOUT) import locale import re import string @@ -11,6 +12,14 @@ from re import Scanner from weakref import proxy +# some platforms lack working multiprocessing +try: + import _multiprocessing +except ImportError: + multiprocessing = None +else: + import multiprocessing + # Misc tests from Tim Peters' re.doc # WARNING: Don't change details in these tests if you don't know @@ -2438,6 +2447,26 @@ def test_template_function_and_flag_is_deprecated(self): self.assertTrue(template_re1.match('ahoy')) self.assertFalse(template_re1.match('nope')) + @unittest.skipIf(multiprocessing is None, 'test requires multiprocessing') + def test_regression_gh94675(self): + pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*' + r'((/[^/\[\n]*(([^\n]|(\[\n]*(]*)*\]))' + r'[^/\[]*)*/))((((//[^\n]*)?[\n])' + r'([\000-\040]|(/\*[^*]*\*+' + r'([^/*]\*+)*/))*)+(?=[^\000-\040);\]}]))') + input_js = '''a(function() { + /////////////////////////////////////////////////////////////////// + });''' + p = multiprocessing.Process(target=pattern.sub, args=('', input_js)) + p.start() + p.join(SHORT_TIMEOUT) + try: + self.assertFalse(p.is_alive(), 'pattern.sub() timed out') + finally: + if p.is_alive(): + p.terminate() + p.join() + def get_debug_out(pat): with captured_stdout() as out: diff --git a/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst b/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst new file mode 100644 index 00000000000..d0005d9f601 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst @@ -0,0 +1 @@ +Add a regression test for :mod:`re` exponentional slowdown when using rjsmin. From webhook-mailer at python.org Wed Aug 3 20:56:13 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 04 Aug 2022 00:56:13 -0000 Subject: [Python-checkins] gh-95191: IDLE Prompts entry for Whatnew 3.11 (#95632) Message-ID: <mailman.468.1659574574.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c569526faccb328a55691664b5931171d1a1494a commit: c569526faccb328a55691664b5931171d1a1494a branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-03T20:56:05-04:00 summary: gh-95191: IDLE Prompts entry for Whatnew 3.11 (#95632) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index d10d9f15a5f..2db647bb4e4 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -574,6 +574,9 @@ IDLE and idlelib * Apply syntax highlighting to `.pyi` files. (Contributed by Alex Waygood and Terry Jan Reedy in :issue:`45447`.) +* Include prompts when saving Shell with inputs and outputs. + (Contributed by Terry Jan Reedy in :gh:`95191`.) + inspect ------- * Add :func:`inspect.getmembers_static`: return all members without From webhook-mailer at python.org Wed Aug 3 21:04:17 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 01:04:17 -0000 Subject: [Python-checkins] gh-95191: IDLE Prompts entry for Whatnew 3.11 (GH-95632) Message-ID: <mailman.469.1659575058.3313.python-checkins@python.org> https://github.com/python/cpython/commit/dc5fecbf83adb701e79e8287feac08ced6574644 commit: dc5fecbf83adb701e79e8287feac08ced6574644 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T18:04:07-07:00 summary: gh-95191: IDLE Prompts entry for Whatnew 3.11 (GH-95632) (cherry picked from commit c569526faccb328a55691664b5931171d1a1494a) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 428c190e41e..1067982c3dc 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -574,6 +574,9 @@ IDLE and idlelib * Apply syntax highlighting to `.pyi` files. (Contributed by Alex Waygood and Terry Jan Reedy in :issue:`45447`.) +* Include prompts when saving Shell with inputs and outputs. + (Contributed by Terry Jan Reedy in :gh:`95191`.) + inspect ------- * Add :func:`inspect.getmembers_static`: return all members without From webhook-mailer at python.org Wed Aug 3 22:18:31 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 04 Aug 2022 02:18:31 -0000 Subject: [Python-checkins] gh-95191: IDLE Prompts entry for What's New 3.10 (#95633) Message-ID: <mailman.470.1659579513.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bcc74d509a3bd7e4fdc658179ae6d77614d1fd36 commit: bcc74d509a3bd7e4fdc658179ae6d77614d1fd36 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-03T22:17:57-04:00 summary: gh-95191: IDLE Prompts entry for What's New 3.10 (#95633) files: M Doc/whatsnew/3.10.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index d0fbf0d216d..db8d9281b1f 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1186,6 +1186,9 @@ New in 3.10 maintenance releases. Apply syntax highlighting to `.pyi` files. (Contributed by Alex Waygood and Terry Jan Reedy in :issue:`45447`.) +Include prompts when saving Shell with inputs and outputs. +(Contributed by Terry Jan Reedy in :gh:`95191`.) + importlib.metadata ------------------ From webhook-mailer at python.org Wed Aug 3 22:25:40 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 02:25:40 -0000 Subject: [Python-checkins] gh-95191: IDLE Prompts entry for What's New 3.10 (GH-95633) Message-ID: <mailman.471.1659579942.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b56a80ec6256f0362a42f4f9b363992278239cf5 commit: b56a80ec6256f0362a42f4f9b363992278239cf5 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T19:25:36-07:00 summary: gh-95191: IDLE Prompts entry for What's New 3.10 (GH-95633) (cherry picked from commit bcc74d509a3bd7e4fdc658179ae6d77614d1fd36) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/whatsnew/3.10.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index d0fbf0d216d..db8d9281b1f 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1186,6 +1186,9 @@ New in 3.10 maintenance releases. Apply syntax highlighting to `.pyi` files. (Contributed by Alex Waygood and Terry Jan Reedy in :issue:`45447`.) +Include prompts when saving Shell with inputs and outputs. +(Contributed by Terry Jan Reedy in :gh:`95191`.) + importlib.metadata ------------------ From webhook-mailer at python.org Wed Aug 3 22:27:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 02:27:21 -0000 Subject: [Python-checkins] gh-95191: IDLE Prompts entry for What's New 3.10 (GH-95633) Message-ID: <mailman.472.1659580042.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b6503fa7956d6c009a568477799963195792efdf commit: b6503fa7956d6c009a568477799963195792efdf branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-03T19:27:16-07:00 summary: gh-95191: IDLE Prompts entry for What's New 3.10 (GH-95633) (cherry picked from commit bcc74d509a3bd7e4fdc658179ae6d77614d1fd36) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/whatsnew/3.10.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 322e15e5e90..19ffd7e98ee 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1175,6 +1175,9 @@ New in 3.10 maintenance releases. Apply syntax highlighting to `.pyi` files. (Contributed by Alex Waygood and Terry Jan Reedy in :issue:`45447`.) +Include prompts when saving Shell with inputs and outputs. +(Contributed by Terry Jan Reedy in :gh:`95191`.) + importlib.metadata ------------------ From webhook-mailer at python.org Thu Aug 4 03:14:20 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 04 Aug 2022 07:14:20 -0000 Subject: [Python-checkins] gh-91838: Use HTTPS links in docs for resources which redirect to HTTPS (GH-95527) Message-ID: <mailman.473.1659597261.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f79547a429d5c90af83a0da821e082cba20d4712 commit: f79547a429d5c90af83a0da821e082cba20d4712 branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-04T10:13:49+03:00 summary: gh-91838: Use HTTPS links in docs for resources which redirect to HTTPS (GH-95527) If an HTTP link is redirected to a same looking HTTPS link, the latter can be used directly without changes in readability and behavior. It protects from a men-in-the-middle attack. This change does not affect Python examples. files: M .github/CONTRIBUTING.rst M Doc/extending/index.rst M Doc/faq/design.rst M Doc/faq/extending.rst M Doc/faq/programming.rst M Doc/howto/cporting.rst M Doc/howto/curses.rst M Doc/howto/functional.rst M Doc/howto/pyporting.rst M Doc/howto/unicode.rst M Doc/howto/urllib2.rst M Doc/library/collections.rst M Doc/library/difflib.rst M Doc/library/gettext.rst M Doc/library/http.client.rst M Doc/library/importlib.resources.rst M Doc/library/json.rst M Doc/library/os.path.rst M Doc/library/os.rst M Doc/library/random.rst M Doc/library/secrets.rst M Doc/library/shutil.rst M Doc/library/socket.rst M Doc/library/statistics.rst M Doc/library/string.rst M Doc/library/sys.rst M Doc/library/tkinter.rst M Doc/library/xmlrpc.client.rst M Doc/license.rst M Doc/reference/introduction.rst M Doc/using/cmdline.rst M Doc/using/mac.rst M Doc/whatsnew/2.5.rst M Doc/whatsnew/2.6.rst M Doc/whatsnew/2.7.rst M Doc/whatsnew/3.1.rst M Doc/whatsnew/3.2.rst M Doc/whatsnew/3.3.rst M Doc/whatsnew/3.5.rst M Doc/whatsnew/3.7.rst diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 30a39a40494f..627f57070d20 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -6,19 +6,19 @@ Build Status - main - + `Stable buildbots <http://buildbot.python.org/3.x.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.x.stable/>`_ - 3.9 - + `Stable buildbots <http://buildbot.python.org/3.9.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.9.stable/>`_ - 3.8 - + `Stable buildbots <http://buildbot.python.org/3.8.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.8.stable/>`_ - 3.7 - + `Stable buildbots <http://buildbot.python.org/3.7.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.7.stable/>`_ Thank You diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index 0994e3e8627d..01b4df6d44ac 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -27,8 +27,8 @@ Recommended third party tools This guide only covers the basic tools for creating extensions provided as part of this version of CPython. Third party tools like -`Cython <http://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, -`SWIG <http://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ +`Cython <https://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, +`SWIG <https://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ offer both simpler and more sophisticated approaches to creating C and C++ extensions for Python. diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 794b69795bac..9da1d01abd6f 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -321,8 +321,8 @@ is exactly the same type of object that a lambda expression yields) is assigned! Can Python be compiled to machine code, C or some other language? ----------------------------------------------------------------- -`Cython <http://cython.org/>`_ compiles a modified version of Python with -optional annotations into C extensions. `Nuitka <http://www.nuitka.net/>`_ is +`Cython <https://cython.org/>`_ compiles a modified version of Python with +optional annotations into C extensions. `Nuitka <https://www.nuitka.net/>`_ is an up-and-coming compiler of Python into C++ code, aiming to support the full Python language. @@ -338,8 +338,8 @@ cycles and deletes the objects involved. The :mod:`gc` module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector's parameters. -Other implementations (such as `Jython <http://www.jython.org>`_ or -`PyPy <http://www.pypy.org>`_), however, can rely on a different mechanism +Other implementations (such as `Jython <https://www.jython.org>`_ or +`PyPy <https://www.pypy.org>`_), however, can rely on a different mechanism such as a full-blown garbage collector. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 1d2aca6f4c8d..318e35508eae 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -41,7 +41,7 @@ on what you're trying to do. .. XXX make sure these all work -`Cython <http://cython.org>`_ and its relative `Pyrex +`Cython <https://cython.org>`_ and its relative `Pyrex <https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having @@ -49,10 +49,10 @@ to learn Python's C API. If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library's data types and functions -with a tool such as `SWIG <http://www.swig.org>`_. `SIP +with a tool such as `SWIG <https://www.swig.org>`_. `SIP <https://riverbankcomputing.com/software/sip/intro>`__, `CXX <http://cxx.sourceforge.net/>`_ `Boost -<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave +<https://www.boost.org/libs/python/doc/index.html>`_, or `Weave <https://github.com/scipy/weave>`_ are also alternatives for wrapping C++ libraries. @@ -286,6 +286,6 @@ Can I create an object class with some methods implemented in C and others in Py Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`, :class:`dict`, etc. -The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) +The Boost Python Library (BPL, https://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL). diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 4aea1277f9e7..5b5c357d5945 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1066,7 +1066,7 @@ performance levels: detrimental to readability). If you have reached the limit of what pure Python can allow, there are tools -to take you further away. For example, `Cython <http://cython.org>`_ can +to take you further away. For example, `Cython <https://cython.org>`_ can compile a slightly modified version of Python code into a C extension, and can be used on many different platforms. Cython can take advantage of compilation (and optional type annotations) to make your code significantly diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst index ce7700fc5990..7773620b40b9 100644 --- a/Doc/howto/cporting.rst +++ b/Doc/howto/cporting.rst @@ -22,5 +22,5 @@ We recommend the following resources for porting extension modules to Python 3: .. _Migrating C extensions: http://python3porting.com/cextensions.html .. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html -.. _Cython: http://cython.org/ +.. _Cython: https://cython.org/ .. _CFFI: https://cffi.readthedocs.io/en/latest/ diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index 26c4ece5ae6d..48add160c884 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -536,10 +536,10 @@ Patches adding support for these would be welcome; see `the Python Developer's Guide <https://devguide.python.org/>`_ to learn more about submitting patches to Python. -* `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_: +* `Writing Programs with NCURSES <https://invisible-island.net/ncurses/ncurses-intro.html>`_: a lengthy tutorial for C programmers. * `The ncurses man page <https://linux.die.net/man/3/ncurses>`_ -* `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_ +* `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. * `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index eb800152050d..1c3bd23f9fee 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1215,7 +1215,7 @@ flow inside a program. The book uses Scheme for its examples, but many of the design approaches described in these chapters are applicable to functional-style Python code. -http://www.defmacro.org/ramblings/fp.html: A general introduction to functional +https://www.defmacro.org/ramblings/fp.html: A general introduction to functional programming that uses Java examples and has a lengthy historical introduction. https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry @@ -1228,7 +1228,7 @@ https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying. Python-specific --------------- -http://gnosis.cx/TPiP/: The first chapter of David Mertz's book +https://gnosis.cx/TPiP/: The first chapter of David Mertz's book :title-reference:`Text Processing in Python` discusses functional programming for text processing, in the section titled "Utilizing Higher-Order Functions in Text Processing". diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index abcc34287e3d..add1c11be534 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -433,9 +433,9 @@ to make sure everything functions as expected in both versions of Python. .. _caniusepython3: https://pypi.org/project/caniusepython3 -.. _cheat sheet: http://python-future.org/compatible_idioms.html +.. _cheat sheet: https://python-future.org/compatible_idioms.html .. _coverage.py: https://pypi.org/project/coverage -.. _Futurize: http://python-future.org/automatic_conversion.html +.. _Futurize: https://python-future.org/automatic_conversion.html .. _importlib2: https://pypi.org/project/importlib2 .. _Modernize: https://python-modernize.readthedocs.io/ .. _mypy: http://mypy-lang.org/ @@ -445,7 +445,7 @@ to make sure everything functions as expected in both versions of Python. .. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html .. _pytype: https://github.com/google/pytype -.. _python-future: http://python-future.org/ +.. _python-future: https://python-future.org/ .. _python-porting: https://mail.python.org/pipermail/python-porting/ .. _six: https://pypi.org/project/six .. _tox: https://pypi.org/project/tox diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 535b21bd4a54..4969d2420d6a 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -167,7 +167,7 @@ On the Computerphile Youtube channel, Tom Scott briefly (9 minutes 36 seconds). To help understand the standard, Jukka Korpela has written `an introductory -guide <http://jkorpela.fi/unicode/guide.html>`_ to reading the +guide <https://jkorpela.fi/unicode/guide.html>`_ to reading the Unicode character tables. Another `good introductory article <https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_ @@ -735,7 +735,7 @@ References ---------- One section of `Mastering Python 3 Input/Output -<http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, +<https://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. The `PDF slides for Marc-Andr? Lemburg's presentation "Writing Unicode-aware @@ -745,7 +745,7 @@ discuss questions of character encodings as well as how to internationalize and localize an application. These slides cover Python 2.x only. `The Guts of Unicode in Python -<http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ +<https://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode representation in Python 3.3. diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index e1a2f48f0b08..69af3c3a85c5 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -411,7 +411,7 @@ fetched, particularly the headers sent by the server. It is currently an :class:`http.client.HTTPMessage` instance. Typical headers include 'Content-length', 'Content-type', and so on. See the -`Quick Reference to HTTP Headers <http://jkorpela.fi/http.html>`_ +`Quick Reference to HTTP Headers <https://jkorpela.fi/http.html>`_ for a useful listing of HTTP headers with brief explanations of their meaning and use. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 67b64ddda7a2..20863837fa1b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -664,7 +664,7 @@ added elements by appending to the right and popping to the left:: def moving_average(iterable, n=3): # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 - # http://en.wikipedia.org/wiki/Moving_average + # https://en.wikipedia.org/wiki/Moving_average it = iter(iterable) d = deque(itertools.islice(it, n-1)) d.appendleft(0) diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 87c38602113e..c5a279688a44 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -353,9 +353,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. seealso:: - `Pattern Matching: The Gestalt Approach <http://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ + `Pattern Matching: The Gestalt Approach <https://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This - was published in `Dr. Dobb's Journal <http://www.drdobbs.com/>`_ in July, 1988. + was published in `Dr. Dobb's Journal <https://www.drdobbs.com/>`_ in July, 1988. .. _sequence-matcher: diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 624501952421..747f8703b750 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -445,7 +445,7 @@ There are a few tools to extract the strings meant for translation. The original GNU :program:`gettext` only supported C or C++ source code but its extended version :program:`xgettext` scans code written in a number of languages, including Python, to find strings marked as -translatable. `Babel <http://babel.pocoo.org/>`__ is a Python +translatable. `Babel <https://babel.pocoo.org/>`__ is a Python internationalization library that includes a :file:`pybabel` script to extract and compile message catalogs. Fran?ois Pinard's program called :program:`xpot` does a similar job and is available as part of diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 8bb3187ef51d..16823ec67b01 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -591,7 +591,7 @@ Here is an example session that shows how to ``POST`` requests:: 302 Found >>> data = response.read() >>> data - b'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>' + b'Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>' >>> conn.close() Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst index d367dcee7c20..827e7d8d5ace 100644 --- a/Doc/library/importlib.resources.rst +++ b/Doc/library/importlib.resources.rst @@ -26,16 +26,16 @@ for example, a package and its resources can be imported from a zip file using This module provides functionality similar to `pkg_resources <https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_ `Basic Resource Access - <http://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access>`_ + <https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access>`_ without the performance overhead of that package. This makes reading resources included in packages easier, with more stable and consistent semantics. The standalone backport of this module provides more information on `using importlib.resources - <http://importlib-resources.readthedocs.io/en/latest/using.html>`_ and + <https://importlib-resources.readthedocs.io/en/latest/using.html>`_ and `migrating from pkg_resources to importlib.resources - <http://importlib-resources.readthedocs.io/en/latest/migration.html>`_. + <https://importlib-resources.readthedocs.io/en/latest/migration.html>`_. :class:`Loaders <importlib.abc.Loader>` that wish to support resource reading should implement a ``get_resource_reader(fullname)`` method as specified by diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 1e203242327c..f65be85d31bf 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -226,7 +226,7 @@ Basic Usage *object_hook* is an optional function that will be called with the result of any object literal decoded (a :class:`dict`). The return value of *object_hook* will be used instead of the :class:`dict`. This feature can be used - to implement custom decoders (e.g. `JSON-RPC <http://www.jsonrpc.org>`_ + to implement custom decoders (e.g. `JSON-RPC <https://www.jsonrpc.org>`_ class hinting). *object_pairs_hook* is an optional function that will be called with the @@ -326,7 +326,7 @@ Encoders and Decoders *object_hook*, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given :class:`dict`. This can be used to provide custom deserializations (e.g. to - support `JSON-RPC <http://www.jsonrpc.org>`_ class hinting). + support `JSON-RPC <https://www.jsonrpc.org>`_ class hinting). *object_pairs_hook*, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value of diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 85989ef32d49..7c35f3cafd12 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -335,7 +335,7 @@ the :mod:`glob` module.) .. note:: On POSIX systems, in accordance with `IEEE Std 1003.1 2013 Edition; 4.13 - Pathname Resolution <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_, + Pathname Resolution <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_, if a pathname begins with exactly two slashes, the first component following the leading characters may be interpreted in an implementation-defined manner, although more than two leading characters shall be treated as a diff --git a/Doc/library/os.rst b/Doc/library/os.rst index e5555c2355f1..eb154633e713 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2518,9 +2518,9 @@ features: .. note:: On Unix-based systems, :func:`scandir` uses the system's - `opendir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ + `opendir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ and - `readdir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ + `readdir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ functions. On Windows, it uses the Win32 `FindFirstFileW <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_ and @@ -4989,7 +4989,7 @@ Random numbers :py:data:`GRND_NONBLOCK`. See also the `Linux getrandom() manual page - <http://man7.org/linux/man-pages/man2/getrandom.2.html>`_. + <https://man7.org/linux/man-pages/man2/getrandom.2.html>`_. .. availability:: Linux >= 3.17. diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 78c2b030d609..913040052775 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -266,7 +266,7 @@ The following function generates a discrete distribution. .. function:: binomialvariate(n=1, p=0.5) `Binomial distribution - <http://mathworld.wolfram.com/BinomialDistribution.html>`_. + <https://mathworld.wolfram.com/BinomialDistribution.html>`_. Return the number of successes for *n* independent trials with the probability of success in each trial being *p*: diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index 86fa35fec59f..dc8e5f46fb58 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -153,7 +153,7 @@ Generate an eight-character alphanumeric password: .. note:: Applications should not - `store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_, + `store passwords in a recoverable format <https://cwe.mitre.org/data/definitions/257.html>`_, whether plain text or encrypted. They should be salted and hashed using a cryptographically strong one-way (irreversible) hash function. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 7d69c5ff266f..8f1668f76b90 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -801,4 +801,4 @@ Querying the size of the output terminal http://www.manpagez.com/man/3/copyfile/ .. _`Other Environment Variables`: - http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 + https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index b2bb8c788674..f97c4f670016 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -370,7 +370,7 @@ Constants .. seealso:: - `Secure File Descriptor Handling <http://udrepper.livejournal.com/20407.html>`_ + `Secure File Descriptor Handling <https://udrepper.livejournal.com/20407.html>`_ for a more thorough explanation. .. availability:: Linux >= 2.6.27. diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 5aef6f6f05d6..bf869903c0f8 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -938,7 +938,7 @@ Carlo simulation <https://en.wikipedia.org/wiki/Monte_Carlo_method>`_: [1.4591308524824727, 1.8035946855390597, 2.175091447274739] Normal distributions can be used to approximate `Binomial -distributions <http://mathworld.wolfram.com/BinomialDistribution.html>`_ +distributions <https://mathworld.wolfram.com/BinomialDistribution.html>`_ when the sample size is large and when the probability of a successful trial is near 50%. diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 35e9bc116803..7d0d601799f7 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -738,7 +738,7 @@ internationalization (i18n) since in that context, the simpler syntax and functionality makes it easier to translate than other built-in string formatting facilities in Python. As an example of a library built on template strings for i18n, see the -`flufl.i18n <http://flufli18n.readthedocs.io/en/latest/>`_ package. +`flufl.i18n <https://flufli18n.readthedocs.io/en/latest/>`_ package. .. index:: single: $ (dollar); in template strings diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 632ce627d86f..43db4baf62df 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1799,4 +1799,4 @@ always available. .. rubric:: Citations -.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . +.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 096a343bd955..0447b15e26fe 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -61,7 +61,7 @@ details that are unchanged. * `Python and Tkinter Programming <https://www.packtpub.com/product/python-gui-programming-with-tkinter/9781788835886>`_ By Alan Moore. (ISBN 978-1788835886) - * `Programming Python <http://learning-python.com/about-pp4e.html>`_ + * `Programming Python <https://learning-python.com/about-pp4e.html>`_ By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101) * `Tcl and the Tk Toolkit (2nd edition) <https://www.amazon.com/exec/obidos/ASIN/032133633X>`_ @@ -988,7 +988,7 @@ wherever the image was used. .. seealso:: - The `Pillow <http://python-pillow.org/>`_ package adds support for + The `Pillow <https://python-pillow.org/>`_ package adds support for formats such as BMP, JPEG, TIFF, and WebP, among others. .. _tkinter-file-handlers: diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 9f5ba46934b7..2dcf3984cf42 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -156,12 +156,12 @@ between conformable Python objects and XML on the wire. Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``, ``float`` and ``bigdecimal``. - See http://ws.apache.org/xmlrpc/types.html for a description. + See https://ws.apache.org/xmlrpc/types.html for a description. .. seealso:: - `XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ + `XML-RPC HOWTO <https://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ A good description of XML-RPC operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know. diff --git a/Doc/license.rst b/Doc/license.rst index e0276b492437..00691b30ba6d 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -353,7 +353,7 @@ Sockets The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and :func:`getnameinfo`, which are coded in separate source files from the WIDE -Project, http://www.wide.ad.jp/. :: +Project, https://www.wide.ad.jp/. :: Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. All rights reserved. diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 72e874ee98e4..914a11556c94 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -54,7 +54,7 @@ Jython Python implemented in Java. This implementation can be used as a scripting language for Java applications, or can be used to create applications using the Java class libraries. It is also often used to create tests for Java libraries. - More information can be found at `the Jython website <http://www.jython.org/>`_. + More information can be found at `the Jython website <https://www.jython.org/>`_. Python for .NET This implementation actually uses the CPython implementation, but is a managed @@ -66,7 +66,7 @@ IronPython An alternate Python for .NET. Unlike Python.NET, this is a complete Python implementation that generates IL, and compiles Python code directly to .NET assemblies. It was created by Jim Hugunin, the original creator of Jython. For - more information, see `the IronPython website <http://ironpython.net/>`_. + more information, see `the IronPython website <https://ironpython.net/>`_. PyPy An implementation of Python written completely in Python. It supports several @@ -74,7 +74,7 @@ PyPy and a Just in Time compiler. One of the goals of the project is to encourage experimentation with the language itself by making it easier to modify the interpreter (since it is written in Python). Additional information is - available on `the PyPy project's home page <http://pypy.org/>`_. + available on `the PyPy project's home page <https://pypy.org/>`_. Each of these implementations varies in some way from the language as documented in this manual, or introduces specific information beyond what's covered in the diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 2d376ec7b40f..6678d476fa83 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -585,7 +585,7 @@ Options you shouldn't use Reserved for use by Jython_. -.. _Jython: http://www.jython.org/ +.. _Jython: https://www.jython.org/ .. _using-on-envvars: diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index f7db038430b6..f85b5bd2e713 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -65,7 +65,7 @@ number of standard Unix command line editors, :program:`vim` and :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see https://macromates.com/). Other editors include -:program:`Gvim` (http://macvim-dev.github.io/macvim/) and :program:`Aquamacs` +:program:`Gvim` (https://macvim-dev.github.io/macvim/) and :program:`Aquamacs` (http://aquamacs.org/). To run your script from the Terminal window you must make sure that diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 1b1fb3be9cab..f580c822dfdd 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -1930,7 +1930,7 @@ with the same digest state. The sqlite3 package ------------------- -The pysqlite module (http://www.pysqlite.org), a wrapper for the SQLite embedded +The pysqlite module (https://www.pysqlite.org), a wrapper for the SQLite embedded database, has been added to the standard library under the package name :mod:`sqlite3`. diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 7524da896393..eaca3165c07c 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -176,7 +176,7 @@ Hosting of the Python bug tracker is kindly provided by of Stellenbosch, South Africa. Martin von L?wis put a lot of effort into importing existing bugs and patches from SourceForge; his scripts for this import operation are at -``http://svn.python.org/view/tracker/importer/`` and may be useful to +``https://svn.python.org/view/tracker/importer/`` and may be useful to other projects wishing to move from SourceForge to Roundup. .. seealso:: @@ -184,13 +184,13 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.python.org The Python bug tracker. - http://bugs.jython.org: + https://bugs.jython.org: The Jython bug tracker. http://roundup.sourceforge.net/ Roundup downloads and documentation. - http://svn.python.org/view/tracker/importer/ + https://svn.python.org/view/tracker/importer/ Martin von L?wis's conversion scripts. New Documentation Format: reStructuredText Using Sphinx @@ -1433,7 +1433,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6. `Scheme's numerical tower <https://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual. - `Scheme's number datatypes <http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. + `Scheme's number datatypes <https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. The :mod:`fractions` Module diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index 59d68a192b8f..01f140dac8ae 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -299,7 +299,7 @@ modules. constructor was extended with an *object_pairs_hook* parameter to allow :class:`OrderedDict` instances to be built by the decoder. Support was also added for third-party tools like - `PyYAML <http://pyyaml.org/>`_. + `PyYAML <https://pyyaml.org/>`_. .. seealso:: @@ -1048,7 +1048,7 @@ changes, or look through the Subversion logs for all the details. The new version features better Python 3.x compatibility, various bug fixes, and adds several new BerkeleyDB flags and methods. (Updated by Jes?s Cea Avi?n; :issue:`8156`. The pybsddb - changelog can be read at http://hg.jcea.es/pybsddb/file/tip/ChangeLog.) + changelog can be read at https://hg.jcea.es/pybsddb/file/tip/ChangeLog.) * The :mod:`bz2` module's :class:`~bz2.BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f:``. @@ -1831,7 +1831,7 @@ packaged as the :mod:`unittest2` package, from https://pypi.org/project/unittest2. When used from the command line, the module can automatically discover -tests. It's not as fancy as `py.test <http://pytest.org>`__ or +tests. It's not as fancy as `py.test <https://pytest.org>`__ or `nose <https://nose.readthedocs.io/>`__, but provides a simple way to run tests kept within a set of package directories. For example, the following command will search the :file:`test/` subdirectory for @@ -2692,7 +2692,7 @@ As part of this change, the :ref:`installing-index` and completely redesigned as short getting started and FAQ documents. Most packaging documentation has now been moved out to the Python Packaging Authority maintained `Python Packaging User Guide -<http://packaging.python.org>`__ and the documentation of the individual +<https://packaging.python.org>`__ and the documentation of the individual projects. However, as this migration is currently still incomplete, the legacy diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index 3d89b97fa8f1..6ce6358d49fb 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -72,7 +72,7 @@ order. The *_asdict()* method for :func:`collections.namedtuple` now returns an ordered dictionary with the values appearing in the same order as the underlying tuple indices. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also added for third-party tools like `PyYAML <http://pyyaml.org/>`_. +Support was also added for third-party tools like `PyYAML <https://pyyaml.org/>`_. .. seealso:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index c7b42ef0ed73..e2681bc983a8 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -2506,7 +2506,7 @@ IDLE Code Repository =============== -In addition to the existing Subversion code repository at http://svn.python.org +In addition to the existing Subversion code repository at https://svn.python.org there is now a `Mercurial <https://www.mercurial-scm.org/>`_ repository at https://hg.python.org/\ . diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 0f989464c9c8..1b5b6831e430 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1106,7 +1106,7 @@ the precision is user configurable, the exact figures may vary. For example, in integer bignum arithmetic the differences can be significantly higher. The following table is meant as an illustration. Benchmarks are available -at http://www.bytereef.org/mpdecimal/quickstart.html. +at https://www.bytereef.org/mpdecimal/quickstart.html. +---------+-------------+--------------+-------------+ | | decimal.py | _decimal | speedup | diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index 537007b42fc6..a5c2d9bb0874 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -1253,7 +1253,7 @@ imghdr ------ The :func:`~imghdr.what` function now recognizes the -`OpenEXR <http://www.openexr.com>`_ format +`OpenEXR <https://www.openexr.com>`_ format (contributed by Martin Vignali and Claudiu Popa in :issue:`20295`), and the `WebP <https://en.wikipedia.org/wiki/WebP>`_ format (contributed by Fabrice Aneche and Claudiu Popa in :issue:`20197`.) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index fd99682f3a4f..2e9738721a77 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -611,7 +611,7 @@ Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`. .. seealso:: - `importlib_resources <http://importlib-resources.readthedocs.io/en/latest/>`_ + `importlib_resources <https://importlib-resources.readthedocs.io/en/latest/>`_ -- a PyPI backport for earlier Python versions. From webhook-mailer at python.org Thu Aug 4 03:36:05 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 04 Aug 2022 07:36:05 -0000 Subject: [Python-checkins] gh-95638: Update idlelib README file and menu lists (#95639) Message-ID: <mailman.474.1659598566.3313.python-checkins@python.org> https://github.com/python/cpython/commit/621b33ce258f3eaf154322c1edf0ead1e4892e36 commit: 621b33ce258f3eaf154322c1edf0ead1e4892e36 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-04T03:35:42-04:00 summary: gh-95638: Update idlelib README file and menu lists (#95639) files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 8870fda315e3..67de2be26256 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -16,8 +16,9 @@ and omissions and lag behind changes in idlelib. IDLELIB FILES +============= + Implementation files not in IDLE MENU are marked (nim). -Deprecated files and objects are listed separately as the end. Startup ------- @@ -33,22 +34,22 @@ autocomplete.py # Complete attribute names or filenames. autocomplete_w.py # Display completions. autoexpand.py # Expand word with previous word in file. browser.py # Create module browser window. +calltip.py # Create calltip text. calltip_w.py # Display calltip. -calltips.py # Create calltip text. codecontext.py # Show compound statement headers otherwise not visible. -colorizer.py # Colorize text (nim) +colorizer.py # Colorize text (nim). config.py # Load, fetch, and save configuration (nim). configdialog.py # Display user configuration dialogs. -config_help.py # Specify help source in configdialog. config_key.py # Change keybindings. -dynoption.py # Define mutable OptionMenu widget (nim). -debugobj.py # Define class used in stackviewer. -debugobj_r.py # Communicate objects between processes with rpc (nim). debugger.py # Debug code run from shell or editor; show window. debugger_r.py # Debug code run in remote process. +debugobj.py # Define class used in stackviewer. +debugobj_r.py # Communicate objects between processes with rpc (nim). delegator.py # Define base class for delegators (nim). +dynoption.py # Define mutable OptionMenu widget (nim) editor.py # Define most of editor and utility functions. filelist.py # Open files and manage list of open windows (nim). +format.py # Define format menu options. grep.py # Find all occurrences of pattern in multiple files. help.py # Display IDLE's html doc. help_about.py # Display About IDLE dialog. @@ -59,7 +60,6 @@ macosx.py # Help IDLE run on Macs (nim). mainmenu.py # Define most of IDLE menu. multicall.py # Wrap tk widget to allow multiple calls per event (nim). outwin.py # Create window for grep output. -paragraph.py # Re-wrap multiline strings and comments. parenmatch.py # Match fenceposts: (), [], and {}. pathbrowser.py # Create path browser window. percolator.py # Manage delegator stack (nim). @@ -69,22 +69,25 @@ query.py # Query user for information redirector.py # Intercept widget subcommands (for percolator) (nim). replace.py # Search and replace pattern in text. rpc.py # Communicate between idle and user processes (nim). -rstrip.py # Strip trailing whitespace. run.py # Manage user code execution subprocess. runscript.py # Check and run user code. scrolledlist.py # Define scrolledlist widget for IDLE (nim). search.py # Search for pattern in text. searchbase.py # Define base for search, replace, and grep dialogs. searchengine.py # Define engine for all 3 search dialogs. +sidebar.py # Define line number and shell prompt sidebars. +squeezer.py # Squeeze long shell output (nim). stackviewer.py # View stack after exception. statusbar.py # Define status bar for windows (nim). tabbedpages.py # Define tabbed pages widget (nim). textview.py # Define read-only text widget (nim). +tooltip.py # Define popups for calltips, squeezer (nim). tree.py # Define tree widget, used in browsers (nim). undo.py # Manage undo stack. -util.py # Define objects imported elsewhere with no dependencies (nim) +util.py # Define common objects imported elsewhere (nim). windows.py # Manage window list and define listed top level. zoomheight.py # Zoom window to full height of screen. +zzdummy.py # Example extension. Configuration ------------- @@ -98,6 +101,7 @@ Text CREDITS.txt # not maintained, displayed by About IDLE HISTORY.txt # NEWS up to July 2001 NEWS.txt # commits, displayed by About IDLE +NEWS2.txt # commits to Python2 README.txt # this file, displayed by About IDLE TODO.txt # needs review extend.txt # about writing extensions @@ -108,13 +112,10 @@ Subdirectories Icons # small image files idle_test # files for human test and automated unit tests -Unused and Deprecated files and objects (nim) ---------------------------------------------- -tooltip.py # unused - - IDLE MENUS +========== + Top level items and most submenu items are defined in mainmenu. Extensions add submenu items when active. The names given are found, quoted, in one of these modules, paired with a '<<pseudoevent>>'. @@ -160,63 +161,68 @@ Edit Show call tip # Calltips extension and CalltipWindow (& Hyperparser) Show surrounding parens # parenmatch (& Hyperparser) +Format (Editor only) [fFR = format.FormatRegion] + Format Paragraph # format.FormatParagraph.format_paragraph_event + Indent Region # fFR.indent_region_event + Dedent Region # fFR.dedent_region_event + Comment Out Reg. # fFR.comment_region_event + Uncomment Region # fFR.uncomment_region_event + Tabify Region # fFR.tabify_region_event + Untabify Region # fFR.untabify_region_event + Toggle Tabs # format.Indents.toggle_tabs_event + New Indent Width # format.Indents.change_indentwidth_event + Strip tailing whitespace # format.rstrip + Zin # zzdummy + Zout # zzdummy + +Run (Editor only) + Run Module # runscript.ScriptBinding.run_module_event + Run... Customized # runscript.ScriptBinding.run_custom_event + Check Module # runscript.ScriptBinding.check_module_event + Python Shell # pyshell.Pyshell, pyshell.ModifiedInterpreter + Shell # pyshell View Last Restart # pyshell.PyShell.view_restart_mark Restart Shell # pyshell.PyShell.restart_shell + Previous History # history.History.history_prev + Next History # history.History.history_next Interrupt Execution # pyshell.PyShell.cancel_callback Debug (Shell only) - Go to File/Line + Go to File/Line # outwin.OutputWindow.goto_file_line debugger # debugger, debugger_r, PyShell.toggle_debugger Stack Viewer # stackviewer, PyShell.open_stack_viewer Auto-open Stack Viewer # stackviewer -Format (Editor only) - Indent Region # eEW.indent_region_event - Dedent Region # eEW.dedent_region_event - Comment Out Reg. # eEW.comment_region_event - Uncomment Region # eEW.uncomment_region_event - Tabify Region # eEW.tabify_region_event - Untabify Region # eEW.untabify_region_event - Toggle Tabs # eEW.toggle_tabs_event - New Indent Width # eEW.change_indentwidth_event - Format Paragraph # paragraph extension - --- - Strip tailing whitespace # rstrip extension - -Run (Editor only) - Python Shell # pyshell - --- - Check Module # runscript - Run Module # runscript - Options - Configure IDLE # eEW.config_dialog, configdialog - (tabs in the dialog) - Font tab # config-main.def - Highlight tab # query, config-highlight.def - Keys tab # query, config_key, config_keys.def - General tab # config_help, config-main.def - Extensions tab # config-extensions.def, corresponding .py + Configure IDLE # eEW.config_dialog, config, configdialog (cd) + (Parts of the dialog) + Buttons # cd.ConfigDialog + Font tab # cd.FontPage, config-main.def + Highlight tab # cd.HighPage, query, config-highlight.def + Keys tab # cd.KeysPage, query, config_key, config_keys.def + Windows tab # cd.WinPage, config_main.def + Shell/Ed tab # cd.ShedPage, config-main.def + Extensions tab # config-extensions.def, corresponding .py files --- - Code Context (ed)# codecontext extension + ... Code Context # codecontext + ... Line Numbers # sidebar + Zoomheight # zoomheight Window - Zoomheight # zoomheight extension - --- <open windows> # windows Help About IDLE # eEW.about_dialog, help_about.AboutDialog --- - IDLE Help # eEW.help_dialog, helpshow_idlehelp - Python Doc # eEW.python_docs + IDLE Help # eEW.help_dialog, help.show_idlehelp + Python Docs # eEW.python_docs Turtle Demo # eEW.open_turtle_demo --- <other help sources> <Context Menu> (right click) - Defined in editor, PyShelpyshellut + Defined in editor, PyShell.pyshell Cut Copy Paste @@ -232,11 +238,14 @@ Help Center Insert # eEW.center_insert_event -CODE STYLE -- Generally PEP 8. +OTHER TOPICS +============ + +Generally use PEP 8. import ------ -Put import at the top, unless there is a good reason otherwise. +Put imports at the top, unless there is a good reason otherwise. PEP 8 says to group stdlib, 3rd-party dependencies, and package imports. For idlelib, the groups are general stdlib, tkinter, and idlelib. Sort modules within each group, except that tkinter.ttk follows tkinter. From webhook-mailer at python.org Thu Aug 4 04:02:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 08:02:05 -0000 Subject: [Python-checkins] gh-95638: Update idlelib README file and menu lists (GH-95639) Message-ID: <mailman.475.1659600127.3313.python-checkins@python.org> https://github.com/python/cpython/commit/390c80d2c44e6983ad541fff23d99625abf8a42d commit: 390c80d2c44e6983ad541fff23d99625abf8a42d branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T01:01:55-07:00 summary: gh-95638: Update idlelib README file and menu lists (GH-95639) (cherry picked from commit 621b33ce258f3eaf154322c1edf0ead1e4892e36) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 8870fda315e3..67de2be26256 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -16,8 +16,9 @@ and omissions and lag behind changes in idlelib. IDLELIB FILES +============= + Implementation files not in IDLE MENU are marked (nim). -Deprecated files and objects are listed separately as the end. Startup ------- @@ -33,22 +34,22 @@ autocomplete.py # Complete attribute names or filenames. autocomplete_w.py # Display completions. autoexpand.py # Expand word with previous word in file. browser.py # Create module browser window. +calltip.py # Create calltip text. calltip_w.py # Display calltip. -calltips.py # Create calltip text. codecontext.py # Show compound statement headers otherwise not visible. -colorizer.py # Colorize text (nim) +colorizer.py # Colorize text (nim). config.py # Load, fetch, and save configuration (nim). configdialog.py # Display user configuration dialogs. -config_help.py # Specify help source in configdialog. config_key.py # Change keybindings. -dynoption.py # Define mutable OptionMenu widget (nim). -debugobj.py # Define class used in stackviewer. -debugobj_r.py # Communicate objects between processes with rpc (nim). debugger.py # Debug code run from shell or editor; show window. debugger_r.py # Debug code run in remote process. +debugobj.py # Define class used in stackviewer. +debugobj_r.py # Communicate objects between processes with rpc (nim). delegator.py # Define base class for delegators (nim). +dynoption.py # Define mutable OptionMenu widget (nim) editor.py # Define most of editor and utility functions. filelist.py # Open files and manage list of open windows (nim). +format.py # Define format menu options. grep.py # Find all occurrences of pattern in multiple files. help.py # Display IDLE's html doc. help_about.py # Display About IDLE dialog. @@ -59,7 +60,6 @@ macosx.py # Help IDLE run on Macs (nim). mainmenu.py # Define most of IDLE menu. multicall.py # Wrap tk widget to allow multiple calls per event (nim). outwin.py # Create window for grep output. -paragraph.py # Re-wrap multiline strings and comments. parenmatch.py # Match fenceposts: (), [], and {}. pathbrowser.py # Create path browser window. percolator.py # Manage delegator stack (nim). @@ -69,22 +69,25 @@ query.py # Query user for information redirector.py # Intercept widget subcommands (for percolator) (nim). replace.py # Search and replace pattern in text. rpc.py # Communicate between idle and user processes (nim). -rstrip.py # Strip trailing whitespace. run.py # Manage user code execution subprocess. runscript.py # Check and run user code. scrolledlist.py # Define scrolledlist widget for IDLE (nim). search.py # Search for pattern in text. searchbase.py # Define base for search, replace, and grep dialogs. searchengine.py # Define engine for all 3 search dialogs. +sidebar.py # Define line number and shell prompt sidebars. +squeezer.py # Squeeze long shell output (nim). stackviewer.py # View stack after exception. statusbar.py # Define status bar for windows (nim). tabbedpages.py # Define tabbed pages widget (nim). textview.py # Define read-only text widget (nim). +tooltip.py # Define popups for calltips, squeezer (nim). tree.py # Define tree widget, used in browsers (nim). undo.py # Manage undo stack. -util.py # Define objects imported elsewhere with no dependencies (nim) +util.py # Define common objects imported elsewhere (nim). windows.py # Manage window list and define listed top level. zoomheight.py # Zoom window to full height of screen. +zzdummy.py # Example extension. Configuration ------------- @@ -98,6 +101,7 @@ Text CREDITS.txt # not maintained, displayed by About IDLE HISTORY.txt # NEWS up to July 2001 NEWS.txt # commits, displayed by About IDLE +NEWS2.txt # commits to Python2 README.txt # this file, displayed by About IDLE TODO.txt # needs review extend.txt # about writing extensions @@ -108,13 +112,10 @@ Subdirectories Icons # small image files idle_test # files for human test and automated unit tests -Unused and Deprecated files and objects (nim) ---------------------------------------------- -tooltip.py # unused - - IDLE MENUS +========== + Top level items and most submenu items are defined in mainmenu. Extensions add submenu items when active. The names given are found, quoted, in one of these modules, paired with a '<<pseudoevent>>'. @@ -160,63 +161,68 @@ Edit Show call tip # Calltips extension and CalltipWindow (& Hyperparser) Show surrounding parens # parenmatch (& Hyperparser) +Format (Editor only) [fFR = format.FormatRegion] + Format Paragraph # format.FormatParagraph.format_paragraph_event + Indent Region # fFR.indent_region_event + Dedent Region # fFR.dedent_region_event + Comment Out Reg. # fFR.comment_region_event + Uncomment Region # fFR.uncomment_region_event + Tabify Region # fFR.tabify_region_event + Untabify Region # fFR.untabify_region_event + Toggle Tabs # format.Indents.toggle_tabs_event + New Indent Width # format.Indents.change_indentwidth_event + Strip tailing whitespace # format.rstrip + Zin # zzdummy + Zout # zzdummy + +Run (Editor only) + Run Module # runscript.ScriptBinding.run_module_event + Run... Customized # runscript.ScriptBinding.run_custom_event + Check Module # runscript.ScriptBinding.check_module_event + Python Shell # pyshell.Pyshell, pyshell.ModifiedInterpreter + Shell # pyshell View Last Restart # pyshell.PyShell.view_restart_mark Restart Shell # pyshell.PyShell.restart_shell + Previous History # history.History.history_prev + Next History # history.History.history_next Interrupt Execution # pyshell.PyShell.cancel_callback Debug (Shell only) - Go to File/Line + Go to File/Line # outwin.OutputWindow.goto_file_line debugger # debugger, debugger_r, PyShell.toggle_debugger Stack Viewer # stackviewer, PyShell.open_stack_viewer Auto-open Stack Viewer # stackviewer -Format (Editor only) - Indent Region # eEW.indent_region_event - Dedent Region # eEW.dedent_region_event - Comment Out Reg. # eEW.comment_region_event - Uncomment Region # eEW.uncomment_region_event - Tabify Region # eEW.tabify_region_event - Untabify Region # eEW.untabify_region_event - Toggle Tabs # eEW.toggle_tabs_event - New Indent Width # eEW.change_indentwidth_event - Format Paragraph # paragraph extension - --- - Strip tailing whitespace # rstrip extension - -Run (Editor only) - Python Shell # pyshell - --- - Check Module # runscript - Run Module # runscript - Options - Configure IDLE # eEW.config_dialog, configdialog - (tabs in the dialog) - Font tab # config-main.def - Highlight tab # query, config-highlight.def - Keys tab # query, config_key, config_keys.def - General tab # config_help, config-main.def - Extensions tab # config-extensions.def, corresponding .py + Configure IDLE # eEW.config_dialog, config, configdialog (cd) + (Parts of the dialog) + Buttons # cd.ConfigDialog + Font tab # cd.FontPage, config-main.def + Highlight tab # cd.HighPage, query, config-highlight.def + Keys tab # cd.KeysPage, query, config_key, config_keys.def + Windows tab # cd.WinPage, config_main.def + Shell/Ed tab # cd.ShedPage, config-main.def + Extensions tab # config-extensions.def, corresponding .py files --- - Code Context (ed)# codecontext extension + ... Code Context # codecontext + ... Line Numbers # sidebar + Zoomheight # zoomheight Window - Zoomheight # zoomheight extension - --- <open windows> # windows Help About IDLE # eEW.about_dialog, help_about.AboutDialog --- - IDLE Help # eEW.help_dialog, helpshow_idlehelp - Python Doc # eEW.python_docs + IDLE Help # eEW.help_dialog, help.show_idlehelp + Python Docs # eEW.python_docs Turtle Demo # eEW.open_turtle_demo --- <other help sources> <Context Menu> (right click) - Defined in editor, PyShelpyshellut + Defined in editor, PyShell.pyshell Cut Copy Paste @@ -232,11 +238,14 @@ Help Center Insert # eEW.center_insert_event -CODE STYLE -- Generally PEP 8. +OTHER TOPICS +============ + +Generally use PEP 8. import ------ -Put import at the top, unless there is a good reason otherwise. +Put imports at the top, unless there is a good reason otherwise. PEP 8 says to group stdlib, 3rd-party dependencies, and package imports. For idlelib, the groups are general stdlib, tkinter, and idlelib. Sort modules within each group, except that tkinter.ttk follows tkinter. From webhook-mailer at python.org Thu Aug 4 04:05:30 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 08:05:30 -0000 Subject: [Python-checkins] gh-95638: Update idlelib README file and menu lists (GH-95639) Message-ID: <mailman.476.1659600331.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c5916a034ab573aaf5bf124e53d987de5cc6d102 commit: c5916a034ab573aaf5bf124e53d987de5cc6d102 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T01:05:20-07:00 summary: gh-95638: Update idlelib README file and menu lists (GH-95639) (cherry picked from commit 621b33ce258f3eaf154322c1edf0ead1e4892e36) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 8870fda315e3..67de2be26256 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -16,8 +16,9 @@ and omissions and lag behind changes in idlelib. IDLELIB FILES +============= + Implementation files not in IDLE MENU are marked (nim). -Deprecated files and objects are listed separately as the end. Startup ------- @@ -33,22 +34,22 @@ autocomplete.py # Complete attribute names or filenames. autocomplete_w.py # Display completions. autoexpand.py # Expand word with previous word in file. browser.py # Create module browser window. +calltip.py # Create calltip text. calltip_w.py # Display calltip. -calltips.py # Create calltip text. codecontext.py # Show compound statement headers otherwise not visible. -colorizer.py # Colorize text (nim) +colorizer.py # Colorize text (nim). config.py # Load, fetch, and save configuration (nim). configdialog.py # Display user configuration dialogs. -config_help.py # Specify help source in configdialog. config_key.py # Change keybindings. -dynoption.py # Define mutable OptionMenu widget (nim). -debugobj.py # Define class used in stackviewer. -debugobj_r.py # Communicate objects between processes with rpc (nim). debugger.py # Debug code run from shell or editor; show window. debugger_r.py # Debug code run in remote process. +debugobj.py # Define class used in stackviewer. +debugobj_r.py # Communicate objects between processes with rpc (nim). delegator.py # Define base class for delegators (nim). +dynoption.py # Define mutable OptionMenu widget (nim) editor.py # Define most of editor and utility functions. filelist.py # Open files and manage list of open windows (nim). +format.py # Define format menu options. grep.py # Find all occurrences of pattern in multiple files. help.py # Display IDLE's html doc. help_about.py # Display About IDLE dialog. @@ -59,7 +60,6 @@ macosx.py # Help IDLE run on Macs (nim). mainmenu.py # Define most of IDLE menu. multicall.py # Wrap tk widget to allow multiple calls per event (nim). outwin.py # Create window for grep output. -paragraph.py # Re-wrap multiline strings and comments. parenmatch.py # Match fenceposts: (), [], and {}. pathbrowser.py # Create path browser window. percolator.py # Manage delegator stack (nim). @@ -69,22 +69,25 @@ query.py # Query user for information redirector.py # Intercept widget subcommands (for percolator) (nim). replace.py # Search and replace pattern in text. rpc.py # Communicate between idle and user processes (nim). -rstrip.py # Strip trailing whitespace. run.py # Manage user code execution subprocess. runscript.py # Check and run user code. scrolledlist.py # Define scrolledlist widget for IDLE (nim). search.py # Search for pattern in text. searchbase.py # Define base for search, replace, and grep dialogs. searchengine.py # Define engine for all 3 search dialogs. +sidebar.py # Define line number and shell prompt sidebars. +squeezer.py # Squeeze long shell output (nim). stackviewer.py # View stack after exception. statusbar.py # Define status bar for windows (nim). tabbedpages.py # Define tabbed pages widget (nim). textview.py # Define read-only text widget (nim). +tooltip.py # Define popups for calltips, squeezer (nim). tree.py # Define tree widget, used in browsers (nim). undo.py # Manage undo stack. -util.py # Define objects imported elsewhere with no dependencies (nim) +util.py # Define common objects imported elsewhere (nim). windows.py # Manage window list and define listed top level. zoomheight.py # Zoom window to full height of screen. +zzdummy.py # Example extension. Configuration ------------- @@ -98,6 +101,7 @@ Text CREDITS.txt # not maintained, displayed by About IDLE HISTORY.txt # NEWS up to July 2001 NEWS.txt # commits, displayed by About IDLE +NEWS2.txt # commits to Python2 README.txt # this file, displayed by About IDLE TODO.txt # needs review extend.txt # about writing extensions @@ -108,13 +112,10 @@ Subdirectories Icons # small image files idle_test # files for human test and automated unit tests -Unused and Deprecated files and objects (nim) ---------------------------------------------- -tooltip.py # unused - - IDLE MENUS +========== + Top level items and most submenu items are defined in mainmenu. Extensions add submenu items when active. The names given are found, quoted, in one of these modules, paired with a '<<pseudoevent>>'. @@ -160,63 +161,68 @@ Edit Show call tip # Calltips extension and CalltipWindow (& Hyperparser) Show surrounding parens # parenmatch (& Hyperparser) +Format (Editor only) [fFR = format.FormatRegion] + Format Paragraph # format.FormatParagraph.format_paragraph_event + Indent Region # fFR.indent_region_event + Dedent Region # fFR.dedent_region_event + Comment Out Reg. # fFR.comment_region_event + Uncomment Region # fFR.uncomment_region_event + Tabify Region # fFR.tabify_region_event + Untabify Region # fFR.untabify_region_event + Toggle Tabs # format.Indents.toggle_tabs_event + New Indent Width # format.Indents.change_indentwidth_event + Strip tailing whitespace # format.rstrip + Zin # zzdummy + Zout # zzdummy + +Run (Editor only) + Run Module # runscript.ScriptBinding.run_module_event + Run... Customized # runscript.ScriptBinding.run_custom_event + Check Module # runscript.ScriptBinding.check_module_event + Python Shell # pyshell.Pyshell, pyshell.ModifiedInterpreter + Shell # pyshell View Last Restart # pyshell.PyShell.view_restart_mark Restart Shell # pyshell.PyShell.restart_shell + Previous History # history.History.history_prev + Next History # history.History.history_next Interrupt Execution # pyshell.PyShell.cancel_callback Debug (Shell only) - Go to File/Line + Go to File/Line # outwin.OutputWindow.goto_file_line debugger # debugger, debugger_r, PyShell.toggle_debugger Stack Viewer # stackviewer, PyShell.open_stack_viewer Auto-open Stack Viewer # stackviewer -Format (Editor only) - Indent Region # eEW.indent_region_event - Dedent Region # eEW.dedent_region_event - Comment Out Reg. # eEW.comment_region_event - Uncomment Region # eEW.uncomment_region_event - Tabify Region # eEW.tabify_region_event - Untabify Region # eEW.untabify_region_event - Toggle Tabs # eEW.toggle_tabs_event - New Indent Width # eEW.change_indentwidth_event - Format Paragraph # paragraph extension - --- - Strip tailing whitespace # rstrip extension - -Run (Editor only) - Python Shell # pyshell - --- - Check Module # runscript - Run Module # runscript - Options - Configure IDLE # eEW.config_dialog, configdialog - (tabs in the dialog) - Font tab # config-main.def - Highlight tab # query, config-highlight.def - Keys tab # query, config_key, config_keys.def - General tab # config_help, config-main.def - Extensions tab # config-extensions.def, corresponding .py + Configure IDLE # eEW.config_dialog, config, configdialog (cd) + (Parts of the dialog) + Buttons # cd.ConfigDialog + Font tab # cd.FontPage, config-main.def + Highlight tab # cd.HighPage, query, config-highlight.def + Keys tab # cd.KeysPage, query, config_key, config_keys.def + Windows tab # cd.WinPage, config_main.def + Shell/Ed tab # cd.ShedPage, config-main.def + Extensions tab # config-extensions.def, corresponding .py files --- - Code Context (ed)# codecontext extension + ... Code Context # codecontext + ... Line Numbers # sidebar + Zoomheight # zoomheight Window - Zoomheight # zoomheight extension - --- <open windows> # windows Help About IDLE # eEW.about_dialog, help_about.AboutDialog --- - IDLE Help # eEW.help_dialog, helpshow_idlehelp - Python Doc # eEW.python_docs + IDLE Help # eEW.help_dialog, help.show_idlehelp + Python Docs # eEW.python_docs Turtle Demo # eEW.open_turtle_demo --- <other help sources> <Context Menu> (right click) - Defined in editor, PyShelpyshellut + Defined in editor, PyShell.pyshell Cut Copy Paste @@ -232,11 +238,14 @@ Help Center Insert # eEW.center_insert_event -CODE STYLE -- Generally PEP 8. +OTHER TOPICS +============ + +Generally use PEP 8. import ------ -Put import at the top, unless there is a good reason otherwise. +Put imports at the top, unless there is a good reason otherwise. PEP 8 says to group stdlib, 3rd-party dependencies, and package imports. For idlelib, the groups are general stdlib, tkinter, and idlelib. Sort modules within each group, except that tkinter.ttk follows tkinter. From webhook-mailer at python.org Thu Aug 4 04:45:08 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 04 Aug 2022 08:45:08 -0000 Subject: [Python-checkins] [3.11] gh-91838: Use HTTPS links in docs for resources which redirect to HTTPS (GH-95527) (GH-95643) Message-ID: <mailman.477.1659602709.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d8df7e02071087894e4295e9b299689d8db74973 commit: d8df7e02071087894e4295e9b299689d8db74973 branch: 3.11 author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-04T11:45:03+03:00 summary: [3.11] gh-91838: Use HTTPS links in docs for resources which redirect to HTTPS (GH-95527) (GH-95643) If an HTTP link is redirected to a same looking HTTPS link, the latter can be used directly without changes in readability and behavior. It protects from a men-in-the-middle attack. This change does not affect Python examples.. (cherry picked from commit f79547a429d5c90af83a0da821e082cba20d4712) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M .github/CONTRIBUTING.rst M Doc/extending/index.rst M Doc/faq/design.rst M Doc/faq/extending.rst M Doc/faq/programming.rst M Doc/howto/cporting.rst M Doc/howto/curses.rst M Doc/howto/functional.rst M Doc/howto/pyporting.rst M Doc/howto/unicode.rst M Doc/howto/urllib2.rst M Doc/library/collections.rst M Doc/library/difflib.rst M Doc/library/gettext.rst M Doc/library/http.client.rst M Doc/library/importlib.resources.rst M Doc/library/json.rst M Doc/library/os.path.rst M Doc/library/os.rst M Doc/library/secrets.rst M Doc/library/shutil.rst M Doc/library/socket.rst M Doc/library/statistics.rst M Doc/library/string.rst M Doc/library/sys.rst M Doc/library/tkinter.rst M Doc/library/xmlrpc.client.rst M Doc/license.rst M Doc/reference/introduction.rst M Doc/using/cmdline.rst M Doc/using/mac.rst M Doc/whatsnew/2.5.rst M Doc/whatsnew/2.6.rst M Doc/whatsnew/2.7.rst M Doc/whatsnew/3.1.rst M Doc/whatsnew/3.2.rst M Doc/whatsnew/3.3.rst M Doc/whatsnew/3.5.rst M Doc/whatsnew/3.7.rst diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 30a39a40494f..627f57070d20 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -6,19 +6,19 @@ Build Status - main - + `Stable buildbots <http://buildbot.python.org/3.x.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.x.stable/>`_ - 3.9 - + `Stable buildbots <http://buildbot.python.org/3.9.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.9.stable/>`_ - 3.8 - + `Stable buildbots <http://buildbot.python.org/3.8.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.8.stable/>`_ - 3.7 - + `Stable buildbots <http://buildbot.python.org/3.7.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.7.stable/>`_ Thank You diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index 0994e3e8627d..01b4df6d44ac 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -27,8 +27,8 @@ Recommended third party tools This guide only covers the basic tools for creating extensions provided as part of this version of CPython. Third party tools like -`Cython <http://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, -`SWIG <http://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ +`Cython <https://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, +`SWIG <https://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ offer both simpler and more sophisticated approaches to creating C and C++ extensions for Python. diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 794b69795bac..9da1d01abd6f 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -321,8 +321,8 @@ is exactly the same type of object that a lambda expression yields) is assigned! Can Python be compiled to machine code, C or some other language? ----------------------------------------------------------------- -`Cython <http://cython.org/>`_ compiles a modified version of Python with -optional annotations into C extensions. `Nuitka <http://www.nuitka.net/>`_ is +`Cython <https://cython.org/>`_ compiles a modified version of Python with +optional annotations into C extensions. `Nuitka <https://www.nuitka.net/>`_ is an up-and-coming compiler of Python into C++ code, aiming to support the full Python language. @@ -338,8 +338,8 @@ cycles and deletes the objects involved. The :mod:`gc` module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector's parameters. -Other implementations (such as `Jython <http://www.jython.org>`_ or -`PyPy <http://www.pypy.org>`_), however, can rely on a different mechanism +Other implementations (such as `Jython <https://www.jython.org>`_ or +`PyPy <https://www.pypy.org>`_), however, can rely on a different mechanism such as a full-blown garbage collector. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 1d2aca6f4c8d..318e35508eae 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -41,7 +41,7 @@ on what you're trying to do. .. XXX make sure these all work -`Cython <http://cython.org>`_ and its relative `Pyrex +`Cython <https://cython.org>`_ and its relative `Pyrex <https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having @@ -49,10 +49,10 @@ to learn Python's C API. If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library's data types and functions -with a tool such as `SWIG <http://www.swig.org>`_. `SIP +with a tool such as `SWIG <https://www.swig.org>`_. `SIP <https://riverbankcomputing.com/software/sip/intro>`__, `CXX <http://cxx.sourceforge.net/>`_ `Boost -<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave +<https://www.boost.org/libs/python/doc/index.html>`_, or `Weave <https://github.com/scipy/weave>`_ are also alternatives for wrapping C++ libraries. @@ -286,6 +286,6 @@ Can I create an object class with some methods implemented in C and others in Py Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`, :class:`dict`, etc. -The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) +The Boost Python Library (BPL, https://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL). diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 4aea1277f9e7..5b5c357d5945 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1066,7 +1066,7 @@ performance levels: detrimental to readability). If you have reached the limit of what pure Python can allow, there are tools -to take you further away. For example, `Cython <http://cython.org>`_ can +to take you further away. For example, `Cython <https://cython.org>`_ can compile a slightly modified version of Python code into a C extension, and can be used on many different platforms. Cython can take advantage of compilation (and optional type annotations) to make your code significantly diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst index ce7700fc5990..7773620b40b9 100644 --- a/Doc/howto/cporting.rst +++ b/Doc/howto/cporting.rst @@ -22,5 +22,5 @@ We recommend the following resources for porting extension modules to Python 3: .. _Migrating C extensions: http://python3porting.com/cextensions.html .. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html -.. _Cython: http://cython.org/ +.. _Cython: https://cython.org/ .. _CFFI: https://cffi.readthedocs.io/en/latest/ diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index 26c4ece5ae6d..48add160c884 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -536,10 +536,10 @@ Patches adding support for these would be welcome; see `the Python Developer's Guide <https://devguide.python.org/>`_ to learn more about submitting patches to Python. -* `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_: +* `Writing Programs with NCURSES <https://invisible-island.net/ncurses/ncurses-intro.html>`_: a lengthy tutorial for C programmers. * `The ncurses man page <https://linux.die.net/man/3/ncurses>`_ -* `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_ +* `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. * `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index eb800152050d..1c3bd23f9fee 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1215,7 +1215,7 @@ flow inside a program. The book uses Scheme for its examples, but many of the design approaches described in these chapters are applicable to functional-style Python code. -http://www.defmacro.org/ramblings/fp.html: A general introduction to functional +https://www.defmacro.org/ramblings/fp.html: A general introduction to functional programming that uses Java examples and has a lengthy historical introduction. https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry @@ -1228,7 +1228,7 @@ https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying. Python-specific --------------- -http://gnosis.cx/TPiP/: The first chapter of David Mertz's book +https://gnosis.cx/TPiP/: The first chapter of David Mertz's book :title-reference:`Text Processing in Python` discusses functional programming for text processing, in the section titled "Utilizing Higher-Order Functions in Text Processing". diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index abcc34287e3d..add1c11be534 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -433,9 +433,9 @@ to make sure everything functions as expected in both versions of Python. .. _caniusepython3: https://pypi.org/project/caniusepython3 -.. _cheat sheet: http://python-future.org/compatible_idioms.html +.. _cheat sheet: https://python-future.org/compatible_idioms.html .. _coverage.py: https://pypi.org/project/coverage -.. _Futurize: http://python-future.org/automatic_conversion.html +.. _Futurize: https://python-future.org/automatic_conversion.html .. _importlib2: https://pypi.org/project/importlib2 .. _Modernize: https://python-modernize.readthedocs.io/ .. _mypy: http://mypy-lang.org/ @@ -445,7 +445,7 @@ to make sure everything functions as expected in both versions of Python. .. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html .. _pytype: https://github.com/google/pytype -.. _python-future: http://python-future.org/ +.. _python-future: https://python-future.org/ .. _python-porting: https://mail.python.org/pipermail/python-porting/ .. _six: https://pypi.org/project/six .. _tox: https://pypi.org/project/tox diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 535b21bd4a54..4969d2420d6a 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -167,7 +167,7 @@ On the Computerphile Youtube channel, Tom Scott briefly (9 minutes 36 seconds). To help understand the standard, Jukka Korpela has written `an introductory -guide <http://jkorpela.fi/unicode/guide.html>`_ to reading the +guide <https://jkorpela.fi/unicode/guide.html>`_ to reading the Unicode character tables. Another `good introductory article <https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_ @@ -735,7 +735,7 @@ References ---------- One section of `Mastering Python 3 Input/Output -<http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, +<https://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. The `PDF slides for Marc-Andr? Lemburg's presentation "Writing Unicode-aware @@ -745,7 +745,7 @@ discuss questions of character encodings as well as how to internationalize and localize an application. These slides cover Python 2.x only. `The Guts of Unicode in Python -<http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ +<https://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode representation in Python 3.3. diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index e1a2f48f0b08..69af3c3a85c5 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -411,7 +411,7 @@ fetched, particularly the headers sent by the server. It is currently an :class:`http.client.HTTPMessage` instance. Typical headers include 'Content-length', 'Content-type', and so on. See the -`Quick Reference to HTTP Headers <http://jkorpela.fi/http.html>`_ +`Quick Reference to HTTP Headers <https://jkorpela.fi/http.html>`_ for a useful listing of HTTP headers with brief explanations of their meaning and use. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 67b64ddda7a2..20863837fa1b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -664,7 +664,7 @@ added elements by appending to the right and popping to the left:: def moving_average(iterable, n=3): # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 - # http://en.wikipedia.org/wiki/Moving_average + # https://en.wikipedia.org/wiki/Moving_average it = iter(iterable) d = deque(itertools.islice(it, n-1)) d.appendleft(0) diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index a5ee0fb53897..feaa7c1acde1 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -353,9 +353,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. seealso:: - `Pattern Matching: The Gestalt Approach <http://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ + `Pattern Matching: The Gestalt Approach <https://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This - was published in `Dr. Dobb's Journal <http://www.drdobbs.com/>`_ in July, 1988. + was published in `Dr. Dobb's Journal <https://www.drdobbs.com/>`_ in July, 1988. .. _sequence-matcher: diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 624501952421..747f8703b750 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -445,7 +445,7 @@ There are a few tools to extract the strings meant for translation. The original GNU :program:`gettext` only supported C or C++ source code but its extended version :program:`xgettext` scans code written in a number of languages, including Python, to find strings marked as -translatable. `Babel <http://babel.pocoo.org/>`__ is a Python +translatable. `Babel <https://babel.pocoo.org/>`__ is a Python internationalization library that includes a :file:`pybabel` script to extract and compile message catalogs. Fran?ois Pinard's program called :program:`xpot` does a similar job and is available as part of diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 8bb3187ef51d..16823ec67b01 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -591,7 +591,7 @@ Here is an example session that shows how to ``POST`` requests:: 302 Found >>> data = response.read() >>> data - b'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>' + b'Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>' >>> conn.close() Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst index d367dcee7c20..827e7d8d5ace 100644 --- a/Doc/library/importlib.resources.rst +++ b/Doc/library/importlib.resources.rst @@ -26,16 +26,16 @@ for example, a package and its resources can be imported from a zip file using This module provides functionality similar to `pkg_resources <https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_ `Basic Resource Access - <http://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access>`_ + <https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access>`_ without the performance overhead of that package. This makes reading resources included in packages easier, with more stable and consistent semantics. The standalone backport of this module provides more information on `using importlib.resources - <http://importlib-resources.readthedocs.io/en/latest/using.html>`_ and + <https://importlib-resources.readthedocs.io/en/latest/using.html>`_ and `migrating from pkg_resources to importlib.resources - <http://importlib-resources.readthedocs.io/en/latest/migration.html>`_. + <https://importlib-resources.readthedocs.io/en/latest/migration.html>`_. :class:`Loaders <importlib.abc.Loader>` that wish to support resource reading should implement a ``get_resource_reader(fullname)`` method as specified by diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 1e203242327c..f65be85d31bf 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -226,7 +226,7 @@ Basic Usage *object_hook* is an optional function that will be called with the result of any object literal decoded (a :class:`dict`). The return value of *object_hook* will be used instead of the :class:`dict`. This feature can be used - to implement custom decoders (e.g. `JSON-RPC <http://www.jsonrpc.org>`_ + to implement custom decoders (e.g. `JSON-RPC <https://www.jsonrpc.org>`_ class hinting). *object_pairs_hook* is an optional function that will be called with the @@ -326,7 +326,7 @@ Encoders and Decoders *object_hook*, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given :class:`dict`. This can be used to provide custom deserializations (e.g. to - support `JSON-RPC <http://www.jsonrpc.org>`_ class hinting). + support `JSON-RPC <https://www.jsonrpc.org>`_ class hinting). *object_pairs_hook*, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value of diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index ce7913e3712d..f02877ebcea9 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -335,7 +335,7 @@ the :mod:`glob` module.) .. note:: On POSIX systems, in accordance with `IEEE Std 1003.1 2013 Edition; 4.13 - Pathname Resolution <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_, + Pathname Resolution <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_, if a pathname begins with exactly two slashes, the first component following the leading characters may be interpreted in an implementation-defined manner, although more than two leading characters shall be treated as a diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 8fccef2c2cf0..27b74f9f0cd7 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2504,9 +2504,9 @@ features: .. note:: On Unix-based systems, :func:`scandir` uses the system's - `opendir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ + `opendir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ and - `readdir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ + `readdir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ functions. On Windows, it uses the Win32 `FindFirstFileW <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_ and @@ -4966,7 +4966,7 @@ Random numbers :py:data:`GRND_NONBLOCK`. See also the `Linux getrandom() manual page - <http://man7.org/linux/man-pages/man2/getrandom.2.html>`_. + <https://man7.org/linux/man-pages/man2/getrandom.2.html>`_. .. availability:: Linux >= 3.17. diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index 86fa35fec59f..dc8e5f46fb58 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -153,7 +153,7 @@ Generate an eight-character alphanumeric password: .. note:: Applications should not - `store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_, + `store passwords in a recoverable format <https://cwe.mitre.org/data/definitions/257.html>`_, whether plain text or encrypted. They should be salted and hashed using a cryptographically strong one-way (irreversible) hash function. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 7d69c5ff266f..8f1668f76b90 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -801,4 +801,4 @@ Querying the size of the output terminal http://www.manpagez.com/man/3/copyfile/ .. _`Other Environment Variables`: - http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 + https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index c4bf3dcf32ac..9d1cfb510b0e 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -347,7 +347,7 @@ Constants .. seealso:: - `Secure File Descriptor Handling <http://udrepper.livejournal.com/20407.html>`_ + `Secure File Descriptor Handling <https://udrepper.livejournal.com/20407.html>`_ for a more thorough explanation. .. availability:: Linux >= 2.6.27. diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 5aef6f6f05d6..bf869903c0f8 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -938,7 +938,7 @@ Carlo simulation <https://en.wikipedia.org/wiki/Monte_Carlo_method>`_: [1.4591308524824727, 1.8035946855390597, 2.175091447274739] Normal distributions can be used to approximate `Binomial -distributions <http://mathworld.wolfram.com/BinomialDistribution.html>`_ +distributions <https://mathworld.wolfram.com/BinomialDistribution.html>`_ when the sample size is large and when the probability of a successful trial is near 50%. diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 35e9bc116803..7d0d601799f7 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -738,7 +738,7 @@ internationalization (i18n) since in that context, the simpler syntax and functionality makes it easier to translate than other built-in string formatting facilities in Python. As an example of a library built on template strings for i18n, see the -`flufl.i18n <http://flufli18n.readthedocs.io/en/latest/>`_ package. +`flufl.i18n <https://flufli18n.readthedocs.io/en/latest/>`_ package. .. index:: single: $ (dollar); in template strings diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 632ce627d86f..43db4baf62df 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1799,4 +1799,4 @@ always available. .. rubric:: Citations -.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . +.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 096a343bd955..0447b15e26fe 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -61,7 +61,7 @@ details that are unchanged. * `Python and Tkinter Programming <https://www.packtpub.com/product/python-gui-programming-with-tkinter/9781788835886>`_ By Alan Moore. (ISBN 978-1788835886) - * `Programming Python <http://learning-python.com/about-pp4e.html>`_ + * `Programming Python <https://learning-python.com/about-pp4e.html>`_ By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101) * `Tcl and the Tk Toolkit (2nd edition) <https://www.amazon.com/exec/obidos/ASIN/032133633X>`_ @@ -988,7 +988,7 @@ wherever the image was used. .. seealso:: - The `Pillow <http://python-pillow.org/>`_ package adds support for + The `Pillow <https://python-pillow.org/>`_ package adds support for formats such as BMP, JPEG, TIFF, and WebP, among others. .. _tkinter-file-handlers: diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 9f5ba46934b7..2dcf3984cf42 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -156,12 +156,12 @@ between conformable Python objects and XML on the wire. Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``, ``float`` and ``bigdecimal``. - See http://ws.apache.org/xmlrpc/types.html for a description. + See https://ws.apache.org/xmlrpc/types.html for a description. .. seealso:: - `XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ + `XML-RPC HOWTO <https://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ A good description of XML-RPC operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know. diff --git a/Doc/license.rst b/Doc/license.rst index e0276b492437..00691b30ba6d 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -353,7 +353,7 @@ Sockets The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and :func:`getnameinfo`, which are coded in separate source files from the WIDE -Project, http://www.wide.ad.jp/. :: +Project, https://www.wide.ad.jp/. :: Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. All rights reserved. diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 72e874ee98e4..914a11556c94 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -54,7 +54,7 @@ Jython Python implemented in Java. This implementation can be used as a scripting language for Java applications, or can be used to create applications using the Java class libraries. It is also often used to create tests for Java libraries. - More information can be found at `the Jython website <http://www.jython.org/>`_. + More information can be found at `the Jython website <https://www.jython.org/>`_. Python for .NET This implementation actually uses the CPython implementation, but is a managed @@ -66,7 +66,7 @@ IronPython An alternate Python for .NET. Unlike Python.NET, this is a complete Python implementation that generates IL, and compiles Python code directly to .NET assemblies. It was created by Jim Hugunin, the original creator of Jython. For - more information, see `the IronPython website <http://ironpython.net/>`_. + more information, see `the IronPython website <https://ironpython.net/>`_. PyPy An implementation of Python written completely in Python. It supports several @@ -74,7 +74,7 @@ PyPy and a Just in Time compiler. One of the goals of the project is to encourage experimentation with the language itself by making it easier to modify the interpreter (since it is written in Python). Additional information is - available on `the PyPy project's home page <http://pypy.org/>`_. + available on `the PyPy project's home page <https://pypy.org/>`_. Each of these implementations varies in some way from the language as documented in this manual, or introduces specific information beyond what's covered in the diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index d40155edf3f5..fc8eee3d7392 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -582,7 +582,7 @@ Options you shouldn't use Reserved for use by Jython_. -.. _Jython: http://www.jython.org/ +.. _Jython: https://www.jython.org/ .. _using-on-envvars: diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index f7db038430b6..f85b5bd2e713 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -65,7 +65,7 @@ number of standard Unix command line editors, :program:`vim` and :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see https://macromates.com/). Other editors include -:program:`Gvim` (http://macvim-dev.github.io/macvim/) and :program:`Aquamacs` +:program:`Gvim` (https://macvim-dev.github.io/macvim/) and :program:`Aquamacs` (http://aquamacs.org/). To run your script from the Terminal window you must make sure that diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 1b1fb3be9cab..f580c822dfdd 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -1930,7 +1930,7 @@ with the same digest state. The sqlite3 package ------------------- -The pysqlite module (http://www.pysqlite.org), a wrapper for the SQLite embedded +The pysqlite module (https://www.pysqlite.org), a wrapper for the SQLite embedded database, has been added to the standard library under the package name :mod:`sqlite3`. diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 7524da896393..eaca3165c07c 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -176,7 +176,7 @@ Hosting of the Python bug tracker is kindly provided by of Stellenbosch, South Africa. Martin von L?wis put a lot of effort into importing existing bugs and patches from SourceForge; his scripts for this import operation are at -``http://svn.python.org/view/tracker/importer/`` and may be useful to +``https://svn.python.org/view/tracker/importer/`` and may be useful to other projects wishing to move from SourceForge to Roundup. .. seealso:: @@ -184,13 +184,13 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.python.org The Python bug tracker. - http://bugs.jython.org: + https://bugs.jython.org: The Jython bug tracker. http://roundup.sourceforge.net/ Roundup downloads and documentation. - http://svn.python.org/view/tracker/importer/ + https://svn.python.org/view/tracker/importer/ Martin von L?wis's conversion scripts. New Documentation Format: reStructuredText Using Sphinx @@ -1433,7 +1433,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6. `Scheme's numerical tower <https://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual. - `Scheme's number datatypes <http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. + `Scheme's number datatypes <https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. The :mod:`fractions` Module diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index f753055c16ee..d48a9f7c45f8 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -299,7 +299,7 @@ modules. constructor was extended with an *object_pairs_hook* parameter to allow :class:`OrderedDict` instances to be built by the decoder. Support was also added for third-party tools like - `PyYAML <http://pyyaml.org/>`_. + `PyYAML <https://pyyaml.org/>`_. .. seealso:: @@ -1048,7 +1048,7 @@ changes, or look through the Subversion logs for all the details. The new version features better Python 3.x compatibility, various bug fixes, and adds several new BerkeleyDB flags and methods. (Updated by Jes?s Cea Avi?n; :issue:`8156`. The pybsddb - changelog can be read at http://hg.jcea.es/pybsddb/file/tip/ChangeLog.) + changelog can be read at https://hg.jcea.es/pybsddb/file/tip/ChangeLog.) * The :mod:`bz2` module's :class:`~bz2.BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f:``. @@ -1831,7 +1831,7 @@ packaged as the :mod:`unittest2` package, from https://pypi.org/project/unittest2. When used from the command line, the module can automatically discover -tests. It's not as fancy as `py.test <http://pytest.org>`__ or +tests. It's not as fancy as `py.test <https://pytest.org>`__ or `nose <https://nose.readthedocs.io/>`__, but provides a simple way to run tests kept within a set of package directories. For example, the following command will search the :file:`test/` subdirectory for @@ -2692,7 +2692,7 @@ As part of this change, the :ref:`installing-index` and completely redesigned as short getting started and FAQ documents. Most packaging documentation has now been moved out to the Python Packaging Authority maintained `Python Packaging User Guide -<http://packaging.python.org>`__ and the documentation of the individual +<https://packaging.python.org>`__ and the documentation of the individual projects. However, as this migration is currently still incomplete, the legacy diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index 3d89b97fa8f1..6ce6358d49fb 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -72,7 +72,7 @@ order. The *_asdict()* method for :func:`collections.namedtuple` now returns an ordered dictionary with the values appearing in the same order as the underlying tuple indices. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also added for third-party tools like `PyYAML <http://pyyaml.org/>`_. +Support was also added for third-party tools like `PyYAML <https://pyyaml.org/>`_. .. seealso:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 125eed6b0cbc..8a2159d45cec 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -2507,7 +2507,7 @@ IDLE Code Repository =============== -In addition to the existing Subversion code repository at http://svn.python.org +In addition to the existing Subversion code repository at https://svn.python.org there is now a `Mercurial <https://www.mercurial-scm.org/>`_ repository at https://hg.python.org/\ . diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 0f989464c9c8..1b5b6831e430 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1106,7 +1106,7 @@ the precision is user configurable, the exact figures may vary. For example, in integer bignum arithmetic the differences can be significantly higher. The following table is meant as an illustration. Benchmarks are available -at http://www.bytereef.org/mpdecimal/quickstart.html. +at https://www.bytereef.org/mpdecimal/quickstart.html. +---------+-------------+--------------+-------------+ | | decimal.py | _decimal | speedup | diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index 1defee4090f2..89b8eefb6719 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -1253,7 +1253,7 @@ imghdr ------ The :func:`~imghdr.what` function now recognizes the -`OpenEXR <http://www.openexr.com>`_ format +`OpenEXR <https://www.openexr.com>`_ format (contributed by Martin Vignali and Claudiu Popa in :issue:`20295`), and the `WebP <https://en.wikipedia.org/wiki/WebP>`_ format (contributed by Fabrice Aneche and Claudiu Popa in :issue:`20197`.) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 68901fa27ecc..545b7c738a4b 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -611,7 +611,7 @@ Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`. .. seealso:: - `importlib_resources <http://importlib-resources.readthedocs.io/en/latest/>`_ + `importlib_resources <https://importlib-resources.readthedocs.io/en/latest/>`_ -- a PyPI backport for earlier Python versions. From webhook-mailer at python.org Thu Aug 4 05:19:48 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 04 Aug 2022 09:19:48 -0000 Subject: [Python-checkins] [3.10] gh-91838: Use HTTPS links in docs for resources which redirect to HTTPS (GH-95527) (GH-95644) Message-ID: <mailman.478.1659604789.3313.python-checkins@python.org> https://github.com/python/cpython/commit/54d4b4d992566909182e843f1798534c1853b386 commit: 54d4b4d992566909182e843f1798534c1853b386 branch: 3.10 author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-04T12:19:44+03:00 summary: [3.10] gh-91838: Use HTTPS links in docs for resources which redirect to HTTPS (GH-95527) (GH-95644) If an HTTP link is redirected to a same looking HTTPS link, the latter can be used directly without changes in readability and behavior. It protects from a men-in-the-middle attack. This change does not affect Python examples.. (cherry picked from commit f79547a429d5c90af83a0da821e082cba20d4712) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M .github/CONTRIBUTING.rst M Doc/extending/index.rst M Doc/faq/design.rst M Doc/faq/extending.rst M Doc/faq/programming.rst M Doc/howto/cporting.rst M Doc/howto/curses.rst M Doc/howto/functional.rst M Doc/howto/pyporting.rst M Doc/howto/unicode.rst M Doc/howto/urllib2.rst M Doc/library/collections.rst M Doc/library/difflib.rst M Doc/library/gettext.rst M Doc/library/http.client.rst M Doc/library/json.rst M Doc/library/os.path.rst M Doc/library/os.rst M Doc/library/secrets.rst M Doc/library/shutil.rst M Doc/library/socket.rst M Doc/library/statistics.rst M Doc/library/string.rst M Doc/library/sys.rst M Doc/library/tkinter.rst M Doc/library/xmlrpc.client.rst M Doc/license.rst M Doc/reference/introduction.rst M Doc/using/cmdline.rst M Doc/using/mac.rst M Doc/whatsnew/2.5.rst M Doc/whatsnew/2.6.rst M Doc/whatsnew/2.7.rst M Doc/whatsnew/3.1.rst M Doc/whatsnew/3.2.rst M Doc/whatsnew/3.3.rst M Doc/whatsnew/3.5.rst M Doc/whatsnew/3.7.rst diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index a81935d3c9da..31d8e8578ffa 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -6,19 +6,19 @@ Build Status - master - + `Stable buildbots <http://buildbot.python.org/3.x.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.x.stable/>`_ - 3.9 - + `Stable buildbots <http://buildbot.python.org/3.9.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.9.stable/>`_ - 3.8 - + `Stable buildbots <http://buildbot.python.org/3.8.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.8.stable/>`_ - 3.7 - + `Stable buildbots <http://buildbot.python.org/3.7.stable/>`_ + + `Stable buildbots <https://buildbot.python.org/3.7.stable/>`_ Thank You diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index 0994e3e8627d..01b4df6d44ac 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -27,8 +27,8 @@ Recommended third party tools This guide only covers the basic tools for creating extensions provided as part of this version of CPython. Third party tools like -`Cython <http://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, -`SWIG <http://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ +`Cython <https://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, +`SWIG <https://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ offer both simpler and more sophisticated approaches to creating C and C++ extensions for Python. diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 794b69795bac..9da1d01abd6f 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -321,8 +321,8 @@ is exactly the same type of object that a lambda expression yields) is assigned! Can Python be compiled to machine code, C or some other language? ----------------------------------------------------------------- -`Cython <http://cython.org/>`_ compiles a modified version of Python with -optional annotations into C extensions. `Nuitka <http://www.nuitka.net/>`_ is +`Cython <https://cython.org/>`_ compiles a modified version of Python with +optional annotations into C extensions. `Nuitka <https://www.nuitka.net/>`_ is an up-and-coming compiler of Python into C++ code, aiming to support the full Python language. @@ -338,8 +338,8 @@ cycles and deletes the objects involved. The :mod:`gc` module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector's parameters. -Other implementations (such as `Jython <http://www.jython.org>`_ or -`PyPy <http://www.pypy.org>`_), however, can rely on a different mechanism +Other implementations (such as `Jython <https://www.jython.org>`_ or +`PyPy <https://www.pypy.org>`_), however, can rely on a different mechanism such as a full-blown garbage collector. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 1d2aca6f4c8d..318e35508eae 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -41,7 +41,7 @@ on what you're trying to do. .. XXX make sure these all work -`Cython <http://cython.org>`_ and its relative `Pyrex +`Cython <https://cython.org>`_ and its relative `Pyrex <https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having @@ -49,10 +49,10 @@ to learn Python's C API. If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library's data types and functions -with a tool such as `SWIG <http://www.swig.org>`_. `SIP +with a tool such as `SWIG <https://www.swig.org>`_. `SIP <https://riverbankcomputing.com/software/sip/intro>`__, `CXX <http://cxx.sourceforge.net/>`_ `Boost -<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave +<https://www.boost.org/libs/python/doc/index.html>`_, or `Weave <https://github.com/scipy/weave>`_ are also alternatives for wrapping C++ libraries. @@ -286,6 +286,6 @@ Can I create an object class with some methods implemented in C and others in Py Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`, :class:`dict`, etc. -The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) +The Boost Python Library (BPL, https://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL). diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index db4d0572cdbb..646457b44514 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1066,7 +1066,7 @@ performance levels: detrimental to readability). If you have reached the limit of what pure Python can allow, there are tools -to take you further away. For example, `Cython <http://cython.org>`_ can +to take you further away. For example, `Cython <https://cython.org>`_ can compile a slightly modified version of Python code into a C extension, and can be used on many different platforms. Cython can take advantage of compilation (and optional type annotations) to make your code significantly diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst index ce7700fc5990..7773620b40b9 100644 --- a/Doc/howto/cporting.rst +++ b/Doc/howto/cporting.rst @@ -22,5 +22,5 @@ We recommend the following resources for porting extension modules to Python 3: .. _Migrating C extensions: http://python3porting.com/cextensions.html .. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html -.. _Cython: http://cython.org/ +.. _Cython: https://cython.org/ .. _CFFI: https://cffi.readthedocs.io/en/latest/ diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index c0149ffff377..fdb0dd4352fc 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -537,10 +537,10 @@ Patches adding support for these would be welcome; see `the Python Developer's Guide <https://devguide.python.org/>`_ to learn more about submitting patches to Python. -* `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_: +* `Writing Programs with NCURSES <https://invisible-island.net/ncurses/ncurses-intro.html>`_: a lengthy tutorial for C programmers. * `The ncurses man page <https://linux.die.net/man/3/ncurses>`_ -* `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_ +* `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. * `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index eb800152050d..1c3bd23f9fee 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1215,7 +1215,7 @@ flow inside a program. The book uses Scheme for its examples, but many of the design approaches described in these chapters are applicable to functional-style Python code. -http://www.defmacro.org/ramblings/fp.html: A general introduction to functional +https://www.defmacro.org/ramblings/fp.html: A general introduction to functional programming that uses Java examples and has a lengthy historical introduction. https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry @@ -1228,7 +1228,7 @@ https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying. Python-specific --------------- -http://gnosis.cx/TPiP/: The first chapter of David Mertz's book +https://gnosis.cx/TPiP/: The first chapter of David Mertz's book :title-reference:`Text Processing in Python` discusses functional programming for text processing, in the section titled "Utilizing Higher-Order Functions in Text Processing". diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index abcc34287e3d..add1c11be534 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -433,9 +433,9 @@ to make sure everything functions as expected in both versions of Python. .. _caniusepython3: https://pypi.org/project/caniusepython3 -.. _cheat sheet: http://python-future.org/compatible_idioms.html +.. _cheat sheet: https://python-future.org/compatible_idioms.html .. _coverage.py: https://pypi.org/project/coverage -.. _Futurize: http://python-future.org/automatic_conversion.html +.. _Futurize: https://python-future.org/automatic_conversion.html .. _importlib2: https://pypi.org/project/importlib2 .. _Modernize: https://python-modernize.readthedocs.io/ .. _mypy: http://mypy-lang.org/ @@ -445,7 +445,7 @@ to make sure everything functions as expected in both versions of Python. .. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html .. _pytype: https://github.com/google/pytype -.. _python-future: http://python-future.org/ +.. _python-future: https://python-future.org/ .. _python-porting: https://mail.python.org/pipermail/python-porting/ .. _six: https://pypi.org/project/six .. _tox: https://pypi.org/project/tox diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 535b21bd4a54..4969d2420d6a 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -167,7 +167,7 @@ On the Computerphile Youtube channel, Tom Scott briefly (9 minutes 36 seconds). To help understand the standard, Jukka Korpela has written `an introductory -guide <http://jkorpela.fi/unicode/guide.html>`_ to reading the +guide <https://jkorpela.fi/unicode/guide.html>`_ to reading the Unicode character tables. Another `good introductory article <https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_ @@ -735,7 +735,7 @@ References ---------- One section of `Mastering Python 3 Input/Output -<http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, +<https://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. The `PDF slides for Marc-Andr? Lemburg's presentation "Writing Unicode-aware @@ -745,7 +745,7 @@ discuss questions of character encodings as well as how to internationalize and localize an application. These slides cover Python 2.x only. `The Guts of Unicode in Python -<http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ +<https://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode representation in Python 3.3. diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index e1a2f48f0b08..69af3c3a85c5 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -411,7 +411,7 @@ fetched, particularly the headers sent by the server. It is currently an :class:`http.client.HTTPMessage` instance. Typical headers include 'Content-length', 'Content-type', and so on. See the -`Quick Reference to HTTP Headers <http://jkorpela.fi/http.html>`_ +`Quick Reference to HTTP Headers <https://jkorpela.fi/http.html>`_ for a useful listing of HTTP headers with brief explanations of their meaning and use. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 67b64ddda7a2..20863837fa1b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -664,7 +664,7 @@ added elements by appending to the right and popping to the left:: def moving_average(iterable, n=3): # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 - # http://en.wikipedia.org/wiki/Moving_average + # https://en.wikipedia.org/wiki/Moving_average it = iter(iterable) d = deque(itertools.islice(it, n-1)) d.appendleft(0) diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index a5ee0fb53897..feaa7c1acde1 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -353,9 +353,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. seealso:: - `Pattern Matching: The Gestalt Approach <http://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ + `Pattern Matching: The Gestalt Approach <https://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This - was published in `Dr. Dobb's Journal <http://www.drdobbs.com/>`_ in July, 1988. + was published in `Dr. Dobb's Journal <https://www.drdobbs.com/>`_ in July, 1988. .. _sequence-matcher: diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index ec2c12806b41..2a9946d7588c 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -528,7 +528,7 @@ There are a few tools to extract the strings meant for translation. The original GNU :program:`gettext` only supported C or C++ source code but its extended version :program:`xgettext` scans code written in a number of languages, including Python, to find strings marked as -translatable. `Babel <http://babel.pocoo.org/>`__ is a Python +translatable. `Babel <https://babel.pocoo.org/>`__ is a Python internationalization library that includes a :file:`pybabel` script to extract and compile message catalogs. Fran?ois Pinard's program called :program:`xpot` does a similar job and is available as part of diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index e605f7b8b141..380f52b2558f 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -589,7 +589,7 @@ Here is an example session that shows how to ``POST`` requests:: 302 Found >>> data = response.read() >>> data - b'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>' + b'Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>' >>> conn.close() Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 608e70df5b14..4dbc543fc0e4 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -226,7 +226,7 @@ Basic Usage *object_hook* is an optional function that will be called with the result of any object literal decoded (a :class:`dict`). The return value of *object_hook* will be used instead of the :class:`dict`. This feature can be used - to implement custom decoders (e.g. `JSON-RPC <http://www.jsonrpc.org>`_ + to implement custom decoders (e.g. `JSON-RPC <https://www.jsonrpc.org>`_ class hinting). *object_pairs_hook* is an optional function that will be called with the @@ -326,7 +326,7 @@ Encoders and Decoders *object_hook*, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given :class:`dict`. This can be used to provide custom deserializations (e.g. to - support `JSON-RPC <http://www.jsonrpc.org>`_ class hinting). + support `JSON-RPC <https://www.jsonrpc.org>`_ class hinting). *object_pairs_hook*, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value of diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index ce7913e3712d..f02877ebcea9 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -335,7 +335,7 @@ the :mod:`glob` module.) .. note:: On POSIX systems, in accordance with `IEEE Std 1003.1 2013 Edition; 4.13 - Pathname Resolution <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_, + Pathname Resolution <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_, if a pathname begins with exactly two slashes, the first component following the leading characters may be interpreted in an implementation-defined manner, although more than two leading characters shall be treated as a diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6694768419cb..c8bb5a902d81 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2439,9 +2439,9 @@ features: .. note:: On Unix-based systems, :func:`scandir` uses the system's - `opendir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ + `opendir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ and - `readdir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ + `readdir() <https://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ functions. On Windows, it uses the Win32 `FindFirstFileW <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_ and @@ -4870,7 +4870,7 @@ Random numbers :py:data:`GRND_NONBLOCK`. See also the `Linux getrandom() manual page - <http://man7.org/linux/man-pages/man2/getrandom.2.html>`_. + <https://man7.org/linux/man-pages/man2/getrandom.2.html>`_. .. availability:: Linux 3.17 and newer. diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index 86fa35fec59f..dc8e5f46fb58 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -153,7 +153,7 @@ Generate an eight-character alphanumeric password: .. note:: Applications should not - `store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_, + `store passwords in a recoverable format <https://cwe.mitre.org/data/definitions/257.html>`_, whether plain text or encrypted. They should be salted and hashed using a cryptographically strong one-way (irreversible) hash function. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index cb672d9479cc..311aae414aea 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -791,4 +791,4 @@ Querying the size of the output terminal http://www.manpagez.com/man/3/copyfile/ .. _`Other Environment Variables`: - http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 + https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index bbf2ea180f5d..9c94b86991ca 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -340,7 +340,7 @@ Constants .. seealso:: - `Secure File Descriptor Handling <http://udrepper.livejournal.com/20407.html>`_ + `Secure File Descriptor Handling <https://udrepper.livejournal.com/20407.html>`_ for a more thorough explanation. .. availability:: Linux >= 2.6.27. diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 6484e74422dc..1ff6faec151f 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -911,7 +911,7 @@ Carlo simulation <https://en.wikipedia.org/wiki/Monte_Carlo_method>`_: [1.4591308524824727, 1.8035946855390597, 2.175091447274739] Normal distributions can be used to approximate `Binomial -distributions <http://mathworld.wolfram.com/BinomialDistribution.html>`_ +distributions <https://mathworld.wolfram.com/BinomialDistribution.html>`_ when the sample size is large and when the probability of a successful trial is near 50%. diff --git a/Doc/library/string.rst b/Doc/library/string.rst index b7108641805e..ccdda4a097d6 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -729,7 +729,7 @@ internationalization (i18n) since in that context, the simpler syntax and functionality makes it easier to translate than other built-in string formatting facilities in Python. As an example of a library built on template strings for i18n, see the -`flufl.i18n <http://flufli18n.readthedocs.io/en/latest/>`_ package. +`flufl.i18n <https://flufli18n.readthedocs.io/en/latest/>`_ package. .. index:: single: $ (dollar); in template strings diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index c1a8b01f438d..7f066d3cd6b7 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1744,4 +1744,4 @@ always available. .. rubric:: Citations -.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . +.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 096a343bd955..0447b15e26fe 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -61,7 +61,7 @@ details that are unchanged. * `Python and Tkinter Programming <https://www.packtpub.com/product/python-gui-programming-with-tkinter/9781788835886>`_ By Alan Moore. (ISBN 978-1788835886) - * `Programming Python <http://learning-python.com/about-pp4e.html>`_ + * `Programming Python <https://learning-python.com/about-pp4e.html>`_ By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101) * `Tcl and the Tk Toolkit (2nd edition) <https://www.amazon.com/exec/obidos/ASIN/032133633X>`_ @@ -988,7 +988,7 @@ wherever the image was used. .. seealso:: - The `Pillow <http://python-pillow.org/>`_ package adds support for + The `Pillow <https://python-pillow.org/>`_ package adds support for formats such as BMP, JPEG, TIFF, and WebP, among others. .. _tkinter-file-handlers: diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 0d9bfd51f1e4..247509d58168 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -154,12 +154,12 @@ between conformable Python objects and XML on the wire. Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``, ``float`` and ``bigdecimal``. - See http://ws.apache.org/xmlrpc/types.html for a description. + See https://ws.apache.org/xmlrpc/types.html for a description. .. seealso:: - `XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ + `XML-RPC HOWTO <https://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ A good description of XML-RPC operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know. diff --git a/Doc/license.rst b/Doc/license.rst index e0276b492437..00691b30ba6d 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -353,7 +353,7 @@ Sockets The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and :func:`getnameinfo`, which are coded in separate source files from the WIDE -Project, http://www.wide.ad.jp/. :: +Project, https://www.wide.ad.jp/. :: Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. All rights reserved. diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 72e874ee98e4..914a11556c94 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -54,7 +54,7 @@ Jython Python implemented in Java. This implementation can be used as a scripting language for Java applications, or can be used to create applications using the Java class libraries. It is also often used to create tests for Java libraries. - More information can be found at `the Jython website <http://www.jython.org/>`_. + More information can be found at `the Jython website <https://www.jython.org/>`_. Python for .NET This implementation actually uses the CPython implementation, but is a managed @@ -66,7 +66,7 @@ IronPython An alternate Python for .NET. Unlike Python.NET, this is a complete Python implementation that generates IL, and compiles Python code directly to .NET assemblies. It was created by Jim Hugunin, the original creator of Jython. For - more information, see `the IronPython website <http://ironpython.net/>`_. + more information, see `the IronPython website <https://ironpython.net/>`_. PyPy An implementation of Python written completely in Python. It supports several @@ -74,7 +74,7 @@ PyPy and a Just in Time compiler. One of the goals of the project is to encourage experimentation with the language itself by making it easier to modify the interpreter (since it is written in Python). Additional information is - available on `the PyPy project's home page <http://pypy.org/>`_. + available on `the PyPy project's home page <https://pypy.org/>`_. Each of these implementations varies in some way from the language as documented in this manual, or introduces specific information beyond what's covered in the diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index b1e297d52584..d07118bd1b90 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -517,7 +517,7 @@ Options you shouldn't use Reserved for use by Jython_. -.. _Jython: http://www.jython.org/ +.. _Jython: https://www.jython.org/ .. _using-on-envvars: diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index f7db038430b6..f85b5bd2e713 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -65,7 +65,7 @@ number of standard Unix command line editors, :program:`vim` and :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see https://macromates.com/). Other editors include -:program:`Gvim` (http://macvim-dev.github.io/macvim/) and :program:`Aquamacs` +:program:`Gvim` (https://macvim-dev.github.io/macvim/) and :program:`Aquamacs` (http://aquamacs.org/). To run your script from the Terminal window you must make sure that diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 1b1fb3be9cab..f580c822dfdd 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -1930,7 +1930,7 @@ with the same digest state. The sqlite3 package ------------------- -The pysqlite module (http://www.pysqlite.org), a wrapper for the SQLite embedded +The pysqlite module (https://www.pysqlite.org), a wrapper for the SQLite embedded database, has been added to the standard library under the package name :mod:`sqlite3`. diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 7524da896393..eaca3165c07c 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -176,7 +176,7 @@ Hosting of the Python bug tracker is kindly provided by of Stellenbosch, South Africa. Martin von L?wis put a lot of effort into importing existing bugs and patches from SourceForge; his scripts for this import operation are at -``http://svn.python.org/view/tracker/importer/`` and may be useful to +``https://svn.python.org/view/tracker/importer/`` and may be useful to other projects wishing to move from SourceForge to Roundup. .. seealso:: @@ -184,13 +184,13 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.python.org The Python bug tracker. - http://bugs.jython.org: + https://bugs.jython.org: The Jython bug tracker. http://roundup.sourceforge.net/ Roundup downloads and documentation. - http://svn.python.org/view/tracker/importer/ + https://svn.python.org/view/tracker/importer/ Martin von L?wis's conversion scripts. New Documentation Format: reStructuredText Using Sphinx @@ -1433,7 +1433,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6. `Scheme's numerical tower <https://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual. - `Scheme's number datatypes <http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. + `Scheme's number datatypes <https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. The :mod:`fractions` Module diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index b74a45692915..f79dcdc74bcf 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -299,7 +299,7 @@ modules. constructor was extended with an *object_pairs_hook* parameter to allow :class:`OrderedDict` instances to be built by the decoder. Support was also added for third-party tools like - `PyYAML <http://pyyaml.org/>`_. + `PyYAML <https://pyyaml.org/>`_. .. seealso:: @@ -1048,7 +1048,7 @@ changes, or look through the Subversion logs for all the details. The new version features better Python 3.x compatibility, various bug fixes, and adds several new BerkeleyDB flags and methods. (Updated by Jes?s Cea Avi?n; :issue:`8156`. The pybsddb - changelog can be read at http://hg.jcea.es/pybsddb/file/tip/ChangeLog.) + changelog can be read at https://hg.jcea.es/pybsddb/file/tip/ChangeLog.) * The :mod:`bz2` module's :class:`~bz2.BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f:``. @@ -1831,7 +1831,7 @@ packaged as the :mod:`unittest2` package, from https://pypi.org/project/unittest2. When used from the command line, the module can automatically discover -tests. It's not as fancy as `py.test <http://pytest.org>`__ or +tests. It's not as fancy as `py.test <https://pytest.org>`__ or `nose <https://nose.readthedocs.io/>`__, but provides a simple way to run tests kept within a set of package directories. For example, the following command will search the :file:`test/` subdirectory for @@ -2692,7 +2692,7 @@ As part of this change, the :ref:`installing-index` and completely redesigned as short getting started and FAQ documents. Most packaging documentation has now been moved out to the Python Packaging Authority maintained `Python Packaging User Guide -<http://packaging.python.org>`__ and the documentation of the individual +<https://packaging.python.org>`__ and the documentation of the individual projects. However, as this migration is currently still incomplete, the legacy diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index 3d89b97fa8f1..6ce6358d49fb 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -72,7 +72,7 @@ order. The *_asdict()* method for :func:`collections.namedtuple` now returns an ordered dictionary with the values appearing in the same order as the underlying tuple indices. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also added for third-party tools like `PyYAML <http://pyyaml.org/>`_. +Support was also added for third-party tools like `PyYAML <https://pyyaml.org/>`_. .. seealso:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 8526fac1f629..e53955ee0cf5 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -2506,7 +2506,7 @@ IDLE Code Repository =============== -In addition to the existing Subversion code repository at http://svn.python.org +In addition to the existing Subversion code repository at https://svn.python.org there is now a `Mercurial <https://www.mercurial-scm.org/>`_ repository at https://hg.python.org/\ . diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 0f989464c9c8..1b5b6831e430 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1106,7 +1106,7 @@ the precision is user configurable, the exact figures may vary. For example, in integer bignum arithmetic the differences can be significantly higher. The following table is meant as an illustration. Benchmarks are available -at http://www.bytereef.org/mpdecimal/quickstart.html. +at https://www.bytereef.org/mpdecimal/quickstart.html. +---------+-------------+--------------+-------------+ | | decimal.py | _decimal | speedup | diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index 1defee4090f2..89b8eefb6719 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -1253,7 +1253,7 @@ imghdr ------ The :func:`~imghdr.what` function now recognizes the -`OpenEXR <http://www.openexr.com>`_ format +`OpenEXR <https://www.openexr.com>`_ format (contributed by Martin Vignali and Claudiu Popa in :issue:`20295`), and the `WebP <https://en.wikipedia.org/wiki/WebP>`_ format (contributed by Fabrice Aneche and Claudiu Popa in :issue:`20197`.) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 7d6e7f24f542..98ed72cbd110 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -611,7 +611,7 @@ Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`. .. seealso:: - `importlib_resources <http://importlib-resources.readthedocs.io/en/latest/>`_ + `importlib_resources <https://importlib-resources.readthedocs.io/en/latest/>`_ -- a PyPI backport for earlier Python versions. From webhook-mailer at python.org Thu Aug 4 06:30:33 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 04 Aug 2022 10:30:33 -0000 Subject: [Python-checkins] gh-91838: Resolve HTTP links which redirect to HTTPS (GH-95642) Message-ID: <mailman.479.1659609034.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d0d0154443cafb2f0a2cdfb6a1267d80cce8388e commit: d0d0154443cafb2f0a2cdfb6a1267d80cce8388e branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-04T13:30:05+03:00 summary: gh-91838: Resolve HTTP links which redirect to HTTPS (GH-95642) It updates links which redirect to HTTPS with different authority or path. files: M Doc/about.rst M Doc/faq/general.rst M Doc/faq/programming.rst M Doc/howto/curses.rst M Doc/install/index.rst M Doc/library/random.rst M Doc/library/stdtypes.rst M Doc/library/tkinter.rst M Doc/whatsnew/2.3.rst M Doc/whatsnew/2.5.rst M Doc/whatsnew/2.6.rst M Lib/test/datetimetester.py M Modules/_datetimemodule.c diff --git a/Doc/about.rst b/Doc/about.rst index f0b908487b2d..0ce35667924b 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -6,7 +6,7 @@ About these documents These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. -.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _reStructuredText: https://docutils.sourceforge.io/rst.html .. _Sphinx: http://sphinx-doc.org/ .. In the online version of these documents, you can submit comments and suggest @@ -21,7 +21,7 @@ Many thanks go to: * Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content; -* the `Docutils <http://docutils.sourceforge.net/>`_ project for creating +* the `Docutils <https://docutils.sourceforge.io/>`_ project for creating reStructuredText and the Docutils suite; * Fredrik Lundh for his Alternative Python Reference project from which Sphinx got many good ideas. diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index bc4130aaa45c..510ebb5cf904 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -330,7 +330,7 @@ different companies and organizations. High-profile Python projects include `the Mailman mailing list manager <http://www.list.org>`_ and `the Zope application server -<http://www.zope.org>`_. Several Linux distributions, most notably `Red Hat +<https://www.zope.dev>`_. Several Linux distributions, most notably `Red Hat <https://www.redhat.com>`_, have written part or all of their installer and system administration software in Python. Companies that use Python internally include Google, Yahoo, and Lucasfilm Ltd. diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 5b5c357d5945..6514c00d1114 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -95,7 +95,7 @@ The following packages can help with the creation of console and GUI executables: * `Nuitka <https://nuitka.net/>`_ (Cross-platform) -* `PyInstaller <http://www.pyinstaller.org/>`_ (Cross-platform) +* `PyInstaller <https://pyinstaller.org/>`_ (Cross-platform) * `PyOxidizer <https://pyoxidizer.readthedocs.io/en/stable/>`_ (Cross-platform) * `cx_Freeze <https://marcelotduarte.github.io/cx_Freeze/>`_ (Cross-platform) * `py2app <https://github.com/ronaldoussoren/py2app>`_ (macOS only) diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index 48add160c884..83d80471ffc8 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -542,6 +542,6 @@ learn more about submitting patches to Python. * `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. -* `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: +* `"Console Applications with Urwid" <https://pyvideo.org/video/1568/console-applications-with-urwid>`_: video of a PyCon CA 2012 talk demonstrating some applications written using Urwid. diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 0923267d0660..3fc670b19142 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -1066,7 +1066,7 @@ normal libraries do. .. seealso:: - `Building Python modules on MS Windows platform with MinGW <http://old.zope.org/Members/als/tips/win32_mingw_modules>`_ + `Building Python modules on MS Windows platform with MinGW <https://old.zope.dev/Members/als/tips/win32_mingw_modules>`_ Information about building the required libraries for the MinGW environment. diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 913040052775..ad4a1ce7c312 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -494,7 +494,7 @@ Example of `statistical bootstrapping <https://en.wikipedia.org/wiki/Bootstrapping_(statistics)>`_ using resampling with replacement to estimate a confidence interval for the mean of a sample:: - # http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm + # https://www.thoughtco.com/example-of-bootstrapping-3126155 from statistics import fmean as mean from random import choices diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 33fd2831228f..2480e71dded3 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1453,7 +1453,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe <http://code.activestate.com/recipes/579000/>`_ + * The `linspace recipe <https://code.activestate.com/recipes/579000/>`_ shows how to implement a lazy version of range suitable for floating point applications. diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 0447b15e26fe..0d2b344d24f2 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -90,7 +90,7 @@ Tcl (see `Threading model`_ for details). Tk - Tk is a `Tcl package <http://wiki.tcl.tk/37432>`_ implemented in C + Tk is a `Tcl package <https://wiki.tcl-lang.org/37432>`_ implemented in C that adds custom commands to create and manipulate GUI widgets. Each :class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into it. Tk's widgets are very customizable, though at the cost of a dated appearance. diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index 745b0aa22050..55061d2a46bd 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -1082,7 +1082,7 @@ Here are all of the changes that Python 2.3 makes to the core Python language. hierarchy. Classic classes are unaffected by this change. Python 2.2 originally used a topological sort of a class's ancestors, but 2.3 now uses the C3 algorithm as described in the paper `"A Monotonic Superclass Linearization - for Dylan" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To + for Dylan" <https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To understand the motivation for this change, read Michele Simionato's article `"Python 2.3 Method Resolution Order" <http://www.phyast.pitt.edu/~micheles/mro.html>`_, or read the thread on python-dev starting with the message at diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index f580c822dfdd..ea785121db90 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -882,7 +882,7 @@ in an :c:type:`int`. The C compilers for most 64-bit platforms still define :c:type:`int` as a 32-bit type, so that meant that lists could only hold up to ``2**31 - 1`` = 2147483647 items. (There are actually a few different programming models that 64-bit C compilers can use -- see -http://www.unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the +https://unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the most commonly available model leaves :c:type:`int` as 32 bits.) A limit of 2147483647 items doesn't really matter on a 32-bit platform because diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index eaca3165c07c..3d0d18746a21 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -155,7 +155,7 @@ up different products and import some of the bugs and patches from SourceForge. Four different trackers were examined: `Jira <https://www.atlassian.com/software/jira/>`__, `Launchpad <https://launchpad.net/>`__, -`Roundup <http://roundup.sourceforge.net/>`__, and +`Roundup <https://roundup.sourceforge.io/>`__, and `Trac <https://trac.edgewall.org/>`__. The committee eventually settled on Jira and Roundup as the two candidates. Jira is a commercial product that @@ -187,7 +187,7 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.jython.org: The Jython bug tracker. - http://roundup.sourceforge.net/ + https://roundup.sourceforge.io/ Roundup downloads and documentation. https://svn.python.org/view/tracker/importer/ @@ -238,7 +238,7 @@ have adopted Sphinx as their documentation tool. `Sphinx <http://sphinx-doc.org/>`__ Documentation and code for the Sphinx toolchain. - `Docutils <http://docutils.sourceforge.net>`__ + `Docutils <https://docutils.sourceforge.io>`__ The underlying reStructuredText parser and toolset. diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 311f9db10ffe..7e7f4f33d6e5 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1,6 +1,6 @@ """Test date/time type. -See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases +See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases """ import io import itertools diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index ba24e3c12484..eca7c6b29d7a 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1,5 +1,5 @@ /* C implementation for the date/time type documented at - * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage + * https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage */ /* bpo-35081: Defining this prevents including the C API capsule; From webhook-mailer at python.org Thu Aug 4 07:21:46 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 04 Aug 2022 11:21:46 -0000 Subject: [Python-checkins] GH-92678: Fix tp_dictoffset inheritance. (GH-95596) (GH-95604) Message-ID: <mailman.480.1659612107.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2ab560105b9bfda503148e66e58d1d9a6031745e commit: 2ab560105b9bfda503148e66e58d1d9a6031745e branch: 3.11 author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-04T12:21:38+01:00 summary: GH-92678: Fix tp_dictoffset inheritance. (GH-95596) (GH-95604) * Add test for inheriting explicit __dict__ and weakref. * Restore 3.10 behavior for multiple inheritance of C extension classes that store their dictionary at the end of the struct. files: A Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst M Lib/test/test_capi.py M Modules/_testcapimodule.c M Objects/typeobject.c diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index fba78fa44395..7d766ec01787 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -608,6 +608,25 @@ def test_heaptype_with_setattro(self): del obj.value self.assertEqual(obj.pvalue, 0) + def test_multiple_inheritance_ctypes_with_weakref_or_dict(self): + + class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + pass + class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + pass + + for cls in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, + _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): + for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, + _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): + if cls is not cls2: + class S(cls, cls2): + pass + class B1(Both1, cls): + pass + class B2(Both1, cls): + pass + def test_pynumber_tobase(self): from _testcapi import pynumber_tobase self.assertEqual(pynumber_tobase(123, 2), '0b1111011') diff --git a/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst b/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst new file mode 100644 index 000000000000..6bf3d4b1abbf --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst @@ -0,0 +1,2 @@ +Restore the 3.10 behavior for multiple inheritance of C extension classes +that store their dictionary at the end of the struct. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 9022ee4d49a8..a394f4647156 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -7321,6 +7321,14 @@ static PyType_Spec HeapCTypeWithDict_spec = { HeapCTypeWithDict_slots }; +static PyType_Spec HeapCTypeWithDict2_spec = { + "_testcapi.HeapCTypeWithDict2", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + static struct PyMemberDef heapctypewithnegativedict_members[] = { {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, @@ -7380,6 +7388,14 @@ static PyType_Spec HeapCTypeWithWeakref_spec = { HeapCTypeWithWeakref_slots }; +static PyType_Spec HeapCTypeWithWeakref2_spec = { + "_testcapi.HeapCTypeWithWeakref2", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + PyDoc_STRVAR(heapctypesetattr__doc__, "A heap type without GC, but with overridden __setattr__.\n\n" "The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); @@ -7757,6 +7773,12 @@ PyInit__testcapi(void) } PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); + PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); + if (HeapCTypeWithDict2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); + PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); if (HeapCTypeWithNegativeDict == NULL) { return NULL; @@ -7775,6 +7797,12 @@ PyInit__testcapi(void) } PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); + PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); + if (HeapCTypeWithWeakref2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); + PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); if (HeapCTypeSetattr == NULL) { return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c5e832df7af2..03cc72e742b2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2224,6 +2224,11 @@ best_base(PyObject *bases) return base; } +#define ADDED_FIELD_AT_OFFSET(name, offset) \ + (type->tp_ ## name && (base->tp_ ##name == 0) && \ + type->tp_ ## name + sizeof(PyObject *) == (offset) && \ + type->tp_flags & Py_TPFLAGS_HEAPTYPE) + static int extra_ivars(PyTypeObject *type, PyTypeObject *base) { @@ -2236,10 +2241,18 @@ extra_ivars(PyTypeObject *type, PyTypeObject *base) return t_size != b_size || type->tp_itemsize != base->tp_itemsize; } - if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 && - type->tp_weaklistoffset + sizeof(PyObject *) == t_size && - type->tp_flags & Py_TPFLAGS_HEAPTYPE) + /* Check for __dict__ and __weakrefs__ slots in either order */ + if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { + t_size -= sizeof(PyObject *); + } + if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0 && + ADDED_FIELD_AT_OFFSET(dictoffset, t_size)) { t_size -= sizeof(PyObject *); + } + /* Check __weakrefs__ again, in case it precedes __dict__ */ + if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { + t_size -= sizeof(PyObject *); + } return t_size != b_size; } From webhook-mailer at python.org Thu Aug 4 08:03:17 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 04 Aug 2022 12:03:17 -0000 Subject: [Python-checkins] Revert "[3.11] GH-92678: Expose managed dict clear and visit functions (GH-95246). (#95256)" (#95647) Message-ID: <mailman.481.1659614599.3313.python-checkins@python.org> https://github.com/python/cpython/commit/312dab29a3f83940c501caadda9e653e1c7209b1 commit: 312dab29a3f83940c501caadda9e653e1c7209b1 branch: 3.11 author: Mark Shannon <mark at hotpy.org> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-04T13:03:07+01:00 summary: Revert "[3.11] GH-92678: Expose managed dict clear and visit functions (GH-95246). (#95256)" (#95647) This reverts commit 7f731943393d57cf26ed5f2353e6e53084cd55fd. files: M Include/cpython/dictobject.h M Lib/test/test_capi.py M Modules/_testcapimodule.c M Objects/dictobject.c diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index b586f75281b6..033eaeb4c975 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -76,6 +76,3 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); - -PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *self, visitproc visit, void *arg); -PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *self); diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 7d766ec01787..40750cc49324 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -724,20 +724,6 @@ def test_export_symbols(self): with self.subTest(name=name): self.assertTrue(hasattr(ctypes.pythonapi, name)) - def test_clear_managed_dict(self): - - class C: - def __init__(self): - self.a = 1 - - c = C() - _testcapi.clear_managed_dict(c) - self.assertEqual(c.__dict__, {}) - c = C() - self.assertEqual(c.__dict__, {'a':1}) - _testcapi.clear_managed_dict(c) - self.assertEqual(c.__dict__, {}) - class TestPendingCalls(unittest.TestCase): diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index a394f4647156..b0a4687a973d 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6014,14 +6014,6 @@ settrace_to_record(PyObject *self, PyObject *list) Py_RETURN_NONE; } -static PyObject * -clear_managed_dict(PyObject *self, PyObject *obj) -{ - _PyObject_ClearManagedDict(obj); - Py_RETURN_NONE; -} - - static PyObject *negative_dictoffset(PyObject *, PyObject *); static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*); @@ -6323,7 +6315,6 @@ static PyMethodDef TestMethods[] = { {"get_feature_macros", get_feature_macros, METH_NOARGS, NULL}, {"test_code_api", test_code_api, METH_NOARGS, NULL}, {"settrace_to_record", settrace_to_record, METH_O, NULL}, - {"clear_managed_dict", clear_managed_dict, METH_O, NULL}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 25e191fb8ead..ebbd22ee7c14 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -5583,35 +5583,6 @@ _PyObject_FreeInstanceAttributes(PyObject *self) free_values(*values_ptr); } -int -_PyObject_VisitManagedDict(PyObject *self, visitproc visit, void *arg) -{ - PyTypeObject *tp = Py_TYPE(self); - if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - return 0; - } - assert(tp->tp_dictoffset); - int err = _PyObject_VisitInstanceAttributes(self, visit, arg); - if (err) { - return err; - } - Py_VISIT(*_PyObject_ManagedDictPointer(self)); - return 0; -} - - -void -_PyObject_ClearManagedDict(PyObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - return; - } - _PyObject_FreeInstanceAttributes(self); - *_PyObject_ValuesPointer(self) = NULL; - Py_CLEAR(*_PyObject_ManagedDictPointer(self)); -} - PyObject * PyObject_GenericGetDict(PyObject *obj, void *context) { From webhook-mailer at python.org Thu Aug 4 09:15:06 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 13:15:06 -0000 Subject: [Python-checkins] gh-91838: Resolve HTTP links which redirect to HTTPS (GH-95642) Message-ID: <mailman.482.1659618907.3313.python-checkins@python.org> https://github.com/python/cpython/commit/be30a6dc4d7aa998526b1beb101995aa3691145f commit: be30a6dc4d7aa998526b1beb101995aa3691145f branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T06:15:01-07:00 summary: gh-91838: Resolve HTTP links which redirect to HTTPS (GH-95642) It updates links which redirect to HTTPS with different authority or path. (cherry picked from commit d0d0154443cafb2f0a2cdfb6a1267d80cce8388e) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M Doc/about.rst M Doc/faq/general.rst M Doc/faq/programming.rst M Doc/howto/curses.rst M Doc/install/index.rst M Doc/library/random.rst M Doc/library/stdtypes.rst M Doc/library/tkinter.rst M Doc/whatsnew/2.3.rst M Doc/whatsnew/2.5.rst M Doc/whatsnew/2.6.rst M Lib/test/datetimetester.py M Modules/_datetimemodule.c diff --git a/Doc/about.rst b/Doc/about.rst index f0b908487b2d..0ce35667924b 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -6,7 +6,7 @@ About these documents These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. -.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _reStructuredText: https://docutils.sourceforge.io/rst.html .. _Sphinx: http://sphinx-doc.org/ .. In the online version of these documents, you can submit comments and suggest @@ -21,7 +21,7 @@ Many thanks go to: * Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content; -* the `Docutils <http://docutils.sourceforge.net/>`_ project for creating +* the `Docutils <https://docutils.sourceforge.io/>`_ project for creating reStructuredText and the Docutils suite; * Fredrik Lundh for his Alternative Python Reference project from which Sphinx got many good ideas. diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 7723114bcc18..f77bf7e32119 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -336,7 +336,7 @@ different companies and organizations. High-profile Python projects include `the Mailman mailing list manager <http://www.list.org>`_ and `the Zope application server -<http://www.zope.org>`_. Several Linux distributions, most notably `Red Hat +<https://www.zope.dev>`_. Several Linux distributions, most notably `Red Hat <https://www.redhat.com>`_, have written part or all of their installer and system administration software in Python. Companies that use Python internally include Google, Yahoo, and Lucasfilm Ltd. diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 646457b44514..79176d02fb51 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -95,7 +95,7 @@ The following packages can help with the creation of console and GUI executables: * `Nuitka <https://nuitka.net/>`_ (Cross-platform) -* `PyInstaller <http://www.pyinstaller.org/>`_ (Cross-platform) +* `PyInstaller <https://pyinstaller.org/>`_ (Cross-platform) * `PyOxidizer <https://pyoxidizer.readthedocs.io/en/stable/>`_ (Cross-platform) * `cx_Freeze <https://marcelotduarte.github.io/cx_Freeze/>`_ (Cross-platform) * `py2app <https://github.com/ronaldoussoren/py2app>`_ (macOS only) diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index fdb0dd4352fc..b4de190f3c89 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -543,6 +543,6 @@ learn more about submitting patches to Python. * `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. -* `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: +* `"Console Applications with Urwid" <https://pyvideo.org/video/1568/console-applications-with-urwid>`_: video of a PyCon CA 2012 talk demonstrating some applications written using Urwid. diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 63b64b95fc72..84df5e7cb368 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -1062,7 +1062,7 @@ normal libraries do. .. seealso:: - `Building Python modules on MS Windows platform with MinGW <http://old.zope.org/Members/als/tips/win32_mingw_modules>`_ + `Building Python modules on MS Windows platform with MinGW <https://old.zope.dev/Members/als/tips/win32_mingw_modules>`_ Information about building the required libraries for the MinGW environment. diff --git a/Doc/library/random.rst b/Doc/library/random.rst index b9c33af59c8f..7cfa2755851e 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -474,7 +474,7 @@ Example of `statistical bootstrapping <https://en.wikipedia.org/wiki/Bootstrapping_(statistics)>`_ using resampling with replacement to estimate a confidence interval for the mean of a sample:: - # http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm + # https://www.thoughtco.com/example-of-bootstrapping-3126155 from statistics import fmean as mean from random import choices diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index dd7c1ab5c9d1..5c0d259ba989 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1415,7 +1415,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe <http://code.activestate.com/recipes/579000/>`_ + * The `linspace recipe <https://code.activestate.com/recipes/579000/>`_ shows how to implement a lazy version of range suitable for floating point applications. diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 0447b15e26fe..0d2b344d24f2 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -90,7 +90,7 @@ Tcl (see `Threading model`_ for details). Tk - Tk is a `Tcl package <http://wiki.tcl.tk/37432>`_ implemented in C + Tk is a `Tcl package <https://wiki.tcl-lang.org/37432>`_ implemented in C that adds custom commands to create and manipulate GUI widgets. Each :class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into it. Tk's widgets are very customizable, though at the cost of a dated appearance. diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index 745b0aa22050..55061d2a46bd 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -1082,7 +1082,7 @@ Here are all of the changes that Python 2.3 makes to the core Python language. hierarchy. Classic classes are unaffected by this change. Python 2.2 originally used a topological sort of a class's ancestors, but 2.3 now uses the C3 algorithm as described in the paper `"A Monotonic Superclass Linearization - for Dylan" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To + for Dylan" <https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To understand the motivation for this change, read Michele Simionato's article `"Python 2.3 Method Resolution Order" <http://www.phyast.pitt.edu/~micheles/mro.html>`_, or read the thread on python-dev starting with the message at diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index f580c822dfdd..ea785121db90 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -882,7 +882,7 @@ in an :c:type:`int`. The C compilers for most 64-bit platforms still define :c:type:`int` as a 32-bit type, so that meant that lists could only hold up to ``2**31 - 1`` = 2147483647 items. (There are actually a few different programming models that 64-bit C compilers can use -- see -http://www.unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the +https://unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the most commonly available model leaves :c:type:`int` as 32 bits.) A limit of 2147483647 items doesn't really matter on a 32-bit platform because diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index eaca3165c07c..3d0d18746a21 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -155,7 +155,7 @@ up different products and import some of the bugs and patches from SourceForge. Four different trackers were examined: `Jira <https://www.atlassian.com/software/jira/>`__, `Launchpad <https://launchpad.net/>`__, -`Roundup <http://roundup.sourceforge.net/>`__, and +`Roundup <https://roundup.sourceforge.io/>`__, and `Trac <https://trac.edgewall.org/>`__. The committee eventually settled on Jira and Roundup as the two candidates. Jira is a commercial product that @@ -187,7 +187,7 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.jython.org: The Jython bug tracker. - http://roundup.sourceforge.net/ + https://roundup.sourceforge.io/ Roundup downloads and documentation. https://svn.python.org/view/tracker/importer/ @@ -238,7 +238,7 @@ have adopted Sphinx as their documentation tool. `Sphinx <http://sphinx-doc.org/>`__ Documentation and code for the Sphinx toolchain. - `Docutils <http://docutils.sourceforge.net>`__ + `Docutils <https://docutils.sourceforge.io>`__ The underlying reStructuredText parser and toolset. diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 43eab642b8f7..f474a756b33a 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1,6 +1,6 @@ """Test date/time type. -See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases +See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases """ import io import itertools diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index ec823ae52c6f..ce6335cfc423 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1,5 +1,5 @@ /* C implementation for the date/time type documented at - * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage + * https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage */ /* bpo-35081: Defining this prevents including the C API capsule; From webhook-mailer at python.org Thu Aug 4 09:15:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 13:15:16 -0000 Subject: [Python-checkins] gh-91838: Resolve HTTP links which redirect to HTTPS (GH-95642) Message-ID: <mailman.483.1659618917.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c521c5cdc3f766ac5ac3574fa142aeec11c14267 commit: c521c5cdc3f766ac5ac3574fa142aeec11c14267 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T06:15:11-07:00 summary: gh-91838: Resolve HTTP links which redirect to HTTPS (GH-95642) It updates links which redirect to HTTPS with different authority or path. (cherry picked from commit d0d0154443cafb2f0a2cdfb6a1267d80cce8388e) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M Doc/about.rst M Doc/faq/general.rst M Doc/faq/programming.rst M Doc/howto/curses.rst M Doc/install/index.rst M Doc/library/random.rst M Doc/library/stdtypes.rst M Doc/library/tkinter.rst M Doc/whatsnew/2.3.rst M Doc/whatsnew/2.5.rst M Doc/whatsnew/2.6.rst M Lib/test/datetimetester.py M Modules/_datetimemodule.c diff --git a/Doc/about.rst b/Doc/about.rst index f0b908487b2d..0ce35667924b 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -6,7 +6,7 @@ About these documents These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. -.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _reStructuredText: https://docutils.sourceforge.io/rst.html .. _Sphinx: http://sphinx-doc.org/ .. In the online version of these documents, you can submit comments and suggest @@ -21,7 +21,7 @@ Many thanks go to: * Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content; -* the `Docutils <http://docutils.sourceforge.net/>`_ project for creating +* the `Docutils <https://docutils.sourceforge.io/>`_ project for creating reStructuredText and the Docutils suite; * Fredrik Lundh for his Alternative Python Reference project from which Sphinx got many good ideas. diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index bc4130aaa45c..510ebb5cf904 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -330,7 +330,7 @@ different companies and organizations. High-profile Python projects include `the Mailman mailing list manager <http://www.list.org>`_ and `the Zope application server -<http://www.zope.org>`_. Several Linux distributions, most notably `Red Hat +<https://www.zope.dev>`_. Several Linux distributions, most notably `Red Hat <https://www.redhat.com>`_, have written part or all of their installer and system administration software in Python. Companies that use Python internally include Google, Yahoo, and Lucasfilm Ltd. diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 5b5c357d5945..6514c00d1114 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -95,7 +95,7 @@ The following packages can help with the creation of console and GUI executables: * `Nuitka <https://nuitka.net/>`_ (Cross-platform) -* `PyInstaller <http://www.pyinstaller.org/>`_ (Cross-platform) +* `PyInstaller <https://pyinstaller.org/>`_ (Cross-platform) * `PyOxidizer <https://pyoxidizer.readthedocs.io/en/stable/>`_ (Cross-platform) * `cx_Freeze <https://marcelotduarte.github.io/cx_Freeze/>`_ (Cross-platform) * `py2app <https://github.com/ronaldoussoren/py2app>`_ (macOS only) diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index 48add160c884..83d80471ffc8 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -542,6 +542,6 @@ learn more about submitting patches to Python. * `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. -* `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: +* `"Console Applications with Urwid" <https://pyvideo.org/video/1568/console-applications-with-urwid>`_: video of a PyCon CA 2012 talk demonstrating some applications written using Urwid. diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 63b64b95fc72..84df5e7cb368 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -1062,7 +1062,7 @@ normal libraries do. .. seealso:: - `Building Python modules on MS Windows platform with MinGW <http://old.zope.org/Members/als/tips/win32_mingw_modules>`_ + `Building Python modules on MS Windows platform with MinGW <https://old.zope.dev/Members/als/tips/win32_mingw_modules>`_ Information about building the required libraries for the MinGW environment. diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 72881b56a4b1..cf9f04d969df 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -476,7 +476,7 @@ Example of `statistical bootstrapping <https://en.wikipedia.org/wiki/Bootstrapping_(statistics)>`_ using resampling with replacement to estimate a confidence interval for the mean of a sample:: - # http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm + # https://www.thoughtco.com/example-of-bootstrapping-3126155 from statistics import fmean as mean from random import choices diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 33fd2831228f..2480e71dded3 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1453,7 +1453,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe <http://code.activestate.com/recipes/579000/>`_ + * The `linspace recipe <https://code.activestate.com/recipes/579000/>`_ shows how to implement a lazy version of range suitable for floating point applications. diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 0447b15e26fe..0d2b344d24f2 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -90,7 +90,7 @@ Tcl (see `Threading model`_ for details). Tk - Tk is a `Tcl package <http://wiki.tcl.tk/37432>`_ implemented in C + Tk is a `Tcl package <https://wiki.tcl-lang.org/37432>`_ implemented in C that adds custom commands to create and manipulate GUI widgets. Each :class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into it. Tk's widgets are very customizable, though at the cost of a dated appearance. diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index 745b0aa22050..55061d2a46bd 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -1082,7 +1082,7 @@ Here are all of the changes that Python 2.3 makes to the core Python language. hierarchy. Classic classes are unaffected by this change. Python 2.2 originally used a topological sort of a class's ancestors, but 2.3 now uses the C3 algorithm as described in the paper `"A Monotonic Superclass Linearization - for Dylan" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To + for Dylan" <https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3910>`_. To understand the motivation for this change, read Michele Simionato's article `"Python 2.3 Method Resolution Order" <http://www.phyast.pitt.edu/~micheles/mro.html>`_, or read the thread on python-dev starting with the message at diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index f580c822dfdd..ea785121db90 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -882,7 +882,7 @@ in an :c:type:`int`. The C compilers for most 64-bit platforms still define :c:type:`int` as a 32-bit type, so that meant that lists could only hold up to ``2**31 - 1`` = 2147483647 items. (There are actually a few different programming models that 64-bit C compilers can use -- see -http://www.unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the +https://unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the most commonly available model leaves :c:type:`int` as 32 bits.) A limit of 2147483647 items doesn't really matter on a 32-bit platform because diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index eaca3165c07c..3d0d18746a21 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -155,7 +155,7 @@ up different products and import some of the bugs and patches from SourceForge. Four different trackers were examined: `Jira <https://www.atlassian.com/software/jira/>`__, `Launchpad <https://launchpad.net/>`__, -`Roundup <http://roundup.sourceforge.net/>`__, and +`Roundup <https://roundup.sourceforge.io/>`__, and `Trac <https://trac.edgewall.org/>`__. The committee eventually settled on Jira and Roundup as the two candidates. Jira is a commercial product that @@ -187,7 +187,7 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.jython.org: The Jython bug tracker. - http://roundup.sourceforge.net/ + https://roundup.sourceforge.io/ Roundup downloads and documentation. https://svn.python.org/view/tracker/importer/ @@ -238,7 +238,7 @@ have adopted Sphinx as their documentation tool. `Sphinx <http://sphinx-doc.org/>`__ Documentation and code for the Sphinx toolchain. - `Docutils <http://docutils.sourceforge.net>`__ + `Docutils <https://docutils.sourceforge.io>`__ The underlying reStructuredText parser and toolset. diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 8e4bcc7c9efd..bb67722267dd 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1,6 +1,6 @@ """Test date/time type. -See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases +See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases """ import io import itertools diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index e0bb4ee602c4..274d7df8c4d2 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1,5 +1,5 @@ /* C implementation for the date/time type documented at - * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage + * https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage */ /* bpo-35081: Defining this prevents including the C API capsule; From webhook-mailer at python.org Thu Aug 4 09:51:51 2022 From: webhook-mailer at python.org (ambv) Date: Thu, 04 Aug 2022 13:51:51 -0000 Subject: [Python-checkins] gh-91323: Revert "Allow overriding a future compliance check in asyncio.Task (GH-32197)" (GH-95442) Message-ID: <mailman.484.1659621112.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0342c93a6b866118c894c4e1120fb4db316adebb commit: 0342c93a6b866118c894c4e1120fb4db316adebb branch: main author: ?ukasz Langa <lukasz at langa.pl> committer: ambv <lukasz at langa.pl> date: 2022-08-04T15:51:38+02:00 summary: gh-91323: Revert "Allow overriding a future compliance check in asyncio.Task (GH-32197)" (GH-95442) This reverts commit d4bb38f82bf18b00db3129031ce4969b6f0caab9. files: M Doc/library/asyncio-extending.rst M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_tasks.py M Modules/_asynciomodule.c M Modules/clinic/_asynciomodule.c.h diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst index acbaa6f7faf7..8ffd356f2d1c 100644 --- a/Doc/library/asyncio-extending.rst +++ b/Doc/library/asyncio-extending.rst @@ -63,12 +63,6 @@ For this purpose the following, *private* constructors are listed: *context* argument is added. -.. method:: Task._check_future(future) - - Return ``True`` if *future* is attached to the same loop as the task, ``False`` - otherwise. - - .. versionadded:: 3.11 Task lifetime support diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 3952b5f2a774..27fe58da1513 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -252,10 +252,6 @@ def uncancel(self): self._num_cancels_requested -= 1 return self._num_cancels_requested - def _check_future(self, future): - """Return False if task and future loops are not compatible.""" - return futures._get_loop(future) is self._loop - def __step(self, exc=None): if self.done(): raise exceptions.InvalidStateError( @@ -296,7 +292,7 @@ def __step(self, exc=None): blocking = getattr(result, '_asyncio_future_blocking', None) if blocking is not None: # Yielded Future must come from Future.__iter__(). - if not self._check_future(result): + if futures._get_loop(result) is not self._loop: new_exc = RuntimeError( f'Task {self!r} got Future ' f'{result!r} attached to a different loop') diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index bde4defdf012..de735ba77aae 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2380,13 +2380,7 @@ def add_done_callback(self, *args, **kwargs): return super().add_done_callback(*args, **kwargs) class Task(CommonFuture, BaseTask): - def __init__(self, *args, **kwargs): - self._check_future_called = 0 - super().__init__(*args, **kwargs) - - def _check_future(self, future): - self._check_future_called += 1 - return super()._check_future(future) + pass class Future(CommonFuture, BaseFuture): pass @@ -2412,8 +2406,6 @@ async def func(): dict(fut.calls), {'add_done_callback': 1}) - self.assertEqual(1, task._check_future_called) - # Add patched Task & Future back to the test case cls.Task = Task cls.Future = Future diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 46175ccb8eb3..f94819cad24e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -23,7 +23,6 @@ _Py_IDENTIFIER(call_soon); _Py_IDENTIFIER(cancel); _Py_IDENTIFIER(get_event_loop); _Py_IDENTIFIER(throw); -_Py_IDENTIFIER(_check_future); /* State of the _asyncio module */ @@ -1810,8 +1809,6 @@ class _asyncio.Task "TaskObj *" "&Task_Type" static int task_call_step_soon(TaskObj *, PyObject *); static PyObject * task_wakeup(TaskObj *, PyObject *); static PyObject * task_step(TaskObj *, PyObject *); -static int task_check_future(TaskObj *, PyObject *); -static int task_check_future_exact(TaskObj *, PyObject *); /* ----- Task._step wrapper */ @@ -2286,6 +2283,7 @@ Returns the remaining number of cancellation requests. static PyObject * _asyncio_Task_uncancel_impl(TaskObj *self) /*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2]*/ +/*[clinic end generated code]*/ { if (self->task_num_cancels_requested > 0) { self->task_num_cancels_requested -= 1; @@ -2293,21 +2291,6 @@ _asyncio_Task_uncancel_impl(TaskObj *self) return PyLong_FromLong(self->task_num_cancels_requested); } -/*[clinic input] -_asyncio.Task._check_future -> bool - - future: object - -Return False if task and future loops are not compatible. -[clinic start generated code]*/ - -static int -_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future) -/*[clinic end generated code: output=a3bfba79295c8d57 input=3b1d6dfd6fe90aa5]*/ -{ - return task_check_future_exact(self, future); -} - /*[clinic input] _asyncio.Task.get_stack @@ -2533,7 +2516,6 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_CANCEL_METHODDEF _ASYNCIO_TASK_CANCELLING_METHODDEF _ASYNCIO_TASK_UNCANCEL_METHODDEF - _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF _ASYNCIO_TASK_GET_STACK_METHODDEF _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF @@ -2601,43 +2583,6 @@ TaskObj_dealloc(PyObject *self) Py_TYPE(task)->tp_free(task); } -static int -task_check_future_exact(TaskObj *task, PyObject *future) -{ - int res; - if (Future_CheckExact(future) || Task_CheckExact(future)) { - FutureObj *fut = (FutureObj *)future; - res = (fut->fut_loop == task->task_loop); - } else { - PyObject *oloop = get_future_loop(future); - if (oloop == NULL) { - return -1; - } - res = (oloop == task->task_loop); - Py_DECREF(oloop); - } - return res; -} - - -static int -task_check_future(TaskObj *task, PyObject *future) -{ - if (Task_CheckExact(task)) { - return task_check_future_exact(task, future); - } else { - PyObject * ret = _PyObject_CallMethodIdOneArg((PyObject *)task, - &PyId__check_future, - future); - if (ret == NULL) { - return -1; - } - int is_true = PyObject_IsTrue(ret); - Py_DECREF(ret); - return is_true; - } -} - static int task_call_step_soon(TaskObj *task, PyObject *arg) { @@ -2855,11 +2800,7 @@ task_step_impl(TaskObj *task, PyObject *exc) FutureObj *fut = (FutureObj*)result; /* Check if `result` future is attached to a different loop */ - res = task_check_future(task, result); - if (res == -1) { - goto fail; - } - if (res == 0) { + if (fut->fut_loop != task->task_loop) { goto different_loop; } @@ -2931,13 +2872,15 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* Check if `result` future is attached to a different loop */ - res = task_check_future(task, result); - if (res == -1) { + PyObject *oloop = get_future_loop(result); + if (oloop == NULL) { goto fail; } - if (res == 0) { + if (oloop != task->task_loop) { + Py_DECREF(oloop); goto different_loop; } + Py_DECREF(oloop); if (!blocking) { goto yield_insteadof_yf; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 7cc27b828959..add6bb2e08b5 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -466,43 +466,6 @@ _asyncio_Task_uncancel(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task_uncancel_impl(self); } -PyDoc_STRVAR(_asyncio_Task__check_future__doc__, -"_check_future($self, /, future)\n" -"--\n" -"\n" -"Return False if task and future loops are not compatible."); - -#define _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF \ - {"_check_future", _PyCFunction_CAST(_asyncio_Task__check_future), METH_FASTCALL|METH_KEYWORDS, _asyncio_Task__check_future__doc__}, - -static int -_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future); - -static PyObject * -_asyncio_Task__check_future(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"future", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_check_future", 0}; - PyObject *argsbuf[1]; - PyObject *future; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - future = args[0]; - _return_value = _asyncio_Task__check_future_impl(self, future); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, "get_stack($self, /, *, limit=None)\n" "--\n" @@ -927,4 +890,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=eccf150c9c30efd5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4e678c915567934 input=a9049054013a1b77]*/ From webhook-mailer at python.org Thu Aug 4 09:53:36 2022 From: webhook-mailer at python.org (gvanrossum) Date: Thu, 04 Aug 2022 13:53:36 -0000 Subject: [Python-checkins] gh-94936: C getters: co_varnames, co_cellvars, co_freevars (#95008) Message-ID: <mailman.485.1659621217.3313.python-checkins@python.org> https://github.com/python/cpython/commit/42b102bbf9a9ae6fae8f6710202fb7afeeac277c commit: 42b102bbf9a9ae6fae8f6710202fb7afeeac277c branch: main author: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-04T06:53:31-07:00 summary: gh-94936: C getters: co_varnames, co_cellvars, co_freevars (#95008) files: A Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst M Doc/c-api/code.rst M Doc/whatsnew/3.11.rst M Include/cpython/code.h M Modules/_testcapimodule.c M Objects/codeobject.c diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 7915b81b4637..d4a3c4ae35fa 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -90,3 +90,28 @@ bound into a function. .. versionadded:: 3.11 +.. c:function:: PyObject* PyCode_GetVarnames(PyCodeObject *co) + + Equivalent to the Python code ``getattr(co, 'co_varnames')``. + Returns a new reference to a :c:type:`PyTupleObject` containing the names of + the local variables. On error, ``NULL`` is returned and an exception + is raised. + + .. versionadded:: 3.11 + +.. c:function:: PyObject* PyCode_GetCellvars(PyCodeObject *co) + + Equivalent to the Python code ``getattr(co, 'co_cellvars')``. + Returns a new reference to a :c:type:`PyTupleObject` containing the names of + the local variables that are referenced by nested functions. On error, ``NULL`` + is returned and an exception is raised. + + .. versionadded:: 3.11 + +.. c:function:: PyObject* PyCode_GetFreevars(PyCodeObject *co) + + Equivalent to the Python code ``getattr(co, 'co_freevars')``. + Returns a new reference to a :c:type:`PyTupleObject` containing the names of + the free variables. On error, ``NULL`` is returned and an exception is raised. + + .. versionadded:: 3.11 diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 2db647bb4e4d..c976eddb08ba 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1719,10 +1719,13 @@ Porting to Python 3.11 To get a custom code object: create a code object using the compiler, then get a modified version with the ``replace`` method. -* :c:type:`PyCodeObject` no longer has a ``co_code`` field. Instead, - use ``PyObject_GetAttrString(code_object, "co_code")`` or - :c:func:`PyCode_GetCode` to get the underlying bytes object. - (Contributed by Brandt Bucher in :issue:`46841` and Ken Jin in :gh:`92154`.) +* :c:type:`PyCodeObject` no longer has the ``co_code``, ``co_varnames``, + ``co_cellvars`` and ``co_freevars`` fields. Instead, use + :c:func:`PyCode_GetCode`, :c:func:`PyCode_GetVarnames`, + :c:func:`PyCode_GetCellvars` and :c:func:`PyCode_GetFreevars` respectively + to access them via the C API. + (Contributed by Brandt Bucher in :issue:`46841` and Ken Jin in :gh:`92154` + and :gh:`94936`.) * The old trashcan macros (``Py_TRASHCAN_SAFE_BEGIN``/``Py_TRASHCAN_SAFE_END``) are now deprecated. They should be replaced by the new macros diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 595cd9e94f31..7ce69022557a 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -210,6 +210,12 @@ PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, /* Equivalent to getattr(code, 'co_code') in Python. Returns a strong reference to a bytes object. */ PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_varnames') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_cellvars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_freevars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code); typedef enum _PyCodeLocationInfoKind { /* short forms are 0 to 9 */ diff --git a/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst b/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst new file mode 100644 index 000000000000..abef9bb376c8 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst @@ -0,0 +1,3 @@ +Added :c:func:`PyCode_GetVarnames`, :c:func:`PyCode_GetCellvars` and +:c:func:`PyCode_GetFreevars` for accessing ``co_varnames``, ``co_cellvars`` +and ``co_freevars`` respectively via the C API. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f56b36a15e79..517591465b49 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5600,21 +5600,79 @@ test_code_api(PyObject *self, PyObject *Py_UNUSED(args)) if (co == NULL) { return NULL; } - PyObject *co_code = PyCode_GetCode(co); - if (co_code == NULL) { - Py_DECREF(co); - return NULL; - } - assert(PyBytes_CheckExact(co_code)); - if (PyObject_Length(co_code) == 0) { - PyErr_SetString(PyExc_ValueError, "empty co_code"); - Py_DECREF(co); + /* co_code */ + { + PyObject *co_code = PyCode_GetCode(co); + if (co_code == NULL) { + goto fail; + } + assert(PyBytes_CheckExact(co_code)); + if (PyObject_Length(co_code) == 0) { + PyErr_SetString(PyExc_ValueError, "empty co_code"); + Py_DECREF(co_code); + goto fail; + } Py_DECREF(co_code); - return NULL; + } + /* co_varnames */ + { + PyObject *co_varnames = PyCode_GetVarnames(co); + if (co_varnames == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_varnames)) { + PyErr_SetString(PyExc_TypeError, "co_varnames not tuple"); + Py_DECREF(co_varnames); + goto fail; + } + if (PyTuple_GET_SIZE(co_varnames) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_varnames"); + Py_DECREF(co_varnames); + goto fail; + } + Py_DECREF(co_varnames); + } + /* co_cellvars */ + { + PyObject *co_cellvars = PyCode_GetCellvars(co); + if (co_cellvars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_cellvars)) { + PyErr_SetString(PyExc_TypeError, "co_cellvars not tuple"); + Py_DECREF(co_cellvars); + goto fail; + } + if (PyTuple_GET_SIZE(co_cellvars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_cellvars"); + Py_DECREF(co_cellvars); + goto fail; + } + Py_DECREF(co_cellvars); + } + /* co_freevars */ + { + PyObject *co_freevars = PyCode_GetFreevars(co); + if (co_freevars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_freevars)) { + PyErr_SetString(PyExc_TypeError, "co_freevars not tuple"); + Py_DECREF(co_freevars); + goto fail; + } + if (PyTuple_GET_SIZE(co_freevars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_freevars"); + Py_DECREF(co_freevars); + goto fail; + } + Py_DECREF(co_freevars); } Py_DECREF(co); - Py_DECREF(co_code); Py_RETURN_NONE; +fail: + Py_DECREF(co); + return NULL; } static int diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 7ebbfdbdec18..aeb6a8c0804e 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1401,18 +1401,36 @@ _PyCode_GetVarnames(PyCodeObject *co) return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals); } +PyObject * +PyCode_GetVarnames(PyCodeObject *code) +{ + return _PyCode_GetVarnames(code); +} + PyObject * _PyCode_GetCellvars(PyCodeObject *co) { return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars); } +PyObject * +PyCode_GetCellvars(PyCodeObject *code) +{ + return _PyCode_GetCellvars(code); +} + PyObject * _PyCode_GetFreevars(PyCodeObject *co) { return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars); } +PyObject * +PyCode_GetFreevars(PyCodeObject *code) +{ + return _PyCode_GetFreevars(code); +} + static void deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) { From webhook-mailer at python.org Thu Aug 4 09:57:49 2022 From: webhook-mailer at python.org (gvanrossum) Date: Thu, 04 Aug 2022 13:57:49 -0000 Subject: [Python-checkins] GH-95289: Always call uncancel() when parent cancellation is requested (#95602) Message-ID: <mailman.486.1659621470.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2fef27589e44c91042c2598b5cad6c6ad0516d93 commit: 2fef27589e44c91042c2598b5cad6c6ad0516d93 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-04T06:57:44-07:00 summary: GH-95289: Always call uncancel() when parent cancellation is requested (#95602) Co-authored-by: Guido van Rossum <guido at python.org> files: A Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst M Lib/asyncio/taskgroups.py M Lib/test/test_asyncio/test_taskgroups.py diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 3ca65062efd2..097b4864f7ab 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -54,21 +54,22 @@ async def __aenter__(self): async def __aexit__(self, et, exc, tb): self._exiting = True - propagate_cancellation_error = None if (exc is not None and self._is_base_error(exc) and self._base_error is None): self._base_error = exc - if et is not None: - if et is exceptions.CancelledError: - if self._parent_cancel_requested and not self._parent_task.uncancel(): - # Do nothing, i.e. swallow the error. - pass - else: - propagate_cancellation_error = exc + propagate_cancellation_error = \ + exc if et is exceptions.CancelledError else None + if self._parent_cancel_requested: + # If this flag is set we *must* call uncancel(). + if self._parent_task.uncancel() == 0: + # If there are no pending cancellations left, + # don't propagate CancelledError. + propagate_cancellation_error = None + if et is not None: if not self._aborting: # Our parent task is being cancelled: # diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 26fb5e466af9..99498e7b36f0 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -3,7 +3,7 @@ import asyncio import contextvars - +import contextlib from asyncio import taskgroups import unittest @@ -741,6 +741,37 @@ async def coro2(g): self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + async def test_taskgroup_context_manager_exit_raises(self): + # See https://github.com/python/cpython/issues/95289 + class CustomException(Exception): + pass + + async def raise_exc(): + raise CustomException + + @contextlib.asynccontextmanager + async def database(): + try: + yield + finally: + raise CustomException + + async def main(): + task = asyncio.current_task() + try: + async with taskgroups.TaskGroup() as tg: + async with database(): + tg.create_task(raise_exc()) + await asyncio.sleep(1) + except* CustomException as err: + self.assertEqual(task.cancelling(), 0) + self.assertEqual(len(err.exceptions), 2) + + else: + self.fail('CustomException not raised') + + await asyncio.create_task(main()) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst b/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst new file mode 100644 index 000000000000..d802f557217b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.TaskGroup` to propagate exception when :exc:`asyncio.CancelledError` was replaced with another exception by a context manger. Patch by Kumar Aditya and Guido van Rossum. From webhook-mailer at python.org Thu Aug 4 09:59:37 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 04 Aug 2022 13:59:37 -0000 Subject: [Python-checkins] gh-87092: create a 'jump target label' abstraction so that the compiler's codegen stage does not work directly with basic blocks (GH-95398) Message-ID: <mailman.487.1659621578.3313.python-checkins@python.org> https://github.com/python/cpython/commit/000c3874bfa63507293c22249881f6cfc61af311 commit: 000c3874bfa63507293c22249881f6cfc61af311 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: markshannon <mark at hotpy.org> date: 2022-08-04T14:59:32+01:00 summary: gh-87092: create a 'jump target label' abstraction so that the compiler's codegen stage does not work directly with basic blocks (GH-95398) files: A Misc/NEWS.d/next/Core and Builtins/2022-07-28-19-07-06.gh-issue-87092.73IPS1.rst M Python/compile.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-28-19-07-06.gh-issue-87092.73IPS1.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-28-19-07-06.gh-issue-87092.73IPS1.rst new file mode 100644 index 000000000000..d4cc4bb9afc2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-28-19-07-06.gh-issue-87092.73IPS1.rst @@ -0,0 +1 @@ +Create a 'jump target label' abstraction in the compiler so that the compiler's codegen stage does not work directly with basic blocks. This prepares the code for changes to the underlying CFG generation mechanism. diff --git a/Python/compile.c b/Python/compile.c index 975efa7e23ec..3c4dd56b0592 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -139,10 +139,31 @@ struct location { static struct location NO_LOCATION = {-1, -1, -1, -1}; +typedef struct jump_target_label_ { + int id; + struct basicblock_ *block; +} jump_target_label; + +static struct jump_target_label_ NO_LABEL = {-1, NULL}; + +#define SAME_LABEL(L1, L2) ((L1).id == (L2).id) +#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) + +#define NEW_JUMP_TARGET_LABEL(C, NAME) \ + jump_target_label NAME = {cfg_new_label_id(CFG_BUILDER(C)), cfg_builder_new_block(CFG_BUILDER(C))}; \ + if (!IS_LABEL(NAME)) { \ + return 0; \ + } + +#define USE_LABEL(C, LBL) cfg_builder_use_label(CFG_BUILDER(C), LBL) + struct instr { int i_opcode; int i_oparg; - /* target block (if jump instruction) */ + /* target block (if jump instruction) -- we temporarily have both the label + and the block in the instr. The label is set by front end, and the block + is calculated by backend. */ + jump_target_label i_target_label; struct basicblock_ *i_target; /* target block when exception is raised, should not be set by front-end. */ struct basicblock_ *i_except; @@ -235,6 +256,8 @@ typedef struct basicblock_ { reverse order that the block are allocated. b_list points to the next block, not to be confused with b_next, which is next by control flow. */ struct basicblock_ *b_list; + /* The label of this block if it is a jump target, -1 otherwise */ + int b_label; /* Exception stack at start of block, used by assembler to create the exception handling table */ ExceptStack *b_exceptstack; /* pointer to an array of instructions, initially NULL */ @@ -309,9 +332,9 @@ enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, struct fblockinfo { enum fblocktype fb_type; - basicblock *fb_block; + jump_target_label fb_block; /* (optional) type-specific exit or cleanup block */ - basicblock *fb_exit; + jump_target_label fb_exit; /* (optional) additional information required for unwinding */ void *fb_datum; }; @@ -334,6 +357,10 @@ typedef struct cfg_builder_ { basicblock *block_list; /* pointer to the block currently being constructed */ basicblock *curblock; + /* label for the next instruction to be placed */ + jump_target_label g_current_label; + /* next free label id */ + int g_next_free_label; } cfg_builder; /* The following items change on entry and exit of code blocks. @@ -418,7 +445,7 @@ typedef struct { // fail_pop[2]: POP_TOP // fail_pop[1]: POP_TOP // fail_pop[0]: NOP - basicblock **fail_pop; + jump_target_label *fail_pop; // The current length of fail_pop. Py_ssize_t fail_pop_size; // The number of items on top of the stack that need to *stay* on top of the @@ -429,6 +456,7 @@ typedef struct { static int basicblock_next_instr(basicblock *); +static int cfg_builder_maybe_start_new_block(cfg_builder *g); static int cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct location loc); static void compiler_free(struct compiler *); @@ -839,6 +867,11 @@ compiler_set_qualname(struct compiler *c) return 1; } +static int +cfg_new_label_id(cfg_builder *g) +{ + return g->g_next_free_label++; +} /* Allocate a new block and return a pointer to it. Returns NULL on error. @@ -854,6 +887,7 @@ cfg_builder_new_block(cfg_builder *g) /* Extend the singly linked list of blocks with new block. */ b->b_list = g->block_list; g->block_list = b; + b->b_label = -1; return b; } @@ -866,16 +900,11 @@ cfg_builder_use_next_block(cfg_builder *g, basicblock *block) return block; } -static basicblock * -compiler_new_block(struct compiler *c) -{ - return cfg_builder_new_block(CFG_BUILDER(c)); -} - -static basicblock * -compiler_use_next_block(struct compiler *c, basicblock *block) +static int +cfg_builder_use_label(cfg_builder *g, jump_target_label lbl) { - return cfg_builder_use_next_block(CFG_BUILDER(c), block); + g->g_current_label = lbl; + return cfg_builder_maybe_start_new_block(g); } static basicblock * @@ -1254,16 +1283,16 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) static int basicblock_addop(basicblock *b, int opcode, int oparg, - basicblock *target, struct location loc) + jump_target_label target, struct location loc) { assert(IS_WITHIN_OPCODE_RANGE(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); assert(HAS_ARG(opcode) || oparg == 0); assert(0 <= oparg && oparg < (1 << 30)); - assert((target == NULL) || + assert(!IS_LABEL(target) || IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); - assert(oparg == 0 || target == NULL); + assert(oparg == 0 || !IS_LABEL(target)); int off = basicblock_next_instr(b); if (off < 0) { @@ -1272,24 +1301,51 @@ basicblock_addop(basicblock *b, int opcode, int oparg, struct instr *i = &b->b_instr[off]; i->i_opcode = opcode; i->i_oparg = oparg; - i->i_target = target; + i->i_target_label = target; + i->i_target = NULL; i->i_loc = loc; return 1; } -static int -cfg_builder_addop(cfg_builder *g, int opcode, int oparg, basicblock *target, - struct location loc) +static bool +cfg_builder_current_block_is_terminated(cfg_builder *g) { + if (IS_LABEL(g->g_current_label)) { + return true; + } struct instr *last = basicblock_last_instr(g->curblock); - if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) { - basicblock *b = cfg_builder_new_block(g); + return last && IS_TERMINATOR_OPCODE(last->i_opcode); +} + +static int +cfg_builder_maybe_start_new_block(cfg_builder *g) +{ + if (cfg_builder_current_block_is_terminated(g)) { + basicblock *b; + if (IS_LABEL(g->g_current_label)) { + b = g->g_current_label.block; + b->b_label = g->g_current_label.id; + g->g_current_label = NO_LABEL; + } + else { + b = cfg_builder_new_block(g); + } if (b == NULL) { return -1; } cfg_builder_use_next_block(g, b); } + return 0; +} + +static int +cfg_builder_addop(cfg_builder *g, int opcode, int oparg, jump_target_label target, + struct location loc) +{ + if (cfg_builder_maybe_start_new_block(g) != 0) { + return -1; + } return basicblock_addop(g->curblock, opcode, oparg, target, loc); } @@ -1297,7 +1353,7 @@ static int cfg_builder_addop_noarg(cfg_builder *g, int opcode, struct location loc) { assert(!HAS_ARG(opcode)); - return cfg_builder_addop(g, opcode, 0, NULL, loc); + return cfg_builder_addop(g, opcode, 0, NO_LABEL, loc); } static Py_ssize_t @@ -1509,13 +1565,13 @@ cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct locatio EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - return cfg_builder_addop(g, opcode, oparg_, NULL, loc); + return cfg_builder_addop(g, opcode, oparg_, NO_LABEL, loc); } static int -cfg_builder_addop_j(cfg_builder *g, int opcode, basicblock *target, struct location loc) +cfg_builder_addop_j(cfg_builder *g, int opcode, jump_target_label target, struct location loc) { - assert(target != NULL); + assert(IS_LABEL(target)); assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); return cfg_builder_addop(g, opcode, 0, target, loc); } @@ -1744,6 +1800,7 @@ compiler_enter_scope(struct compiler *c, identifier name, if (block == NULL) return 0; g->curblock = g->cfg_entryblock = block; + g->g_current_label = NO_LABEL; if (u->u_scope_type == COMPILER_SCOPE_MODULE) { c->u->u_loc.lineno = 0; @@ -1863,8 +1920,8 @@ find_ann(asdl_stmt_seq *stmts) */ static int -compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, - basicblock *exit, void *datum) +compiler_push_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label, + jump_target_label exit, void *datum) { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { @@ -1872,20 +1929,20 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, } f = &c->u->u_fblock[c->u->u_nfblocks++]; f->fb_type = t; - f->fb_block = b; + f->fb_block = block_label; f->fb_exit = exit; f->fb_datum = datum; return 1; } static void -compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) +compiler_pop_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label) { struct compiler_unit *u = c->u; assert(u->u_nfblocks > 0); u->u_nfblocks--; assert(u->u_fblock[u->u_nfblocks].fb_type == t); - assert(u->u_fblock[u->u_nfblocks].fb_block == b); + assert(SAME_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label)); } static int @@ -1900,20 +1957,19 @@ compiler_call_exit_with_nones(struct compiler *c) { static int compiler_add_yield_from(struct compiler *c, int await) { - basicblock *start, *resume, *exit; - start = compiler_new_block(c); - resume = compiler_new_block(c); - exit = compiler_new_block(c); - if (start == NULL || resume == NULL || exit == NULL) { - return 0; - } - compiler_use_next_block(c, start); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, resume); + NEW_JUMP_TARGET_LABEL(c, exit); + + USE_LABEL(c, start); ADDOP_JUMP(c, SEND, exit); - compiler_use_next_block(c, resume); + + USE_LABEL(c, resume); ADDOP_I(c, YIELD_VALUE, 0); ADDOP_I(c, RESUME, await ? 3 : 2); ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start); - compiler_use_next_block(c, exit); + + USE_LABEL(c, exit); return 1; } @@ -1965,14 +2021,14 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, /* This POP_BLOCK gets the line number of the unwinding statement */ ADDOP(c, POP_BLOCK); if (preserve_tos) { - if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) { + if (!compiler_push_fblock(c, POP_VALUE, NO_LABEL, NO_LABEL, NULL)) { return 0; } } /* Emit the finally block */ VISIT_SEQ(c, stmt, info->fb_datum); if (preserve_tos) { - compiler_pop_fblock(c, POP_VALUE, NULL); + compiler_pop_fblock(c, POP_VALUE, NO_LABEL); } /* The finally block should appear to execute after the * statement causing the unwinding, so make the unwinding @@ -2816,7 +2872,7 @@ static int compiler_addcompare(struct compiler *c, cmpop_ty op) static int -compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) +compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond) { switch (e->kind) { case UnaryOp_kind: @@ -2829,11 +2885,10 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) Py_ssize_t i, n = asdl_seq_LEN(s) - 1; assert(n >= 0); int cond2 = e->v.BoolOp.op == Or; - basicblock *next2 = next; + jump_target_label next2 = next; if (!cond2 != !cond) { - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, new_next2); + next2 = new_next2; } for (i = 0; i < n; ++i) { if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2)) @@ -2841,27 +2896,25 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) } if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond)) return 0; - if (next2 != next) - compiler_use_next_block(c, next2); + if (!SAME_LABEL(next2, next)) { + USE_LABEL(c, next2); + } return 1; } case IfExp_kind: { - basicblock *end, *next2; - end = compiler_new_block(c); - if (end == NULL) - return 0; - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, next2); if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0)) return 0; if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) return 0; ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, next2); + + USE_LABEL(c, next2); if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) return 0; - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } case Compare_kind: { @@ -2870,9 +2923,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) if (!check_compare(c, e)) { return 0; } - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, cleanup); VISIT(c, expr, e->v.Compare.left); for (i = 0; i < n; i++) { VISIT(c, expr, @@ -2885,16 +2936,16 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) 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_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); ADDOP(c, POP_TOP); if (!cond) { ADDOP_JUMP_NOLINE(c, JUMP, next); } - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } /* fallback to general implementation */ @@ -2914,22 +2965,19 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) static int compiler_ifexp(struct compiler *c, expr_ty e) { - basicblock *end, *next; - assert(e->kind == IfExp_kind); - end = compiler_new_block(c); - if (end == NULL) - return 0; - next = compiler_new_block(c); - if (next == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, next); + if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) return 0; VISIT(c, expr, e->v.IfExp.body); ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, next); + + USE_LABEL(c, next); VISIT(c, expr, e->v.IfExp.orelse); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } @@ -2993,17 +3041,12 @@ compiler_lambda(struct compiler *c, expr_ty e) static int compiler_if(struct compiler *c, stmt_ty s) { - basicblock *end, *next; + jump_target_label next; assert(s->kind == If_kind); - end = compiler_new_block(c); - if (end == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, end); if (asdl_seq_LEN(s->v.If.orelse)) { - next = compiler_new_block(c); - if (next == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, orelse); + next = orelse; } else { next = end; @@ -3014,44 +3057,46 @@ 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_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, next); + + USE_LABEL(c, next); VISIT_SEQ(c, stmt, s->v.If.orelse); } - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } static int compiler_for(struct compiler *c, stmt_ty s) { - basicblock *start, *body, *cleanup, *end; + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, cleanup); + NEW_JUMP_TARGET_LABEL(c, end); - start = compiler_new_block(c); - body = compiler_new_block(c); - cleanup = compiler_new_block(c); - end = compiler_new_block(c); - if (start == NULL || body == NULL || end == NULL || cleanup == NULL) { - return 0; - } if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { return 0; } VISIT(c, expr, s->v.For.iter); ADDOP(c, GET_ITER); - compiler_use_next_block(c, start); + + USE_LABEL(c, start); ADDOP_JUMP(c, FOR_ITER, cleanup); - compiler_use_next_block(c, body); + + USE_LABEL(c, body); VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ UNSET_LOC(c); ADDOP_JUMP(c, JUMP, start); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); compiler_pop_fblock(c, FOR_LOOP, start); VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } @@ -3059,24 +3104,20 @@ compiler_for(struct compiler *c, stmt_ty s) static int compiler_async_for(struct compiler *c, stmt_ty s) { - basicblock *start, *except, *end; if (IS_TOP_LEVEL_AWAIT(c)){ c->u->u_ste->ste_coroutine = 1; } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { return compiler_error(c, "'async for' outside async function"); } - start = compiler_new_block(c); - except = compiler_new_block(c); - end = compiler_new_block(c); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, end); - if (start == NULL || except == NULL || end == NULL) { - return 0; - } VISIT(c, expr, s->v.AsyncFor.iter); ADDOP(c, GET_AITER); - compiler_use_next_block(c, start); + USE_LABEL(c, start); if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { return 0; } @@ -3097,7 +3138,7 @@ compiler_async_for(struct compiler *c, stmt_ty s) compiler_pop_fblock(c, FOR_LOOP, start); /* Except block for __anext__ */ - compiler_use_next_block(c, except); + USE_LABEL(c, except); /* Use same line number as the iterator, * as the END_ASYNC_FOR succeeds the `for`, not the body. */ @@ -3107,23 +3148,19 @@ compiler_async_for(struct compiler *c, stmt_ty s) /* `else` block */ VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); - + USE_LABEL(c, end); return 1; } static int compiler_while(struct compiler *c, stmt_ty s) { - basicblock *loop, *body, *end, *anchor = NULL; - loop = compiler_new_block(c); - body = compiler_new_block(c); - anchor = compiler_new_block(c); - end = compiler_new_block(c); - if (loop == NULL || body == NULL || anchor == NULL || end == NULL) { - return 0; - } - compiler_use_next_block(c, loop); + NEW_JUMP_TARGET_LABEL(c, loop); + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, anchor); + + USE_LABEL(c, loop); if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) { return 0; } @@ -3131,7 +3168,7 @@ compiler_while(struct compiler *c, stmt_ty s) return 0; } - compiler_use_next_block(c, body); + USE_LABEL(c, body); VISIT_SEQ(c, stmt, s->v.While.body); SET_LOC(c, s); if (!compiler_jump_if(c, s->v.While.test, body, 1)) { @@ -3140,12 +3177,12 @@ compiler_while(struct compiler *c, stmt_ty s) compiler_pop_fblock(c, WHILE_LOOP, loop); - compiler_use_next_block(c, anchor); + USE_LABEL(c, anchor); if (s->v.While.orelse) { VISIT_SEQ(c, stmt, s->v.While.orelse); } - compiler_use_next_block(c, end); + USE_LABEL(c, end); return 1; } @@ -3257,18 +3294,15 @@ compiler_continue(struct compiler *c) static int compiler_try_finally(struct compiler *c, stmt_ty s) { - basicblock *body, *end, *exit, *cleanup; + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); - body = compiler_new_block(c); - end = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (body == NULL || end == NULL || exit == NULL || cleanup == NULL) { - return 0; - } /* `try` block */ ADDOP_JUMP(c, SETUP_FINALLY, end); - compiler_use_next_block(c, body); + + USE_LABEL(c, body); if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody)) return 0; if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { @@ -3283,44 +3317,36 @@ compiler_try_finally(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, s->v.Try.finalbody); ADDOP_JUMP_NOLINE(c, JUMP, exit); /* `finally` block */ - compiler_use_next_block(c, end); + + USE_LABEL(c, end); UNSET_LOC(c); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) + if (!compiler_push_fblock(c, FINALLY_END, end, NO_LABEL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, exit); + + USE_LABEL(c, exit); return 1; } static int compiler_try_star_finally(struct compiler *c, stmt_ty s) { - basicblock *body = compiler_new_block(c); - if (body == NULL) { - return 0; - } - basicblock *end = compiler_new_block(c); - if (!end) { - return 0; - } - basicblock *exit = compiler_new_block(c); - if (!exit) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (!cleanup) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* `try` block */ ADDOP_JUMP(c, SETUP_FINALLY, end); - compiler_use_next_block(c, body); + + USE_LABEL(c, body); if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.TryStar.finalbody)) { return 0; } @@ -3336,21 +3362,24 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); ADDOP_JUMP_NOLINE(c, JUMP, exit); + /* `finally` block */ - compiler_use_next_block(c, end); + USE_LABEL(c, end); UNSET_LOC(c); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) { + if (!compiler_push_fblock(c, FINALLY_END, end, NO_LABEL, NULL)) { return 0; } VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); compiler_pop_fblock(c, FINALLY_END, end); ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, exit); + + USE_LABEL(c, exit); return 1; } @@ -3386,18 +3415,17 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) static int compiler_try_except(struct compiler *c, stmt_ty s) { - basicblock *body, *except, *end, *cleanup; Py_ssize_t i, n; - body = compiler_new_block(c); - except = compiler_new_block(c); - end = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (body == NULL || except == NULL || end == NULL || cleanup == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, cleanup); + ADDOP_JUMP(c, SETUP_FINALLY, except); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) + + USE_LABEL(c, body); + if (!compiler_push_fblock(c, TRY_EXCEPT, body, NO_LABEL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); compiler_pop_fblock(c, TRY_EXCEPT, body); @@ -3407,13 +3435,14 @@ compiler_try_except(struct compiler *c, stmt_ty s) } ADDOP_JUMP_NOLINE(c, JUMP, end); n = asdl_seq_LEN(s->v.Try.handlers); - compiler_use_next_block(c, except); + + USE_LABEL(c, except); UNSET_LOC(c); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) + if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL)) return 0; for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( @@ -3422,22 +3451,16 @@ compiler_try_except(struct compiler *c, stmt_ty s) if (!handler->v.ExceptHandler.type && i < n-1) { return compiler_error(c, "default 'except:' must be last"); } - except = compiler_new_block(c); - if (except == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, next_except); + except = next_except; if (handler->v.ExceptHandler.type) { VISIT(c, expr, handler->v.ExceptHandler.type); ADDOP(c, CHECK_EXC_MATCH); ADDOP_JUMP(c, POP_JUMP_IF_FALSE, except); } if (handler->v.ExceptHandler.name) { - basicblock *cleanup_end, *cleanup_body; - - cleanup_end = compiler_new_block(c); - cleanup_body = compiler_new_block(c); - if (cleanup_end == NULL || cleanup_body == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, cleanup_end); + NEW_JUMP_TARGET_LABEL(c, cleanup_body); compiler_nameop(c, handler->v.ExceptHandler.name, Store); @@ -3454,8 +3477,9 @@ compiler_try_except(struct compiler *c, stmt_ty s) /* second try: */ ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) + + USE_LABEL(c, cleanup_body); + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NO_LABEL, handler->v.ExceptHandler.name)) return 0; /* second # body */ @@ -3472,7 +3496,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP_JUMP(c, JUMP, end); /* except: */ - compiler_use_next_block(c, cleanup_end); + USE_LABEL(c, cleanup_end); /* name = None; del name; # Mark as artificial */ UNSET_LOC(c); @@ -3484,15 +3508,12 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP_I(c, RERAISE, 1); } else { - basicblock *cleanup_body; - - cleanup_body = compiler_new_block(c); - if (!cleanup_body) - return 0; + NEW_JUMP_TARGET_LABEL(c, cleanup_body); ADDOP(c, POP_TOP); /* exc_value */ - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL)) + + USE_LABEL(c, cleanup_body); + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NO_LABEL, NULL)) return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); @@ -3501,15 +3522,18 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP(c, POP_EXCEPT); ADDOP_JUMP(c, JUMP, end); } - compiler_use_next_block(c, except); + + USE_LABEL(c, except); } /* Mark as artificial */ UNSET_LOC(c); - compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); + compiler_pop_fblock(c, EXCEPTION_HANDLER, NO_LABEL); ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } @@ -3565,34 +3589,17 @@ compiler_try_except(struct compiler *c, stmt_ty s) static int compiler_try_star_except(struct compiler *c, stmt_ty s) { - basicblock *body = compiler_new_block(c); - if (body == NULL) { - return 0; - } - basicblock *except = compiler_new_block(c); - if (except == NULL) { - return 0; - } - basicblock *orelse = compiler_new_block(c); - if (orelse == NULL) { - return 0; - } - basicblock *end = compiler_new_block(c); - if (end == NULL) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) { - return 0; - } - basicblock *reraise_star = compiler_new_block(c); - if (reraise_star == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, orelse); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, cleanup); + NEW_JUMP_TARGET_LABEL(c, reraise_star); ADDOP_JUMP(c, SETUP_FINALLY, except); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) { + + USE_LABEL(c, body); + if (!compiler_push_fblock(c, TRY_EXCEPT, body, NO_LABEL, NULL)) { return 0; } VISIT_SEQ(c, stmt, s->v.TryStar.body); @@ -3600,28 +3607,24 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) ADDOP_NOLINE(c, POP_BLOCK); ADDOP_JUMP_NOLINE(c, JUMP, orelse); Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers); - compiler_use_next_block(c, except); + + USE_LABEL(c, except); UNSET_LOC(c); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); /* Runtime will push a block here, so we need to account for that */ if (!compiler_push_fblock(c, EXCEPTION_GROUP_HANDLER, - NULL, NULL, "except handler")) { + NO_LABEL, NO_LABEL, "except handler")) { return 0; } for (Py_ssize_t i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.TryStar.handlers, i); SET_LOC(c, handler); - except = compiler_new_block(c); - if (except == NULL) { - return 0; - } - basicblock *handle_match = compiler_new_block(c); - if (handle_match == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, next_except); + except = next_except; + NEW_JUMP_TARGET_LABEL(c, handle_match); if (i == 0) { /* Push the original EG into the stack */ /* @@ -3648,16 +3651,10 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) ADDOP_JUMP(c, JUMP, except); } - compiler_use_next_block(c, handle_match); + USE_LABEL(c, handle_match); - basicblock *cleanup_end = compiler_new_block(c); - if (cleanup_end == NULL) { - return 0; - } - basicblock *cleanup_body = compiler_new_block(c); - if (cleanup_body == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, cleanup_end); + NEW_JUMP_TARGET_LABEL(c, cleanup_body); if (handler->v.ExceptHandler.name) { compiler_nameop(c, handler->v.ExceptHandler.name, Store); @@ -3678,8 +3675,9 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) */ /* second try: */ ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) + + USE_LABEL(c, cleanup_body); + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NO_LABEL, handler->v.ExceptHandler.name)) return 0; /* second # body */ @@ -3696,7 +3694,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) ADDOP_JUMP(c, JUMP, except); /* except: */ - compiler_use_next_block(c, cleanup_end); + USE_LABEL(c, cleanup_end); /* name = None; del name; # Mark as artificial */ UNSET_LOC(c); @@ -3710,9 +3708,9 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) /* add exception raised to the res list */ ADDOP_I(c, LIST_APPEND, 3); // exc ADDOP(c, POP_TOP); // lasti - ADDOP_JUMP(c, JUMP, except); - compiler_use_next_block(c, except); + + USE_LABEL(c, except); if (i == n - 1) { /* Add exc to the list (if not None it's the unhandled part of the EG) */ @@ -3722,13 +3720,10 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) } /* Mark as artificial */ UNSET_LOC(c); - compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NULL); - basicblock *reraise = compiler_new_block(c); - if (!reraise) { - return 0; - } + compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NO_LABEL); + NEW_JUMP_TARGET_LABEL(c, reraise); - compiler_use_next_block(c, reraise_star); + USE_LABEL(c, reraise_star); ADDOP(c, PREP_RERAISE_STAR); ADDOP_I(c, COPY, 1); ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, reraise); @@ -3738,16 +3733,20 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); ADDOP_JUMP(c, JUMP, end); - compiler_use_next_block(c, reraise); + + USE_LABEL(c, reraise); ADDOP(c, POP_BLOCK); ADDOP_I(c, SWAP, 2); ADDOP(c, POP_EXCEPT); ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, orelse); + + USE_LABEL(c, orelse); VISIT_SEQ(c, stmt, s->v.TryStar.orelse); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } @@ -3917,8 +3916,6 @@ compiler_from_import(struct compiler *c, stmt_ty s) static int compiler_assert(struct compiler *c, stmt_ty s) { - basicblock *end; - /* Always emit a warning if the test is a non-zero length tuple */ if ((s->v.Assert.test->kind == Tuple_kind && asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || @@ -3934,9 +3931,7 @@ compiler_assert(struct compiler *c, stmt_ty s) } if (c->c_optimize) return 1; - end = compiler_new_block(c); - if (end == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); if (!compiler_jump_if(c, s->v.Assert.test, end, 1)) return 0; ADDOP(c, LOAD_ASSERTION_ERROR); @@ -3945,7 +3940,8 @@ compiler_assert(struct compiler *c, stmt_ty s) ADDOP_I(c, CALL, 0); } ADDOP_I(c, RAISE_VARARGS, 1); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } @@ -4243,7 +4239,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) static int compiler_boolop(struct compiler *c, expr_ty e) { - basicblock *end; int jumpi; Py_ssize_t i, n; asdl_expr_seq *s; @@ -4253,23 +4248,20 @@ compiler_boolop(struct compiler *c, expr_ty e) jumpi = JUMP_IF_FALSE_OR_POP; else jumpi = JUMP_IF_TRUE_OR_POP; - end = compiler_new_block(c); - if (end == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); s = e->v.BoolOp.values; n = asdl_seq_LEN(s) - 1; assert(n >= 0); for (i = 0; i < n; ++i) { VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); ADDOP_JUMP(c, jumpi, end); - basicblock *next = compiler_new_block(c); - if (next == NULL) { - return 0; - } - compiler_use_next_block(c, next); + NEW_JUMP_TARGET_LABEL(c, next); + + USE_LABEL(c, next); } VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); return 1; } @@ -4563,9 +4555,7 @@ compiler_compare(struct compiler *c, expr_ty e) ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0)); } else { - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, cleanup); for (i = 0; i < n; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); @@ -4576,14 +4566,14 @@ compiler_compare(struct compiler *c, expr_ty e) } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); ADDOP_I(c, SWAP, 2); ADDOP(c, POP_TOP); - compiler_use_next_block(c, end); + + USE_LABEL(c, end); } return 1; } @@ -5138,16 +5128,11 @@ compiler_sync_comprehension_generator(struct compiler *c, and then write to the element */ comprehension_ty gen; - basicblock *start, *anchor, *if_cleanup; Py_ssize_t i, n; - start = compiler_new_block(c); - if_cleanup = compiler_new_block(c); - anchor = compiler_new_block(c); - - if (start == NULL || if_cleanup == NULL || anchor == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, if_cleanup); + NEW_JUMP_TARGET_LABEL(c, anchor); gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); @@ -5176,17 +5161,17 @@ compiler_sync_comprehension_generator(struct compiler *c, expr_ty elt = asdl_seq_GET(elts, 0); if (elt->kind != Starred_kind) { VISIT(c, expr, elt); - start = NULL; + start = NO_LABEL; } } - if (start) { + if (IS_LABEL(start)) { VISIT(c, expr, gen->iter); ADDOP(c, GET_ITER); } } - if (start) { + if (IS_LABEL(start)) { depth++; - compiler_use_next_block(c, start); + USE_LABEL(c, start); ADDOP_JUMP(c, FOR_ITER, anchor); } VISIT(c, expr, gen->target); @@ -5233,10 +5218,12 @@ compiler_sync_comprehension_generator(struct compiler *c, return 0; } } - compiler_use_next_block(c, if_cleanup); - if (start) { + + USE_LABEL(c, if_cleanup); + if (IS_LABEL(start)) { ADDOP_JUMP(c, JUMP, start); - compiler_use_next_block(c, anchor); + + USE_LABEL(c, anchor); } return 1; @@ -5249,15 +5236,10 @@ compiler_async_comprehension_generator(struct compiler *c, expr_ty elt, expr_ty val, int type) { comprehension_ty gen; - basicblock *start, *if_cleanup, *except; Py_ssize_t i, n; - start = compiler_new_block(c); - except = compiler_new_block(c); - if_cleanup = compiler_new_block(c); - - if (start == NULL || if_cleanup == NULL || except == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, if_cleanup); gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); @@ -5272,10 +5254,10 @@ compiler_async_comprehension_generator(struct compiler *c, ADDOP(c, GET_AITER); } - compiler_use_next_block(c, start); + USE_LABEL(c, start); /* Runtime will push a block here, so we need to account for that */ if (!compiler_push_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start, - NULL, NULL)) { + NO_LABEL, NULL)) { return 0; } @@ -5328,12 +5310,13 @@ compiler_async_comprehension_generator(struct compiler *c, return 0; } } - compiler_use_next_block(c, if_cleanup); + + USE_LABEL(c, if_cleanup); ADDOP_JUMP(c, JUMP, start); compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); - compiler_use_next_block(c, except); + USE_LABEL(c, except); //UNSET_LOC(c); ADDOP(c, END_ASYNC_FOR); @@ -5494,28 +5477,25 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k) static int -compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { +compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) { UNSET_LOC(c); - basicblock *suppress = compiler_new_block(c); - if (suppress == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, suppress); ADDOP_JUMP(c, POP_JUMP_IF_TRUE, suppress); ADDOP_I(c, RERAISE, 2); - compiler_use_next_block(c, suppress); + + USE_LABEL(c, suppress); ADDOP(c, POP_TOP); /* exc_value */ ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); ADDOP(c, POP_TOP); ADDOP(c, POP_TOP); - basicblock *exit = compiler_new_block(c); - if (exit == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, exit); ADDOP_JUMP(c, JUMP, exit); - compiler_use_next_block(c, cleanup); + + USE_LABEL(c, cleanup); POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, exit); + + USE_LABEL(c, exit); return 1; } @@ -5546,7 +5526,6 @@ compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { static int compiler_async_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *final, *exit, *cleanup; withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); assert(s->kind == AsyncWith_kind); @@ -5556,12 +5535,10 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) return compiler_error(c, "'async with' outside async function"); } - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (!block || !final || !exit || !cleanup) - return 0; + NEW_JUMP_TARGET_LABEL(c, block); + NEW_JUMP_TARGET_LABEL(c, final); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); @@ -5574,7 +5551,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP_JUMP(c, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); + USE_LABEL(c, block); if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) { return 0; } @@ -5613,7 +5590,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP_JUMP(c, JUMP, exit); /* For exceptional outcome: */ - compiler_use_next_block(c, final); + USE_LABEL(c, final); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); @@ -5623,7 +5600,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADD_YIELD_FROM(c, 1); compiler_with_except_finish(c, cleanup); - compiler_use_next_block(c, exit); + USE_LABEL(c, exit); return 1; } @@ -5652,17 +5629,14 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) static int compiler_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *final, *exit, *cleanup; withitem_ty item = asdl_seq_GET(s->v.With.items, pos); assert(s->kind == With_kind); - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (!block || !final || !exit || !cleanup) - return 0; + NEW_JUMP_TARGET_LABEL(c, block); + NEW_JUMP_TARGET_LABEL(c, final); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); @@ -5671,7 +5645,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) ADDOP_JUMP(c, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); + USE_LABEL(c, block); if (!compiler_push_fblock(c, WITH, block, final, s)) { return 0; } @@ -5709,14 +5683,14 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) ADDOP_JUMP(c, JUMP, exit); /* For exceptional outcome: */ - compiler_use_next_block(c, final); + USE_LABEL(c, final); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); ADDOP(c, WITH_EXCEPT_START); compiler_with_except_finish(c, cleanup); - compiler_use_next_block(c, exit); + USE_LABEL(c, exit); return 1; } @@ -6243,16 +6217,15 @@ ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n) if (size <= pc->fail_pop_size) { return 1; } - Py_ssize_t needed = sizeof(basicblock*) * size; - basicblock **resized = PyObject_Realloc(pc->fail_pop, needed); + Py_ssize_t needed = sizeof(jump_target_label) * size; + jump_target_label *resized = PyObject_Realloc(pc->fail_pop, needed); if (resized == NULL) { PyErr_NoMemory(); return 0; } pc->fail_pop = resized; while (pc->fail_pop_size < size) { - basicblock *new_block; - RETURN_IF_FALSE(new_block = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, new_block); pc->fail_pop[pc->fail_pop_size++] = new_block; } return 1; @@ -6279,7 +6252,7 @@ emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) return 1; } while (--pc->fail_pop_size) { - compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]); + USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]); if (!cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, COMPILER_LOC(c))) { pc->fail_pop_size = 0; PyObject_Free(pc->fail_pop); @@ -6287,7 +6260,7 @@ emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) return 0; } } - compiler_use_next_block(c, pc->fail_pop[0]); + USE_LABEL(c, pc->fail_pop[0]); PyObject_Free(pc->fail_pop); pc->fail_pop = NULL; return 1; @@ -6689,8 +6662,7 @@ static int compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchOr_kind); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns); assert(size > 1); // We're going to be messing with pc. Keep the original info handy: @@ -6793,7 +6765,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) if (!cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, COMPILER_LOC(c)) || !jump_to_fail_pop(c, pc, JUMP)) { goto error; } - compiler_use_next_block(c, end); + + USE_LABEL(c, end); Py_ssize_t nstores = PyList_GET_SIZE(control); // There's a bunch of stuff on the stack between where the new stores // are and where they need to be: @@ -6952,8 +6925,7 @@ static int compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc) { VISIT(c, expr, s->v.Match.subject); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases); assert(cases > 0); match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1); @@ -7022,7 +6994,7 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc) } VISIT_SEQ(c, stmt, m->body); } - compiler_use_next_block(c, end); + USE_LABEL(c, end); return 1; } @@ -7438,11 +7410,17 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) { if (explicit_jump == NULL) { return -1; } - basicblock_addop(explicit_jump, JUMP, 0, b->b_next, NO_LOCATION); - + jump_target_label next_label = {b->b_next->b_label, b->b_next}; + basicblock_addop(explicit_jump, JUMP, 0, next_label, NO_LOCATION); explicit_jump->b_cold = 1; explicit_jump->b_next = b->b_next; b->b_next = explicit_jump; + + /* calculate target from target_label */ + /* TODO: formalize an API for adding jumps in the backend */ + struct instr *last = basicblock_last_instr(explicit_jump); + last->i_target = last->i_target_label.block; + last->i_target_label = NO_LABEL; } } @@ -8262,8 +8240,8 @@ static void dump_basicblock(const basicblock *b) { const char *b_return = basicblock_returns(b) ? "return " : ""; - fprintf(stderr, "[%d %d %d %p] used: %d, depth: %d, offset: %d %s\n", - b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused, + fprintf(stderr, "%d: [%d %d %d %p] used: %d, depth: %d, offset: %d %s\n", + b->b_label, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused, b->b_startdepth, b->b_offset, b_return); if (b->b_instr) { int i; @@ -8279,6 +8257,9 @@ dump_basicblock(const basicblock *b) static int normalize_basic_block(basicblock *bb); +static int +calculate_jump_targets(basicblock *entryblock); + static int optimize_cfg(basicblock *entryblock, PyObject *consts, PyObject *const_cache); @@ -8497,7 +8478,7 @@ static void eliminate_empty_basic_blocks(basicblock *entryblock); -static void +static int remove_redundant_jumps(basicblock *entryblock) { /* If a non-empty block ends with a jump instruction, check if the next * non-empty block reached through normal flow control is the target @@ -8511,6 +8492,10 @@ remove_redundant_jumps(basicblock *entryblock) { assert(!IS_ASSEMBLER_OPCODE(b_last_instr->i_opcode)); if (b_last_instr->i_opcode == JUMP || b_last_instr->i_opcode == JUMP_NO_INTERRUPT) { + if (b_last_instr->i_target == NULL) { + PyErr_SetString(PyExc_SystemError, "jump with NULL target"); + return -1; + } if (b_last_instr->i_target == b->b_next) { assert(b->b_next->b_iused); b_last_instr->i_opcode = NOP; @@ -8522,6 +8507,7 @@ remove_redundant_jumps(basicblock *entryblock) { if (removed) { eliminate_empty_basic_blocks(entryblock); } + return 0; } static PyCodeObject * @@ -8599,7 +8585,9 @@ assemble(struct compiler *c, int addNone) if (consts == NULL) { goto error; } - + if (calculate_jump_targets(entryblock)) { + goto error; + } if (optimize_cfg(entryblock, consts, c->c_const_cache)) { goto error; } @@ -8627,7 +8615,9 @@ assemble(struct compiler *c, int addNone) goto error; } - remove_redundant_jumps(entryblock); + if (remove_redundant_jumps(entryblock) < 0) { + goto error; + } for (basicblock *b = entryblock; b != NULL; b = b->b_next) { clean_basic_block(b); } @@ -9441,6 +9431,47 @@ propagate_line_numbers(basicblock *entryblock) { } } + +/* Calculate the actual jump target from the target_label */ +static int +calculate_jump_targets(basicblock *entryblock) +{ + int max_label = -1; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_label > max_label) { + max_label = b->b_label; + } + } + size_t mapsize = sizeof(basicblock *) * (max_label + 1); + basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize); + if (!label2block) { + PyErr_NoMemory(); + return -1; + } + memset(label2block, 0, mapsize); + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_label >= 0) { + label2block[b->b_label] = b; + } + } + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + assert(instr->i_target == NULL); + if (is_jump(instr) || is_block_push(instr)) { + int lbl = instr->i_target_label.id; + assert(lbl >= 0 && lbl <= max_label); + instr->i_target = label2block[lbl]; + assert(instr->i_target != NULL); + assert(instr->i_target->b_label == lbl); + } + instr->i_target_label = NO_LABEL; + } + } + PyMem_Free(label2block); + return 0; +} + /* Perform optimizations on a control flow graph. The consts object should still be in list form to allow new constants to be appended. From webhook-mailer at python.org Thu Aug 4 10:13:50 2022 From: webhook-mailer at python.org (encukou) Date: Thu, 04 Aug 2022 14:13:50 -0000 Subject: [Python-checkins] gh-95388: Deprecate creating immutable types with mutable bases (GH-95533) Message-ID: <mailman.488.1659622432.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a613fedd6e18e4ab382cf81ec767e1135fc949a7 commit: a613fedd6e18e4ab382cf81ec767e1135fc949a7 branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-04T16:13:45+02:00 summary: gh-95388: Deprecate creating immutable types with mutable bases (GH-95533) files: A Misc/NEWS.d/next/C API/2022-07-29-10-41-59.gh-issue-95388.aiRSgr.rst M Doc/whatsnew/3.12.rst M Lib/test/test_capi.py M Modules/_testcapi/heaptype.c M Objects/typeobject.c diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 67396f8e0228..be0599763e22 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -205,6 +205,10 @@ Pending Removal in Python 3.14 (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) +* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable + bases using the C API. + + Pending Removal in Future Versions ---------------------------------- @@ -458,6 +462,9 @@ Deprecated :c:type:`PyConfig` instead. (Contributed by Victor Stinner in :gh:`77782`.) +* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable + bases is deprecated and will be disabled in Python 3.14. + Removed ------- diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 013229a6cdc9..c74355789747 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -15,6 +15,7 @@ import threading import time import unittest +import warnings import weakref from test import support from test.support import MISSING_C_DOCSTRINGS @@ -644,6 +645,34 @@ def test_pytype_fromspec_with_repeated_slots(self): with self.assertRaises(SystemError): _testcapi.create_type_from_repeated_slots(variant) + def test_immutable_type_with_mutable_base(self): + # Add deprecation warning here so it's removed in 3.14 + warnings._deprecated( + 'creating immutable classes with mutable bases', remove=(3, 14)) + + class MutableBase: + def meth(self): + return 'original' + + with self.assertWarns(DeprecationWarning): + ImmutableSubclass = _testcapi.make_immutable_type_with_base( + MutableBase) + instance = ImmutableSubclass() + + self.assertEqual(instance.meth(), 'original') + + # Cannot override the static type's method + with self.assertRaisesRegex( + TypeError, + "cannot set 'meth' attribute of immutable type"): + ImmutableSubclass.meth = lambda self: 'overridden' + self.assertEqual(instance.meth(), 'original') + + # Can change the method on the mutable base + MutableBase.meth = lambda self: 'changed' + self.assertEqual(instance.meth(), 'changed') + + def test_pynumber_tobase(self): from _testcapi import pynumber_tobase self.assertEqual(pynumber_tobase(123, 2), '0b1111011') diff --git a/Misc/NEWS.d/next/C API/2022-07-29-10-41-59.gh-issue-95388.aiRSgr.rst b/Misc/NEWS.d/next/C API/2022-07-29-10-41-59.gh-issue-95388.aiRSgr.rst new file mode 100644 index 000000000000..c389d13db6af --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-07-29-10-41-59.gh-issue-95388.aiRSgr.rst @@ -0,0 +1,2 @@ +Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable +bases is deprecated and is planned to be disabled in Python 3.14. diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index 12889e825d55..514541ce348d 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -365,6 +365,21 @@ create_type_from_repeated_slots(PyObject *self, PyObject *variant_obj) } + +static PyObject * +make_immutable_type_with_base(PyObject *self, PyObject *base) +{ + assert(PyType_Check(base)); + PyType_Spec ImmutableSubclass_spec = { + .name = "ImmutableSubclass", + .basicsize = (int)((PyTypeObject*)base)->tp_basicsize, + .slots = empty_type_slots, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, + }; + return PyType_FromSpecWithBases(&ImmutableSubclass_spec, base); +} + + static PyMethodDef TestMethods[] = { {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O}, {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, @@ -375,6 +390,7 @@ static PyMethodDef TestMethods[] = { {"test_from_spec_invalid_metatype_inheritance", test_from_spec_invalid_metatype_inheritance, METH_NOARGS}, + {"make_immutable_type_with_base", make_immutable_type_with_base, METH_O}, {NULL}, }; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1980fcbf9323..0801d9f3d5f1 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3676,6 +3676,32 @@ PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, goto finally; } + /* If this is an immutable type, check if all bases are also immutable, + * and (for now) fire a deprecation warning if not. + * (This isn't necessary for static types: those can't have heap bases, + * and only heap types can be mutable.) + */ + if (spec->flags & Py_TPFLAGS_IMMUTABLETYPE) { + for (int i=0; i<PyTuple_GET_SIZE(bases); i++) { + PyTypeObject *b = (PyTypeObject*)PyTuple_GET_ITEM(bases, i); + if (!b) { + goto finally; + } + if (!_PyType_HasFeature(b, Py_TPFLAGS_IMMUTABLETYPE)) { + if (PyErr_WarnFormat( + PyExc_DeprecationWarning, + 0, + "Creating immutable type %s from mutable base %s is " + "deprecated, and slated to be disallowed in Python 3.14.", + spec->name, + b->tp_name)) + { + goto finally; + } + } + } + } + /* Calculate the metaclass */ if (!metaclass) { From webhook-mailer at python.org Thu Aug 4 10:16:58 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 14:16:58 -0000 Subject: [Python-checkins] gh-94936: C getters: co_varnames, co_cellvars, co_freevars (GH-95008) Message-ID: <mailman.489.1659622618.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f2926358d1cd70625222eaf4b541584d2f2a1272 commit: f2926358d1cd70625222eaf4b541584d2f2a1272 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T07:16:52-07:00 summary: gh-94936: C getters: co_varnames, co_cellvars, co_freevars (GH-95008) (cherry picked from commit 42b102bbf9a9ae6fae8f6710202fb7afeeac277c) Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> files: A Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst M Doc/c-api/code.rst M Doc/whatsnew/3.11.rst M Include/cpython/code.h M Modules/_testcapimodule.c M Objects/codeobject.c diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 7915b81b4637..d4a3c4ae35fa 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -90,3 +90,28 @@ bound into a function. .. versionadded:: 3.11 +.. c:function:: PyObject* PyCode_GetVarnames(PyCodeObject *co) + + Equivalent to the Python code ``getattr(co, 'co_varnames')``. + Returns a new reference to a :c:type:`PyTupleObject` containing the names of + the local variables. On error, ``NULL`` is returned and an exception + is raised. + + .. versionadded:: 3.11 + +.. c:function:: PyObject* PyCode_GetCellvars(PyCodeObject *co) + + Equivalent to the Python code ``getattr(co, 'co_cellvars')``. + Returns a new reference to a :c:type:`PyTupleObject` containing the names of + the local variables that are referenced by nested functions. On error, ``NULL`` + is returned and an exception is raised. + + .. versionadded:: 3.11 + +.. c:function:: PyObject* PyCode_GetFreevars(PyCodeObject *co) + + Equivalent to the Python code ``getattr(co, 'co_freevars')``. + Returns a new reference to a :c:type:`PyTupleObject` containing the names of + the free variables. On error, ``NULL`` is returned and an exception is raised. + + .. versionadded:: 3.11 diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 1067982c3dc3..c57f8a0f3e9f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1724,10 +1724,13 @@ Porting to Python 3.11 To get a custom code object: create a code object using the compiler, then get a modified version with the ``replace`` method. -* :c:type:`PyCodeObject` no longer has a ``co_code`` field. Instead, - use ``PyObject_GetAttrString(code_object, "co_code")`` or - :c:func:`PyCode_GetCode` to get the underlying bytes object. - (Contributed by Brandt Bucher in :issue:`46841` and Ken Jin in :gh:`92154`.) +* :c:type:`PyCodeObject` no longer has the ``co_code``, ``co_varnames``, + ``co_cellvars`` and ``co_freevars`` fields. Instead, use + :c:func:`PyCode_GetCode`, :c:func:`PyCode_GetVarnames`, + :c:func:`PyCode_GetCellvars` and :c:func:`PyCode_GetFreevars` respectively + to access them via the C API. + (Contributed by Brandt Bucher in :issue:`46841` and Ken Jin in :gh:`92154` + and :gh:`94936`.) * The old trashcan macros (``Py_TRASHCAN_SAFE_BEGIN``/``Py_TRASHCAN_SAFE_END``) are now deprecated. They should be replaced by the new macros diff --git a/Include/cpython/code.h b/Include/cpython/code.h index ef8c6422046d..7006060cc760 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -209,6 +209,12 @@ PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, /* Equivalent to getattr(code, 'co_code') in Python. Returns a strong reference to a bytes object. */ PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_varnames') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_cellvars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_freevars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code); typedef enum _PyCodeLocationInfoKind { /* short forms are 0 to 9 */ diff --git a/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst b/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst new file mode 100644 index 000000000000..abef9bb376c8 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst @@ -0,0 +1,3 @@ +Added :c:func:`PyCode_GetVarnames`, :c:func:`PyCode_GetCellvars` and +:c:func:`PyCode_GetFreevars` for accessing ``co_varnames``, ``co_cellvars`` +and ``co_freevars`` respectively via the C API. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b0a4687a973d..961616dae63e 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5952,21 +5952,79 @@ test_code_api(PyObject *self, PyObject *Py_UNUSED(args)) if (co == NULL) { return NULL; } - PyObject *co_code = PyCode_GetCode(co); - if (co_code == NULL) { - Py_DECREF(co); - return NULL; - } - assert(PyBytes_CheckExact(co_code)); - if (PyObject_Length(co_code) == 0) { - PyErr_SetString(PyExc_ValueError, "empty co_code"); - Py_DECREF(co); + /* co_code */ + { + PyObject *co_code = PyCode_GetCode(co); + if (co_code == NULL) { + goto fail; + } + assert(PyBytes_CheckExact(co_code)); + if (PyObject_Length(co_code) == 0) { + PyErr_SetString(PyExc_ValueError, "empty co_code"); + Py_DECREF(co_code); + goto fail; + } Py_DECREF(co_code); - return NULL; + } + /* co_varnames */ + { + PyObject *co_varnames = PyCode_GetVarnames(co); + if (co_varnames == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_varnames)) { + PyErr_SetString(PyExc_TypeError, "co_varnames not tuple"); + Py_DECREF(co_varnames); + goto fail; + } + if (PyTuple_GET_SIZE(co_varnames) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_varnames"); + Py_DECREF(co_varnames); + goto fail; + } + Py_DECREF(co_varnames); + } + /* co_cellvars */ + { + PyObject *co_cellvars = PyCode_GetCellvars(co); + if (co_cellvars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_cellvars)) { + PyErr_SetString(PyExc_TypeError, "co_cellvars not tuple"); + Py_DECREF(co_cellvars); + goto fail; + } + if (PyTuple_GET_SIZE(co_cellvars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_cellvars"); + Py_DECREF(co_cellvars); + goto fail; + } + Py_DECREF(co_cellvars); + } + /* co_freevars */ + { + PyObject *co_freevars = PyCode_GetFreevars(co); + if (co_freevars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_freevars)) { + PyErr_SetString(PyExc_TypeError, "co_freevars not tuple"); + Py_DECREF(co_freevars); + goto fail; + } + if (PyTuple_GET_SIZE(co_freevars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_freevars"); + Py_DECREF(co_freevars); + goto fail; + } + Py_DECREF(co_freevars); } Py_DECREF(co); - Py_DECREF(co_code); Py_RETURN_NONE; +fail: + Py_DECREF(co); + return NULL; } static int diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 970aa6116bfa..c0151434489a 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1399,18 +1399,36 @@ _PyCode_GetVarnames(PyCodeObject *co) return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals); } +PyObject * +PyCode_GetVarnames(PyCodeObject *code) +{ + return _PyCode_GetVarnames(code); +} + PyObject * _PyCode_GetCellvars(PyCodeObject *co) { return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars); } +PyObject * +PyCode_GetCellvars(PyCodeObject *code) +{ + return _PyCode_GetCellvars(code); +} + PyObject * _PyCode_GetFreevars(PyCodeObject *co) { return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars); } +PyObject * +PyCode_GetFreevars(PyCodeObject *code) +{ + return _PyCode_GetFreevars(code); +} + static void deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) { From webhook-mailer at python.org Thu Aug 4 10:51:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 14:51:13 -0000 Subject: [Python-checkins] GH-95289: Always call uncancel() when parent cancellation is requested (GH-95602) Message-ID: <mailman.490.1659624674.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2d84fe59c0a8bba689d79cefa7110970dd781d46 commit: 2d84fe59c0a8bba689d79cefa7110970dd781d46 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T07:50:54-07:00 summary: GH-95289: Always call uncancel() when parent cancellation is requested (GH-95602) Co-authored-by: Guido van Rossum <guido at python.org> (cherry picked from commit 2fef27589e44c91042c2598b5cad6c6ad0516d93) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst M Lib/asyncio/taskgroups.py M Lib/test/test_asyncio/test_taskgroups.py diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 3ca65062efd2..097b4864f7ab 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -54,21 +54,22 @@ async def __aenter__(self): async def __aexit__(self, et, exc, tb): self._exiting = True - propagate_cancellation_error = None if (exc is not None and self._is_base_error(exc) and self._base_error is None): self._base_error = exc - if et is not None: - if et is exceptions.CancelledError: - if self._parent_cancel_requested and not self._parent_task.uncancel(): - # Do nothing, i.e. swallow the error. - pass - else: - propagate_cancellation_error = exc + propagate_cancellation_error = \ + exc if et is exceptions.CancelledError else None + if self._parent_cancel_requested: + # If this flag is set we *must* call uncancel(). + if self._parent_task.uncancel() == 0: + # If there are no pending cancellations left, + # don't propagate CancelledError. + propagate_cancellation_error = None + if et is not None: if not self._aborting: # Our parent task is being cancelled: # diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 26fb5e466af9..99498e7b36f0 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -3,7 +3,7 @@ import asyncio import contextvars - +import contextlib from asyncio import taskgroups import unittest @@ -741,6 +741,37 @@ async def coro2(g): self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + async def test_taskgroup_context_manager_exit_raises(self): + # See https://github.com/python/cpython/issues/95289 + class CustomException(Exception): + pass + + async def raise_exc(): + raise CustomException + + @contextlib.asynccontextmanager + async def database(): + try: + yield + finally: + raise CustomException + + async def main(): + task = asyncio.current_task() + try: + async with taskgroups.TaskGroup() as tg: + async with database(): + tg.create_task(raise_exc()) + await asyncio.sleep(1) + except* CustomException as err: + self.assertEqual(task.cancelling(), 0) + self.assertEqual(len(err.exceptions), 2) + + else: + self.fail('CustomException not raised') + + await asyncio.create_task(main()) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst b/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst new file mode 100644 index 000000000000..d802f557217b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.TaskGroup` to propagate exception when :exc:`asyncio.CancelledError` was replaced with another exception by a context manger. Patch by Kumar Aditya and Guido van Rossum. From webhook-mailer at python.org Thu Aug 4 11:19:39 2022 From: webhook-mailer at python.org (encukou) Date: Thu, 04 Aug 2022 15:19:39 -0000 Subject: [Python-checkins] gh-93274: Make vectorcall safe on mutable classes & inherit it by default (#95437) Message-ID: <mailman.491.1659626380.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7b370b73055d757ed09c7942f4631256b27fdcb6 commit: 7b370b73055d757ed09c7942f4631256b27fdcb6 branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-04T17:19:29+02:00 summary: gh-93274: Make vectorcall safe on mutable classes & inherit it by default (#95437) files: A Misc/NEWS.d/next/C API/2022-07-29-15-24-45.gh-issue-93012.-DdGEy.rst A Modules/_testcapi/clinic/vectorcall.c.h M Doc/c-api/call.rst M Doc/c-api/typeobj.rst M Doc/whatsnew/3.12.rst M Lib/test/test_call.py M Modules/_testcapi/vectorcall.c M Objects/typeobject.c diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index 13ef8b217a16..11d5c33a2d15 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -57,6 +57,15 @@ This bears repeating: A class supporting vectorcall **must** also implement :c:member:`~PyTypeObject.tp_call` with the same semantics. +.. versionchanged:: 3.12 + + The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + when the class's :py:meth:`~object.__call__` method is reassigned. + (This internally sets :c:member:`~PyTypeObject.tp_call` only, and thus + may make it behave differently than the vectorcall function.) + In earlier Python versions, vectorcall should only be used with + :const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` or static types. + A class should not implement vectorcall if that would be slower than *tp_call*. For example, if the callee needs to convert the arguments to an args tuple and kwargs dict anyway, then there is no point diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 7514801f2d4d..44884ac2890a 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -720,29 +720,29 @@ and :c:type:`PyType_Type` effectively act as defaults.) with the *vectorcallfunc* function. This can be done by setting *tp_call* to :c:func:`PyVectorcall_Call`. - .. warning:: - - It is not recommended for :ref:`mutable heap types <heap-types>` to implement - the vectorcall protocol. - When a user sets :attr:`__call__` in Python code, only *tp_call* is updated, - likely making it inconsistent with the vectorcall function. - .. versionchanged:: 3.8 Before version 3.8, this slot was named ``tp_print``. In Python 2.x, it was used for printing to a file. In Python 3.0 to 3.7, it was unused. + .. versionchanged:: 3.12 + + Before version 3.12, it was not recommended for + :ref:`mutable heap types <heap-types>` to implement the vectorcall + protocol. + When a user sets :attr:`~type.__call__` in Python code, only *tp_call* is + updated, likely making it inconsistent with the vectorcall function. + Since 3.12, setting ``__call__`` will disable vectorcall optimization + by clearing the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + **Inheritance:** This field is always inherited. However, the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not - always inherited. If it's not, then the subclass won't use + always inherited. If it's not set, then the subclass won't use :ref:`vectorcall <vectorcall>`, except when :c:func:`PyVectorcall_Call` is explicitly called. - This is in particular the case for types without the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set (including subclasses defined in - Python). .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -1178,12 +1178,18 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - This bit is inherited for types with the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set, if - :c:member:`~PyTypeObject.tp_call` is also inherited. + This bit is inherited if :c:member:`~PyTypeObject.tp_call` is also + inherited. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + + This flag is now removed from a class when the class's + :py:meth:`~object.__call__` method is reassigned. + + This flag can now be inherited by mutable classes. + .. data:: Py_TPFLAGS_IMMUTABLETYPE This bit is set for type objects that are immutable: type attributes cannot be set nor deleted. diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index be0599763e22..97a52e27fec1 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -414,6 +414,15 @@ New Features an additional metaclass argument. (Contributed by Wenzel Jakob in :gh:`93012`.) +* (XXX: this should be combined with :gh:`93274` when that is done) + The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + when the class's :py:meth:`~object.__call__` method is reassigned. + This makes vectorcall safe to use with mutable types (i.e. heap types + without the :const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` flag). + Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now + inherit the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + (Contributed by Petr Viktorin in :gh:`93012`.) + Porting to Python 3.12 ---------------------- diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 4c971bc5ed05..6c81a154f65f 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -606,9 +606,19 @@ def test_vectorcall_flag(self): self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL + # Mutable heap types should inherit Py_TPFLAGS_HAVE_VECTORCALL, + # but should lose it when __call__ is overridden class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): pass + self.assertTrue(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + MethodDescriptorHeap.__call__ = print + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL if + # they define __call__ directly + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + def __call__(self): + pass self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) def test_vectorcall_override(self): @@ -621,6 +631,58 @@ def test_vectorcall_override(self): f = _testcapi.MethodDescriptorNopGet() self.assertIs(f(*args), args) + def test_vectorcall_override_on_mutable_class(self): + """Setting __call__ should disable vectorcall""" + TestType = _testcapi.make_vectorcall_class() + instance = TestType() + self.assertEqual(instance(), "tp_call") + instance.set_vectorcall(TestType) + self.assertEqual(instance(), "vectorcall") # assume vectorcall is used + TestType.__call__ = lambda self: "custom" + self.assertEqual(instance(), "custom") + + def test_vectorcall_override_with_subclass(self): + """Setting __call__ on a superclass should disable vectorcall""" + SuperType = _testcapi.make_vectorcall_class() + class DerivedType(SuperType): + pass + + instance = DerivedType() + + # Derived types with its own vectorcall should be unaffected + UnaffectedType1 = _testcapi.make_vectorcall_class(DerivedType) + UnaffectedType2 = _testcapi.make_vectorcall_class(SuperType) + + # Aside: Quickly check that the C helper actually made derived types + self.assertTrue(issubclass(UnaffectedType1, DerivedType)) + self.assertTrue(issubclass(UnaffectedType2, SuperType)) + + # Initial state: tp_call + self.assertEqual(instance(), "tp_call") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + # Setting the vectorcall function + instance.set_vectorcall(SuperType) + + self.assertEqual(instance(), "vectorcall") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + # Setting __call__ should remove vectorcall from all subclasses + SuperType.__call__ = lambda self: "custom" + + self.assertEqual(instance(), "custom") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), False) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), False) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + def test_vectorcall(self): # Test a bunch of different ways to call objects: # 1. vectorcall using PyVectorcall_Call() diff --git a/Misc/NEWS.d/next/C API/2022-07-29-15-24-45.gh-issue-93012.-DdGEy.rst b/Misc/NEWS.d/next/C API/2022-07-29-15-24-45.gh-issue-93012.-DdGEy.rst new file mode 100644 index 000000000000..199c2d1fc197 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-07-29-15-24-45.gh-issue-93012.-DdGEy.rst @@ -0,0 +1,6 @@ +The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class +when the class's :py:meth:`~object.__call__` method is reassigned. This +makes vectorcall safe to use with mutable types (i.e. heap types without the +:const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` flag). Mutable types that do +not override :c:member:`~PyTypeObject.tp_call` now inherit the +:const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. diff --git a/Modules/_testcapi/clinic/vectorcall.c.h b/Modules/_testcapi/clinic/vectorcall.c.h new file mode 100644 index 000000000000..14cdf23304be --- /dev/null +++ b/Modules/_testcapi/clinic/vectorcall.c.h @@ -0,0 +1,107 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_testcapi_VectorCallClass_set_vectorcall__doc__, +"set_vectorcall($self, type, /)\n" +"--\n" +"\n" +"Set self\'s vectorcall function for `type` to one that returns \"vectorcall\""); + +#define _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF \ + {"set_vectorcall", (PyCFunction)_testcapi_VectorCallClass_set_vectorcall, METH_O, _testcapi_VectorCallClass_set_vectorcall__doc__}, + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, + PyTypeObject *type); + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + + if (!PyObject_TypeCheck(arg, &PyType_Type)) { + _PyArg_BadArgument("set_vectorcall", "argument", (&PyType_Type)->tp_name, arg); + goto exit; + } + type = (PyTypeObject *)arg; + return_value = _testcapi_VectorCallClass_set_vectorcall_impl(self, type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_make_vectorcall_class__doc__, +"make_vectorcall_class($module, base=<unrepresentable>, /)\n" +"--\n" +"\n" +"Create a class whose instances return \"tpcall\" when called.\n" +"\n" +"When the \"set_vectorcall\" method is called on an instance, a vectorcall\n" +"function that returns \"vectorcall\" will be installed."); + +#define _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF \ + {"make_vectorcall_class", _PyCFunction_CAST(_testcapi_make_vectorcall_class), METH_FASTCALL, _testcapi_make_vectorcall_class__doc__}, + +static PyObject * +_testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base); + +static PyObject * +_testcapi_make_vectorcall_class(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base = NULL; + + if (!_PyArg_CheckPositional("make_vectorcall_class", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!PyObject_TypeCheck(args[0], &PyType_Type)) { + _PyArg_BadArgument("make_vectorcall_class", "argument 1", (&PyType_Type)->tp_name, args[0]); + goto exit; + } + base = (PyTypeObject *)args[0]; +skip_optional: + return_value = _testcapi_make_vectorcall_class_impl(module, base); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_has_vectorcall_flag__doc__, +"has_vectorcall_flag($module, type, /)\n" +"--\n" +"\n" +"Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class."); + +#define _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF \ + {"has_vectorcall_flag", (PyCFunction)_testcapi_has_vectorcall_flag, METH_O, _testcapi_has_vectorcall_flag__doc__}, + +static int +_testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type); + +static PyObject * +_testcapi_has_vectorcall_flag(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + int _return_value; + + if (!PyObject_TypeCheck(arg, &PyType_Type)) { + _PyArg_BadArgument("has_vectorcall_flag", "argument", (&PyType_Type)->tp_name, arg); + goto exit; + } + type = (PyTypeObject *)arg; + _return_value = _testcapi_has_vectorcall_flag_impl(module, type); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=cf39927be151aebd input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/vectorcall.c b/Modules/_testcapi/vectorcall.c index 9bc702905caf..21846f97ff81 100644 --- a/Modules/_testcapi/vectorcall.c +++ b/Modules/_testcapi/vectorcall.c @@ -1,5 +1,8 @@ #include "parts.h" -#include <stddef.h> // offsetof +#include "clinic/vectorcall.c.h" + +#include "structmember.h" // PyMemberDef +#include <stddef.h> // offsetof /* Test PEP 590 - Vectorcall */ @@ -122,11 +125,128 @@ test_pyvectorcall_call(PyObject *self, PyObject *args) return PyVectorcall_Call(func, argstuple, kwargs); } +PyObject * +VectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { + return PyUnicode_FromString("tp_call"); +} + +PyObject * +VectorCallClass_vectorcall(PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames) { + return PyUnicode_FromString("vectorcall"); +} + +/*[clinic input] +module _testcapi +class _testcapi.VectorCallClass "PyObject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8423a8e919f2f0df]*/ + +/*[clinic input] +_testcapi.VectorCallClass.set_vectorcall + + type: object(subclass_of="&PyType_Type", type="PyTypeObject *") + / + +Set self's vectorcall function for `type` to one that returns "vectorcall" +[clinic start generated code]*/ + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, + PyTypeObject *type) +/*[clinic end generated code: output=b37f0466f15da903 input=840de66182c7d71a]*/ +{ + if (!PyObject_TypeCheck(self, type)) { + return PyErr_Format( + PyExc_TypeError, + "expected %s instance", + PyType_GetName(type)); + } + if (!type->tp_vectorcall_offset) { + return PyErr_Format( + PyExc_TypeError, + "type %s has no vectorcall offset", + PyType_GetName(type)); + } + *(vectorcallfunc*)((char*)self + type->tp_vectorcall_offset) = ( + VectorCallClass_vectorcall); + Py_RETURN_NONE; +} + +PyMethodDef VectorCallClass_methods[] = { + _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF + {NULL, NULL} +}; + +PyMemberDef VectorCallClass_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, 0/* set later */, READONLY}, + {NULL} +}; + +PyType_Slot VectorCallClass_slots[] = { + {Py_tp_call, VectorCallClass_tpcall}, + {Py_tp_members, VectorCallClass_members}, + {Py_tp_methods, VectorCallClass_methods}, + {0}, +}; + +/*[clinic input] +_testcapi.make_vectorcall_class + + base: object(subclass_of="&PyType_Type", type="PyTypeObject *") = NULL + / + +Create a class whose instances return "tpcall" when called. + +When the "set_vectorcall" method is called on an instance, a vectorcall +function that returns "vectorcall" will be installed. +[clinic start generated code]*/ + +static PyObject * +_testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base) +/*[clinic end generated code: output=16dcfc3062ddf968 input=f72e01ccf52de2b4]*/ +{ + if (!base) { + base = (PyTypeObject *)&PyBaseObject_Type; + } + VectorCallClass_members[0].offset = base->tp_basicsize; + PyType_Spec spec = { + .name = "_testcapi.VectorcallClass", + .basicsize = base->tp_basicsize + (int)sizeof(vectorcallfunc), + .flags = Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_VECTORCALL + | Py_TPFLAGS_BASETYPE, + .slots = VectorCallClass_slots, + }; + + return PyType_FromSpecWithBases(&spec, (PyObject *)base); +} + +/*[clinic input] +_testcapi.has_vectorcall_flag -> bool + + type: object(subclass_of="&PyType_Type", type="PyTypeObject *") + / + +Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class. +[clinic start generated code]*/ + +static int +_testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type) +/*[clinic end generated code: output=3ae8d1374388c671 input=8eee492ac548749e]*/ +{ + return PyType_HasFeature(type, Py_TPFLAGS_HAVE_VECTORCALL); +} + static PyMethodDef TestMethods[] = { {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, + _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF + _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF {NULL}, }; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 0801d9f3d5f1..1c3f8a9b775d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6290,11 +6290,9 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) * won't be used automatically. */ COPYSLOT(tp_vectorcall_offset); - /* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types - * if tp_call is not overridden */ + /* Inherit Py_TPFLAGS_HAVE_VECTORCALL if tp_call is not overridden */ if (!type->tp_call && - _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL) && - _PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) + _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL)) { type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL; } @@ -8713,8 +8711,17 @@ update_one_slot(PyTypeObject *type, slotdef *p) { PyObject *descr; PyWrapperDescrObject *d; - void *generic = NULL, *specific = NULL; + + // The correct specialized C function, like "tp_repr of str" in the + // example above + void *specific = NULL; + + // A generic wrapper that uses method lookup (safe but slow) + void *generic = NULL; + + // Set to 1 if the generic wrapper is necessary int use_generic = 0; + int offset = p->offset; int error; void **ptr = slotptr(type, offset); @@ -8797,6 +8804,10 @@ update_one_slot(PyTypeObject *type, slotdef *p) else { use_generic = 1; generic = p->function; + if (p->function == slot_tp_call) { + /* A generic __call__ is incompatible with vectorcall */ + type->tp_flags &= ~Py_TPFLAGS_HAVE_VECTORCALL; + } } } while ((++p)->offset == offset); if (specific && !use_generic) From webhook-mailer at python.org Thu Aug 4 12:07:44 2022 From: webhook-mailer at python.org (ambv) Date: Thu, 04 Aug 2022 16:07:44 -0000 Subject: [Python-checkins] gh-91323: Revert "Allow overriding a future compliance check in asyncio.Task (GH-32197)" (GH-95442) (GH-95652) Message-ID: <mailman.492.1659629265.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5ac3d0f5733b71d5c2168dcab079bd44a4c8018d commit: 5ac3d0f5733b71d5c2168dcab079bd44a4c8018d branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-04T18:07:39+02:00 summary: gh-91323: Revert "Allow overriding a future compliance check in asyncio.Task (GH-32197)" (GH-95442) (GH-95652) This reverts commit d4bb38f82bf18b00db3129031ce4969b6f0caab9. (cherry picked from commit 0342c93a6b866118c894c4e1120fb4db316adebb) Co-authored-by: ?ukasz Langa <lukasz at langa.pl> files: M Doc/library/asyncio-extending.rst M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_tasks.py M Modules/_asynciomodule.c M Modules/clinic/_asynciomodule.c.h diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst index acbaa6f7faf7..8ffd356f2d1c 100644 --- a/Doc/library/asyncio-extending.rst +++ b/Doc/library/asyncio-extending.rst @@ -63,12 +63,6 @@ For this purpose the following, *private* constructors are listed: *context* argument is added. -.. method:: Task._check_future(future) - - Return ``True`` if *future* is attached to the same loop as the task, ``False`` - otherwise. - - .. versionadded:: 3.11 Task lifetime support diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 3952b5f2a774..27fe58da1513 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -252,10 +252,6 @@ def uncancel(self): self._num_cancels_requested -= 1 return self._num_cancels_requested - def _check_future(self, future): - """Return False if task and future loops are not compatible.""" - return futures._get_loop(future) is self._loop - def __step(self, exc=None): if self.done(): raise exceptions.InvalidStateError( @@ -296,7 +292,7 @@ def __step(self, exc=None): blocking = getattr(result, '_asyncio_future_blocking', None) if blocking is not None: # Yielded Future must come from Future.__iter__(). - if not self._check_future(result): + if futures._get_loop(result) is not self._loop: new_exc = RuntimeError( f'Task {self!r} got Future ' f'{result!r} attached to a different loop') diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index b4a86271c64d..427034a1f1bc 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2384,13 +2384,7 @@ def add_done_callback(self, *args, **kwargs): return super().add_done_callback(*args, **kwargs) class Task(CommonFuture, BaseTask): - def __init__(self, *args, **kwargs): - self._check_future_called = 0 - super().__init__(*args, **kwargs) - - def _check_future(self, future): - self._check_future_called += 1 - return super()._check_future(future) + pass class Future(CommonFuture, BaseFuture): pass @@ -2416,8 +2410,6 @@ async def func(): dict(fut.calls), {'add_done_callback': 1}) - self.assertEqual(1, task._check_future_called) - # Add patched Task & Future back to the test case cls.Task = Task cls.Future = Future diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index eae468d8d96a..cb7afecd8f2c 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -23,7 +23,6 @@ _Py_IDENTIFIER(call_soon); _Py_IDENTIFIER(cancel); _Py_IDENTIFIER(get_event_loop); _Py_IDENTIFIER(throw); -_Py_IDENTIFIER(_check_future); /* State of the _asyncio module */ @@ -1810,8 +1809,6 @@ class _asyncio.Task "TaskObj *" "&Task_Type" static int task_call_step_soon(TaskObj *, PyObject *); static PyObject * task_wakeup(TaskObj *, PyObject *); static PyObject * task_step(TaskObj *, PyObject *); -static int task_check_future(TaskObj *, PyObject *); -static int task_check_future_exact(TaskObj *, PyObject *); /* ----- Task._step wrapper */ @@ -2286,6 +2283,7 @@ Returns the remaining number of cancellation requests. static PyObject * _asyncio_Task_uncancel_impl(TaskObj *self) /*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2]*/ +/*[clinic end generated code]*/ { if (self->task_num_cancels_requested > 0) { self->task_num_cancels_requested -= 1; @@ -2293,21 +2291,6 @@ _asyncio_Task_uncancel_impl(TaskObj *self) return PyLong_FromLong(self->task_num_cancels_requested); } -/*[clinic input] -_asyncio.Task._check_future -> bool - - future: object - -Return False if task and future loops are not compatible. -[clinic start generated code]*/ - -static int -_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future) -/*[clinic end generated code: output=a3bfba79295c8d57 input=3b1d6dfd6fe90aa5]*/ -{ - return task_check_future_exact(self, future); -} - /*[clinic input] _asyncio.Task.get_stack @@ -2533,7 +2516,6 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_CANCEL_METHODDEF _ASYNCIO_TASK_CANCELLING_METHODDEF _ASYNCIO_TASK_UNCANCEL_METHODDEF - _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF _ASYNCIO_TASK_GET_STACK_METHODDEF _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF @@ -2601,43 +2583,6 @@ TaskObj_dealloc(PyObject *self) Py_TYPE(task)->tp_free(task); } -static int -task_check_future_exact(TaskObj *task, PyObject *future) -{ - int res; - if (Future_CheckExact(future) || Task_CheckExact(future)) { - FutureObj *fut = (FutureObj *)future; - res = (fut->fut_loop == task->task_loop); - } else { - PyObject *oloop = get_future_loop(future); - if (oloop == NULL) { - return -1; - } - res = (oloop == task->task_loop); - Py_DECREF(oloop); - } - return res; -} - - -static int -task_check_future(TaskObj *task, PyObject *future) -{ - if (Task_CheckExact(task)) { - return task_check_future_exact(task, future); - } else { - PyObject * ret = _PyObject_CallMethodIdOneArg((PyObject *)task, - &PyId__check_future, - future); - if (ret == NULL) { - return -1; - } - int is_true = PyObject_IsTrue(ret); - Py_DECREF(ret); - return is_true; - } -} - static int task_call_step_soon(TaskObj *task, PyObject *arg) { @@ -2859,11 +2804,7 @@ task_step_impl(TaskObj *task, PyObject *exc) FutureObj *fut = (FutureObj*)result; /* Check if `result` future is attached to a different loop */ - res = task_check_future(task, result); - if (res == -1) { - goto fail; - } - if (res == 0) { + if (fut->fut_loop != task->task_loop) { goto different_loop; } @@ -2935,13 +2876,15 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* Check if `result` future is attached to a different loop */ - res = task_check_future(task, result); - if (res == -1) { + PyObject *oloop = get_future_loop(result); + if (oloop == NULL) { goto fail; } - if (res == 0) { + if (oloop != task->task_loop) { + Py_DECREF(oloop); goto different_loop; } + Py_DECREF(oloop); if (!blocking) { goto yield_insteadof_yf; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 7cc27b828959..add6bb2e08b5 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -466,43 +466,6 @@ _asyncio_Task_uncancel(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task_uncancel_impl(self); } -PyDoc_STRVAR(_asyncio_Task__check_future__doc__, -"_check_future($self, /, future)\n" -"--\n" -"\n" -"Return False if task and future loops are not compatible."); - -#define _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF \ - {"_check_future", _PyCFunction_CAST(_asyncio_Task__check_future), METH_FASTCALL|METH_KEYWORDS, _asyncio_Task__check_future__doc__}, - -static int -_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future); - -static PyObject * -_asyncio_Task__check_future(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"future", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_check_future", 0}; - PyObject *argsbuf[1]; - PyObject *future; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - future = args[0]; - _return_value = _asyncio_Task__check_future_impl(self, future); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, "get_stack($self, /, *, limit=None)\n" "--\n" @@ -927,4 +890,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=eccf150c9c30efd5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4e678c915567934 input=a9049054013a1b77]*/ From webhook-mailer at python.org Thu Aug 4 12:12:17 2022 From: webhook-mailer at python.org (zooba) Date: Thu, 04 Aug 2022 16:12:17 -0000 Subject: [Python-checkins] gh-95587: Fixes some upgrade detection issues in the Windows installer (GH-95631) Message-ID: <mailman.493.1659629538.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5b6acbaa20aa8c80c0f10986bf6c755608664023 commit: 5b6acbaa20aa8c80c0f10986bf6c755608664023 branch: main author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-04T17:12:08+01:00 summary: gh-95587: Fixes some upgrade detection issues in the Windows installer (GH-95631) files: A Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst M Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp diff --git a/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst b/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst new file mode 100644 index 000000000000..1033e892876c --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst @@ -0,0 +1,2 @@ +Fixes some issues where the Windows installer would incorrectly detect +certain features of an existing install when upgrading. diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index fdc2a21d83d5..3a17ffbaa0b6 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -724,6 +724,8 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { auto hr = LoadAssociateFilesStateFromKey(_engine, fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); if (hr == S_OK) { _engine->SetVariableNumeric(L"AssociateFiles", 1); + } else if (hr == S_FALSE) { + _engine->SetVariableNumeric(L"AssociateFiles", 0); } else if (FAILED(hr)) { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr); } @@ -817,6 +819,8 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { auto hr = LoadAssociateFilesStateFromKey(_engine, hkey); if (hr == S_OK) { _engine->SetVariableNumeric(L"AssociateFiles", 1); + } else if (hr == S_FALSE) { + _engine->SetVariableNumeric(L"AssociateFiles", 0); } else if (FAILED(hr)) { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr); } @@ -834,7 +838,17 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { LONGLONG includeLauncher; if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) && includeLauncher == -1) { - _engine->SetVariableNumeric(L"Include_launcher", 1); + if (BOOTSTRAPPER_ACTION_LAYOUT == _command.action || + (BOOTSTRAPPER_ACTION_INSTALL == _command.action && !_upgrading)) { + // When installing/downloading, we want to include the launcher + // by default. + _engine->SetVariableNumeric(L"Include_launcher", 1); + } else { + // Any other action, if we didn't detect the MSI then we want to + // keep it excluded + _engine->SetVariableNumeric(L"Include_launcher", 0); + _engine->SetVariableNumeric(L"AssociateFiles", 0); + } } } @@ -2812,6 +2826,17 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"x64", -1) == CSTR_EQUAL; } + static bool IsTargetPlatformARM64(__in IBootstrapperEngine* pEngine) { + WCHAR platform[8]; + DWORD platformLen = 8; + + if (FAILED(pEngine->GetVariableString(L"TargetPlatform", platform, &platformLen))) { + return S_FALSE; + } + + return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"ARM64", -1) == CSTR_EQUAL; + } + static HRESULT LoadOptionalFeatureStatesFromKey( __in IBootstrapperEngine* pEngine, __in HKEY hkHive, @@ -2820,7 +2845,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { HKEY hKey; LRESULT res; - if (IsTargetPlatformx64(pEngine)) { + if (IsTargetPlatformx64(pEngine) || IsTargetPlatformARM64(pEngine)) { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); } else { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); @@ -2859,7 +2884,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { BYTE buffer[1024]; DWORD bufferLen = sizeof(buffer); - if (IsTargetPlatformx64(pEngine)) { + if (IsTargetPlatformx64(pEngine) || IsTargetPlatformARM64(pEngine)) { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); } else { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); @@ -2917,12 +2942,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { HRESULT hr; HKEY hkHive; - // The launcher installation is separate from the Python install, so we - // check its state later. For now, assume we don't want the launcher or - // file associations, and if they have already been installed then - // loading the state will reactivate these settings. - pEngine->SetVariableNumeric(L"Include_launcher", 0); - pEngine->SetVariableNumeric(L"AssociateFiles", 0); + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading state of optional features"); // Get the registry key from the bundle, to save having to duplicate it // in multiple places. From webhook-mailer at python.org Thu Aug 4 12:12:40 2022 From: webhook-mailer at python.org (ambv) Date: Thu, 04 Aug 2022 16:12:40 -0000 Subject: [Python-checkins] Fix links to old SF bugs (#95648) Message-ID: <mailman.494.1659629562.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ab8a5beb5faf23795ede1e6304aebbcf2e20e0aa commit: ab8a5beb5faf23795ede1e6304aebbcf2e20e0aa branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: ambv <lukasz at langa.pl> date: 2022-08-04T18:12:35+02:00 summary: Fix links to old SF bugs (#95648) files: M Lib/test/crashers/infinite_loop_re.py M Lib/test/test_configparser.py M Lib/test/test_ctypes/test_functions.py M Lib/test/test_ctypes/test_loading.py M Lib/test/test_descr.py M Lib/test/test_file.py M Lib/test/test_fileio.py M Lib/test/test_getopt.py M Lib/test/test_grammar.py M Lib/test/test_lib2to3/data/py2_test_grammar.py M Lib/test/test_lib2to3/data/py3_test_grammar.py M Lib/test/test_pyexpat.py M Lib/test/test_set.py M Lib/test/test_urllib2.py M Misc/HISTORY M Modules/gc_weakref.txt diff --git a/Lib/test/crashers/infinite_loop_re.py b/Lib/test/crashers/infinite_loop_re.py index 9aecc568d91f..c84f28d601f8 100644 --- a/Lib/test/crashers/infinite_loop_re.py +++ b/Lib/test/crashers/infinite_loop_re.py @@ -1,5 +1,5 @@ -# This was taken from http://python.org/sf/1541697 +# This was taken from https://bugs.python.org/issue1541697 # It's not technically a crasher. It may not even truly be infinite, # however, I haven't waited a long time to see the result. It takes # 100% of CPU while running this and should be fixed. diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 5e2715a96b99..da17c00063c5 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -114,7 +114,7 @@ def basic_test(self, cf): # The use of spaces in the section names serves as a # regression test for SourceForge bug #583248: - # http://www.python.org/sf/583248 + # https://bugs.python.org/issue583248 # API access eq(cf.get('Foo Bar', 'foo'), 'bar1') @@ -932,7 +932,7 @@ def test_items(self): ('name', 'value')]) def test_safe_interpolation(self): - # See http://www.python.org/sf/511737 + # See https://bugs.python.org/issue511737 cf = self.fromstring("[section]\n" "option1{eq}xxx\n" "option2{eq}%(option1)s/xxx\n" diff --git a/Lib/test/test_ctypes/test_functions.py b/Lib/test/test_ctypes/test_functions.py index a3db0033533f..95633dfa8b38 100644 --- a/Lib/test/test_ctypes/test_functions.py +++ b/Lib/test/test_ctypes/test_functions.py @@ -371,7 +371,7 @@ class S8I(Structure): (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) def test_sf1651235(self): - # see https://www.python.org/sf/1651235 + # see https://bugs.python.org/issue1651235 proto = CFUNCTYPE(c_int, RECT, POINT) def callback(*args): diff --git a/Lib/test/test_ctypes/test_loading.py b/Lib/test/test_ctypes/test_loading.py index ea892277c4ea..8d8632a4eb64 100644 --- a/Lib/test/test_ctypes/test_loading.py +++ b/Lib/test/test_ctypes/test_loading.py @@ -93,7 +93,7 @@ def test_1703286_A(self): # NOT fit into a 32-bit integer. FreeLibrary must be able # to accept this address. - # These are tests for https://www.python.org/sf/1703286 + # These are tests for https://bugs.python.org/issue1703286 handle = LoadLibrary("advapi32") FreeLibrary(handle) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 4386e113745a..037c859e97d4 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -845,7 +845,7 @@ def __delattr__(self, name): ("getattr", "foo"), ("delattr", "foo")]) - # http://python.org/sf/1174712 + # https://bugs.python.org/issue1174712 try: class Module(types.ModuleType, str): pass diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 1146a37323c9..9df552786935 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -217,7 +217,7 @@ def testSetBufferSize(self): self._checkBufferSize(1) def testTruncateOnWindows(self): - # SF bug <http://www.python.org/sf/801631> + # SF bug <https://bugs.python.org/issue801631> # "file.truncate fault on windows" f = self.open(TESTFN, 'wb') diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index c26cdc028cc8..2263604ed1f9 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -503,7 +503,7 @@ def testTruncate(self): def testTruncateOnWindows(self): def bug801631(): - # SF bug <http://www.python.org/sf/801631> + # SF bug <https://bugs.python.org/issue801631> # "file.truncate fault on windows" f = self.FileIO(TESTFN, 'w') f.write(bytes(range(11))) diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index 64b9ce01e05e..c96a33b77fe2 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -83,7 +83,7 @@ def test_do_longs(self): # Much like the preceding, except with a non-alpha character ("-") in # option name that precedes "="; failed in - # http://python.org/sf/126863 + # https://bugs.python.org/issue126863 opts, args = getopt.do_longs([], 'foo=42', ['foo-bar', 'foo=',], []) self.assertEqual(opts, [('--foo', '42')]) self.assertEqual(args, []) diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index da8851986271..58f907eac09d 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -1592,7 +1592,7 @@ def test_selectors(self): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/test/test_lib2to3/data/py2_test_grammar.py b/Lib/test/test_lib2to3/data/py2_test_grammar.py index f9e4ea1374f9..1a631510f4db 100644 --- a/Lib/test/test_lib2to3/data/py2_test_grammar.py +++ b/Lib/test/test_lib2to3/data/py2_test_grammar.py @@ -735,7 +735,7 @@ def testSelectors(self): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. https://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/test/test_lib2to3/data/py3_test_grammar.py b/Lib/test/test_lib2to3/data/py3_test_grammar.py index a4a3f7eac0dd..774851f5bd7e 100644 --- a/Lib/test/test_lib2to3/data/py3_test_grammar.py +++ b/Lib/test/test_lib2to3/data/py3_test_grammar.py @@ -714,7 +714,7 @@ def testSelectors(self): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. https://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 6f0441b66d9b..863c1194672c 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -508,7 +508,7 @@ def test(self): class sf1296433Test(unittest.TestCase): def test_parse_only_xml_data(self): - # http://python.org/sf/1296433 + # https://bugs.python.org/issue1296433 # xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025) # this one doesn't crash diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 43f23dbbf9bf..2dd65240f5fa 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -427,7 +427,7 @@ def test_remove(self): self.assertRaises(KeyError, self.s.remove, self.thetype(self.word)) def test_remove_keyerror_unpacking(self): - # bug: www.python.org/sf/1576657 + # https://bugs.python.org/issue1576657 for v1 in ['Q', (1,)]: try: self.s.remove(v1) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 88270b7537b5..28f88412fdca 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1556,11 +1556,11 @@ def test_proxy_basic_auth(self): def test_basic_and_digest_auth_handlers(self): # HTTPDigestAuthHandler raised an exception if it couldn't handle a 40* - # response (http://python.org/sf/1479302), where it should instead + # response (https://bugs.python.org/issue1479302), where it should instead # return None to allow another handler (especially # HTTPBasicAuthHandler) to handle the response. - # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must + # Also (https://bugs.python.org/issue14797027, RFC 2617 section 1.2), we must # try digest first (since it's the strongest auth scheme), so we record # order of calls here to check digest comes first: class RecordingOpenerDirector(OpenerDirector): diff --git a/Misc/HISTORY b/Misc/HISTORY index 570638869f92..8ca89854ed13 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -21790,7 +21790,7 @@ Library x == y is False, and x != y is True. This is akin to the change made for mixed-type comparisons of datetime objects in 2.3a2; more info about the rationale is in the NEWS entry for that. See also SF bug - report <http://www.python.org/sf/693121>. + report <https://bugs.python.org/issue693121>. - On Unix platforms, if os.listdir() is called with a Unicode argument, it now returns Unicode strings. (This behavior was added earlier @@ -22025,7 +22025,7 @@ Extension modules now. today() and now() now round system timestamps to the closest - microsecond <http://www.python.org/sf/661086>. This repairs an + microsecond <https://bugs.python.org/issue661086>. This repairs an irritation most likely seen on Windows systems. In dt.astimezone(tz), if tz.utcoffset(dt) returns a duration, @@ -22080,7 +22080,7 @@ Extension modules datetime.fromtimestamp(): Like datetime.now() above, this had less than useful behavior when the optional tinzo argument was specified. See - also SF bug report <http://www.python.org/sf/660872>. + also SF bug report <https://bugs.python.org/issue660872>. date and datetime comparison: In order to prevent comparison from falling back to the default compare-object-addresses strategy, these @@ -22139,10 +22139,10 @@ Library dependent path modules (e.g. ntpath.py) rather than os.py, so these variables are now available via os.path. They continue to be available from the os module. - (see <http://www.python.org/sf/680789>). + (see <https://bugs.python.org/issue680789>). - array.array was added to the types repr.py knows about (see - <http://www.python.org/sf/680789>). + <https://bugs.python.org/issue680789>). - The new pickletools.py contains lots of documentation about pickle internals, and supplies some helpers for working with pickles, such as @@ -22527,7 +22527,7 @@ Core and builtins potential drawback is that list.sort() may require temp space of len(list)*2 bytes (``*4`` on a 64-bit machine). It's therefore possible for list.sort() to raise MemoryError now, even if a comparison function - does not. See <http://www.python.org/sf/587076> for full details. + does not. See <https://bugs.python.org/issue587076> for full details. - All standard iterators now ensure that, once StopIteration has been raised, all future calls to next() on the same iterator will also diff --git a/Modules/gc_weakref.txt b/Modules/gc_weakref.txt index 6d07cce12364..f53fb99dd6cd 100644 --- a/Modules/gc_weakref.txt +++ b/Modules/gc_weakref.txt @@ -47,7 +47,7 @@ soon as we execute Python code, threads other than the gc thread can run too, and they can do ordinary things with weakrefs that end up resurrecting CT while gc is running. - https://www.python.org/sf/1055820 + https://bugs.python.org/issue1055820 shows how innocent it can be, and also how nasty. Variants of the three focused test cases attached to that bug report are now part of Python's From webhook-mailer at python.org Thu Aug 4 12:14:09 2022 From: webhook-mailer at python.org (ambv) Date: Thu, 04 Aug 2022 16:14:09 -0000 Subject: [Python-checkins] [3.9] gh-91423: Remove bugs.python.org from bugs.rst (GH-91425) (GH-95614) Message-ID: <mailman.495.1659629649.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d348afa15d5a997e7a8e51c0f789f41cb15cc651 commit: d348afa15d5a997e7a8e51c0f789f41cb15cc651 branch: 3.9 author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-04T18:14:04+02:00 summary: [3.9] gh-91423: Remove bugs.python.org from bugs.rst (GH-91425) (GH-95614) Co-authored-by: roy reznik <royreznik at gmail.com> Co-authored-by: Inada Naoki <songofacandy at gmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com>. (cherry picked from commit df81d2892eed3a256eb61ce59304f2173fb0c945) files: M Doc/bugs.rst diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 6654a23c060e..69d7c27410d5 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -44,38 +44,39 @@ though it may take a while to be processed. Using the Python issue tracker ============================== -Bug reports for Python itself should be submitted via the Python Bug Tracker -(https://bugs.python.org/). The bug tracker offers a Web form which allows -pertinent information to be entered and submitted to the developers. +Issue reports for Python itself should be submitted via the GitHub issues +tracker (https://github.com/python/cpython/issues). +The GitHub issues tracker offers a web form which allows pertinent information +to be entered and submitted to the developers. The first step in filing a report is to determine whether the problem has already been reported. The advantage in doing so, aside from saving the -developers time, is that you learn what has been done to fix it; it may be that +developers' time, is that you learn what has been done to fix it; it may be that the problem has already been fixed for the next release, or additional information is needed (in which case you are welcome to provide it if you can!). -To do this, search the bug database using the search box on the top of the page. +To do this, search the tracker using the search box at the top of the page. -If the problem you're reporting is not already in the bug tracker, go back to -the Python Bug Tracker and log in. If you don't already have a tracker account, -select the "Register" link or, if you use OpenID, one of the OpenID provider -logos in the sidebar. It is not possible to submit a bug report anonymously. +If the problem you're reporting is not already in the list, log in to GitHub. +If you don't already have a GitHub account, create a new account using the +"Sign up" link. +It is not possible to submit a bug report anonymously. -Being now logged in, you can submit a bug. Select the "Create New" link in the -sidebar to open the bug reporting form. +Being now logged in, you can submit an issue. +Click on the "New issue" button in the top bar to report a new issue. -The submission form has a number of fields. For the "Title" field, enter a -*very* short description of the problem; less than ten words is good. In the -"Type" field, select the type of your problem; also select the "Component" and -"Versions" to which the bug relates. +The submission form has two fields, "Title" and "Comment". + +For the "Title" field, enter a *very* short description of the problem; +less than ten words is good. In the "Comment" field, describe the problem in detail, including what you expected to happen and what did happen. Be sure to include whether any extension modules were involved, and what hardware and software platform you were using (including version information as appropriate). -Each bug report will be assigned to a developer who will determine what needs to -be done to correct the problem. You will receive an update each time action is -taken on the bug. +Each issue report will be reviewed by a developer who will determine what needs to +be done to correct the problem. You will receive an update each time an action is +taken on the issue. .. seealso:: @@ -99,6 +100,6 @@ patching Python in the `Python Developer's Guide`_. If you have questions, the `core-mentorship mailing list`_ is a friendly place to get answers to any and all questions pertaining to the process of fixing issues in Python. -.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity +.. _Documentation bugs: https://github.com/python/cpython/issues?q=is%3Aissue+is%3Aopen+label%3Adocs .. _Python Developer's Guide: https://devguide.python.org/ .. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/ From webhook-mailer at python.org Thu Aug 4 12:41:25 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 16:41:25 -0000 Subject: [Python-checkins] gh-95587: Fixes some upgrade detection issues in the Windows installer (GH-95631) Message-ID: <mailman.496.1659631286.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f5011dfaa2327c3453437904abaed898506bf826 commit: f5011dfaa2327c3453437904abaed898506bf826 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T09:40:57-07:00 summary: gh-95587: Fixes some upgrade detection issues in the Windows installer (GH-95631) (cherry picked from commit 5b6acbaa20aa8c80c0f10986bf6c755608664023) Co-authored-by: Steve Dower <steve.dower at python.org> files: A Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst M Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp diff --git a/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst b/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst new file mode 100644 index 000000000000..1033e892876c --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst @@ -0,0 +1,2 @@ +Fixes some issues where the Windows installer would incorrectly detect +certain features of an existing install when upgrading. diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index fdc2a21d83d5..3a17ffbaa0b6 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -724,6 +724,8 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { auto hr = LoadAssociateFilesStateFromKey(_engine, fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); if (hr == S_OK) { _engine->SetVariableNumeric(L"AssociateFiles", 1); + } else if (hr == S_FALSE) { + _engine->SetVariableNumeric(L"AssociateFiles", 0); } else if (FAILED(hr)) { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr); } @@ -817,6 +819,8 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { auto hr = LoadAssociateFilesStateFromKey(_engine, hkey); if (hr == S_OK) { _engine->SetVariableNumeric(L"AssociateFiles", 1); + } else if (hr == S_FALSE) { + _engine->SetVariableNumeric(L"AssociateFiles", 0); } else if (FAILED(hr)) { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr); } @@ -834,7 +838,17 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { LONGLONG includeLauncher; if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) && includeLauncher == -1) { - _engine->SetVariableNumeric(L"Include_launcher", 1); + if (BOOTSTRAPPER_ACTION_LAYOUT == _command.action || + (BOOTSTRAPPER_ACTION_INSTALL == _command.action && !_upgrading)) { + // When installing/downloading, we want to include the launcher + // by default. + _engine->SetVariableNumeric(L"Include_launcher", 1); + } else { + // Any other action, if we didn't detect the MSI then we want to + // keep it excluded + _engine->SetVariableNumeric(L"Include_launcher", 0); + _engine->SetVariableNumeric(L"AssociateFiles", 0); + } } } @@ -2812,6 +2826,17 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"x64", -1) == CSTR_EQUAL; } + static bool IsTargetPlatformARM64(__in IBootstrapperEngine* pEngine) { + WCHAR platform[8]; + DWORD platformLen = 8; + + if (FAILED(pEngine->GetVariableString(L"TargetPlatform", platform, &platformLen))) { + return S_FALSE; + } + + return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"ARM64", -1) == CSTR_EQUAL; + } + static HRESULT LoadOptionalFeatureStatesFromKey( __in IBootstrapperEngine* pEngine, __in HKEY hkHive, @@ -2820,7 +2845,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { HKEY hKey; LRESULT res; - if (IsTargetPlatformx64(pEngine)) { + if (IsTargetPlatformx64(pEngine) || IsTargetPlatformARM64(pEngine)) { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); } else { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); @@ -2859,7 +2884,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { BYTE buffer[1024]; DWORD bufferLen = sizeof(buffer); - if (IsTargetPlatformx64(pEngine)) { + if (IsTargetPlatformx64(pEngine) || IsTargetPlatformARM64(pEngine)) { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); } else { res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); @@ -2917,12 +2942,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { HRESULT hr; HKEY hkHive; - // The launcher installation is separate from the Python install, so we - // check its state later. For now, assume we don't want the launcher or - // file associations, and if they have already been installed then - // loading the state will reactivate these settings. - pEngine->SetVariableNumeric(L"Include_launcher", 0); - pEngine->SetVariableNumeric(L"AssociateFiles", 0); + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading state of optional features"); // Get the registry key from the bundle, to save having to duplicate it // in multiple places. From webhook-mailer at python.org Thu Aug 4 12:47:06 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Thu, 04 Aug 2022 16:47:06 -0000 Subject: [Python-checkins] gh-90110: Update the C Analyzer Tool Whitelists (gh-95628) Message-ID: <mailman.497.1659631627.3313.python-checkins@python.org> https://github.com/python/cpython/commit/60f54d94852771854cf1cb647df7cef7c1617d9e commit: 60f54d94852771854cf1cb647df7cef7c1617d9e branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-04T10:47:02-06:00 summary: gh-90110: Update the C Analyzer Tool Whitelists (gh-95628) files: M Tools/c-analyzer/cpython/globals-to-fix.tsv M Tools/c-analyzer/cpython/ignored.tsv diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 496bc9a264b1..c8d23e9db0e1 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -539,32 +539,6 @@ Python/specialize.c - _Py_QuickenedCount - ################################## # global objects to fix in builtin modules -#----------------------- -# modules - -Modules/_abc.c - _abcmodule - -Modules/_codecsmodule.c - codecsmodule - -Modules/_collectionsmodule.c - _collectionsmodule - -Modules/_functoolsmodule.c - _functools_module - -Modules/_io/_iomodule.c - _PyIO_Module - -Modules/_io/_iomodule.h - _PyIO_Module - -Modules/_localemodule.c - _localemodule - -Modules/_sre.c - sremodule - -Modules/_stat.c - statmodule - -Modules/_threadmodule.c - threadmodule - -Modules/_tracemalloc.c - module_def - -Modules/_weakref.c - weakrefmodule - -Modules/atexitmodule.c - atexitmodule - -Modules/errnomodule.c - errnomodule - -Modules/faulthandler.c - module_def - -Modules/gcmodule.c - gcmodule - -Modules/itertoolsmodule.c - itertoolsmodule - -Modules/posixmodule.c - posixmodule - -Modules/pwdmodule.c - pwdmodule - -Modules/signalmodule.c - signalmodule - -Modules/symtablemodule.c - symtablemodule - -Modules/timemodule.c - timemodule - - #----------------------- # static types diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index ba48ef4933a4..a395775e8f1b 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -30,6 +30,7 @@ Modules/_io/_iomodule.h - PyBufferedRandom_Type - Modules/_io/_iomodule.h - PyTextIOWrapper_Type - Modules/_io/_iomodule.h - PyIncrementalNewlineDecoder_Type - Modules/_io/_iomodule.h - _PyBytesIOBuffer_Type - +Modules/_io/_iomodule.h - _PyIO_Module - Modules/_io/_iomodule.h - _PyIO_str_close - Modules/_io/_iomodule.h - _PyIO_str_closed - Modules/_io/_iomodule.h - _PyIO_str_decode - @@ -405,16 +406,35 @@ Python/sysmodule.c sys_set_asyncgen_hooks keywords - #----------------------- # PyModuleDef + +Modules/_abc.c - _abcmodule - +Modules/_codecsmodule.c - codecsmodule - +Modules/_collectionsmodule.c - _collectionsmodule - +Modules/_functoolsmodule.c - _functools_module - +Modules/_io/_iomodule.c - _PyIO_Module - +Modules/_localemodule.c - _localemodule - Modules/_multiprocessing/posixshmem.c - _posixshmemmodule - Modules/_sqlite/module.h - _sqlite3module - -Modules/_sre/sre.c - sremodule static struct - +Modules/_sre/sre.c - sremodule - Modules/_ssl.c - _sslmodule_def - Modules/_ssl.h - _sslmodule_def - -Modules/_testcapi/heaptype.c - _testcapimodule static - +Modules/_stat.c - statmodule - +Modules/_testcapi/heaptype.c - _testcapimodule - Modules/_testmultiphase.c - def_module_state_shared - Modules/_threadmodule.c - thread_module - +Modules/_tracemalloc.c - module_def - Modules/_typingmodule.c - typingmodule - +Modules/_weakref.c - weakrefmodule - +Modules/atexitmodule.c - atexitmodule - +Modules/errnomodule.c - errnomodule - +Modules/faulthandler.c - module_def - +Modules/gcmodule.c - gcmodule - +Modules/itertoolsmodule.c - itertoolsmodule - +Modules/posixmodule.c - posixmodule - +Modules/pwdmodule.c - pwdmodule - Modules/signalmodule.c - signal_module - +Modules/symtablemodule.c - symtablemodule - +Modules/timemodule.c - timemodule - Modules/xxlimited_35.c - xxmodule - Python/Python-ast.c - _astmodule - Python/Python-tokenize.c - _tokenizemodule - @@ -1371,8 +1391,10 @@ Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_spec - Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_spec - Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithDict_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithDict2_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithNegativeDict_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref2_spec - Modules/_testcapi/heaptype.c - HeapCTypeSetattr_spec - Modules/_testcapimodule.c - HeapTypeNameType_Spec - Modules/_testcapimodule.c - NullTpDocType_spec - From webhook-mailer at python.org Thu Aug 4 13:28:25 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Thu, 04 Aug 2022 17:28:25 -0000 Subject: [Python-checkins] gh-94673: Recover Weaklist Lookup Performance (gh-95544) Message-ID: <mailman.498.1659634106.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bdbadb905ae638b67a6c9a6767be396e18839dd6 commit: bdbadb905ae638b67a6c9a6767be396e18839dd6 branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-04T11:28:15-06:00 summary: gh-94673: Recover Weaklist Lookup Performance (gh-95544) gh-95302 seems to have introduced a small performance regression. Here we make some minor changes to recover that lost performance. files: M Include/internal/pycore_object.h M Modules/gcmodule.c M Objects/typeobject.c diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 173d36784cf1..b3b0b8464808 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -217,6 +217,16 @@ extern void _Py_PrintReferences(FILE *); extern void _Py_PrintReferenceAddresses(FILE *); #endif + +/* Return the *address* of the object's weaklist. The address may be + * dereferenced to get the current head of the weaklist. This is useful + * for iterating over the linked list of weakrefs, especially when the + * list is being modified externally (e.g. refs getting removed). + * + * The returned pointer should not be used to change the head of the list + * nor should it be used to add, remove, or swap any refs in the list. + * That is the sole responsibility of the code in weakrefobject.c. + */ static inline PyObject ** _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) { @@ -226,10 +236,33 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) (PyTypeObject *)op); return _PyStaticType_GET_WEAKREFS_LISTPTR(state); } + // Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(): Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; return (PyObject **)((char *)op + offset); } +/* This is a special case of _PyObject_GET_WEAKREFS_LISTPTR(). + * Only the most fundamental lookup path is used. + * Consequently, static types should not be used. + * + * For static builtin types the returned pointer will always point + * to a NULL tp_weaklist. This is fine for any deallocation cases, + * since static types are never deallocated and static builtin types + * are only finalized at the end of runtime finalization. + * + * If the weaklist for static types is actually needed then use + * _PyObject_GET_WEAKREFS_LISTPTR(). + */ +static inline PyWeakReference ** +_PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op) +{ + assert(!PyType_Check(op) || + ((PyTypeObject *)op)->tp_flags & Py_TPFLAGS_HEAPTYPE); + Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; + return (PyWeakReference **)((char *)op + offset); +} + + // Fast inlined version of PyObject_IS_GC() static inline int _PyObject_IS_GC(PyObject *obj) diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index dcd46feff0cc..97cb6e6e1efb 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -794,9 +794,12 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) if (! _PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) continue; - /* It supports weakrefs. Does it have any? */ - wrlist = (PyWeakReference **) - _PyObject_GET_WEAKREFS_LISTPTR(op); + /* It supports weakrefs. Does it have any? + * + * This is never triggered for static types so we can avoid the + * (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). + */ + wrlist = _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(op); /* `op` may have some weakrefs. March over the list, clear * all the weakrefs, and move the weakrefs with callbacks diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1c3f8a9b775d..1f56a5866e3d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1505,11 +1505,15 @@ subtype_dealloc(PyObject *self) finalizers since they might rely on part of the object being finalized that has already been destroyed. */ if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { - /* Modeled after GET_WEAKREFS_LISTPTR() */ - PyWeakReference **list = (PyWeakReference **) \ - _PyObject_GET_WEAKREFS_LISTPTR(self); - while (*list) + /* Modeled after GET_WEAKREFS_LISTPTR(). + + This is never triggered for static types so we can avoid the + (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). */ + PyWeakReference **list = \ + _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(self); + while (*list) { _PyWeakref_ClearRef(*list); + } } } From webhook-mailer at python.org Thu Aug 4 14:26:19 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 18:26:19 -0000 Subject: [Python-checkins] Docs: fix two typos in the sqlite3 docs (#95661) Message-ID: <mailman.499.1659637580.3313.python-checkins@python.org> https://github.com/python/cpython/commit/962acd446839c7e10caf301931760133644ce8ca commit: 962acd446839c7e10caf301931760133644ce8ca branch: main author: ceh <emil at hessman.se> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T20:25:53+02:00 summary: Docs: fix two typos in the sqlite3 docs (#95661) - statment => statement - transaciton => transaction files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3fade30c256..9055e0307c8 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -887,7 +887,7 @@ Connection objects Either ``"main"`` (the default) for the main database, ``"temp"`` for the temporary database, or the name of a custom database as attached using the - ``ATTACH DATABASE`` SQL statment. + ``ATTACH DATABASE`` SQL statement. :type name: str :param sleep: @@ -1060,7 +1060,7 @@ Cursor objects .. method:: executescript(sql_script, /) Execute the SQL statements in *sql_script*. - If there is a pending transaciton, + If there is a pending transaction, an implicit ``COMMIT`` statement is executed first. No other implicit transaction control is performed; any transaction control must be added to *sql_script*. From webhook-mailer at python.org Thu Aug 4 14:34:46 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 18:34:46 -0000 Subject: [Python-checkins] Docs: fix two typos in the sqlite3 docs (GH-95661) Message-ID: <mailman.500.1659638087.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f6b1c5e45426f3fcad6a8105bfe94de80f81a5c6 commit: f6b1c5e45426f3fcad6a8105bfe94de80f81a5c6 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T11:34:37-07:00 summary: Docs: fix two typos in the sqlite3 docs (GH-95661) - statment => statement - transaciton => transaction (cherry picked from commit 962acd446839c7e10caf301931760133644ce8ca) Co-authored-by: ceh <emil at hessman.se> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index b1c8166a64b..6afda5934ad 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -752,7 +752,7 @@ Connection objects Either ``"main"`` (the default) for the main database, ``"temp"`` for the temporary database, or the name of a custom database as attached using the - ``ATTACH DATABASE`` SQL statment. + ``ATTACH DATABASE`` SQL statement. :type name: str :param sleep: @@ -851,7 +851,7 @@ Cursor objects .. method:: executescript(sql_script, /) Execute the SQL statements in *sql_script*. - If there is a pending transaciton, + If there is a pending transaction, an implicit ``COMMIT`` statement is executed first. No other implicit transaction control is performed; any transaction control must be added to *sql_script*. From webhook-mailer at python.org Thu Aug 4 14:35:50 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 18:35:50 -0000 Subject: [Python-checkins] Docs: fix two typos in the sqlite3 docs (GH-95661) Message-ID: <mailman.501.1659638150.3313.python-checkins@python.org> https://github.com/python/cpython/commit/33de1863fdabfcaf3c7aa85c0faf5d218fb2a864 commit: 33de1863fdabfcaf3c7aa85c0faf5d218fb2a864 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T11:35:45-07:00 summary: Docs: fix two typos in the sqlite3 docs (GH-95661) - statment => statement - transaciton => transaction (cherry picked from commit 962acd446839c7e10caf301931760133644ce8ca) Co-authored-by: ceh <emil at hessman.se> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 892daf1660c..96694c60544 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -877,7 +877,7 @@ Connection objects Either ``"main"`` (the default) for the main database, ``"temp"`` for the temporary database, or the name of a custom database as attached using the - ``ATTACH DATABASE`` SQL statment. + ``ATTACH DATABASE`` SQL statement. :type name: str :param sleep: @@ -1050,7 +1050,7 @@ Cursor objects .. method:: executescript(sql_script, /) Execute the SQL statements in *sql_script*. - If there is a pending transaciton, + If there is a pending transaction, an implicit ``COMMIT`` statement is executed first. No other implicit transaction control is performed; any transaction control must be added to *sql_script*. From webhook-mailer at python.org Thu Aug 4 15:26:18 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 19:26:18 -0000 Subject: [Python-checkins] gh-95656: Enable the sqlite3 load extension API in Windows build (#95662) Message-ID: <mailman.502.1659641179.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6a5104f4fa83ed08fe31f712757dddabfede394c commit: 6a5104f4fa83ed08fe31f712757dddabfede394c branch: main author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T21:26:13+02:00 summary: gh-95656: Enable the sqlite3 load extension API in Windows build (#95662) files: A Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst M PCbuild/_sqlite3.vcxproj diff --git a/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst b/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst new file mode 100644 index 000000000000..77fea4c33f7a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst @@ -0,0 +1,2 @@ +Enable the :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` +API. diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index 804aa07367a0..57c7413671e5 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -94,7 +94,7 @@ <ItemDefinitionGroup> <ClCompile> <AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>PY_SQLITE_HAVE_SERIALIZE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>PY_SQLITE_HAVE_SERIALIZE;PY_SQLITE_ENABLE_LOAD_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> </ItemDefinitionGroup> <ItemGroup> From webhook-mailer at python.org Thu Aug 4 15:53:46 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 04 Aug 2022 19:53:46 -0000 Subject: [Python-checkins] gh-95656: Enable the sqlite3 load extension API in Windows build (GH-95662) Message-ID: <mailman.503.1659642828.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6d834414428d40ad9cebe48a09de6b244f579dd0 commit: 6d834414428d40ad9cebe48a09de6b244f579dd0 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T12:53:21-07:00 summary: gh-95656: Enable the sqlite3 load extension API in Windows build (GH-95662) (cherry picked from commit 6a5104f4fa83ed08fe31f712757dddabfede394c) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: A Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst M PCbuild/_sqlite3.vcxproj diff --git a/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst b/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst new file mode 100644 index 000000000000..77fea4c33f7a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst @@ -0,0 +1,2 @@ +Enable the :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` +API. diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index 804aa07367a0..57c7413671e5 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -94,7 +94,7 @@ <ItemDefinitionGroup> <ClCompile> <AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>PY_SQLITE_HAVE_SERIALIZE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>PY_SQLITE_HAVE_SERIALIZE;PY_SQLITE_ENABLE_LOAD_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> </ItemDefinitionGroup> <ItemGroup> From webhook-mailer at python.org Thu Aug 4 15:58:22 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 19:58:22 -0000 Subject: [Python-checkins] gh-95273: Improve documented return values and exceptions raised for sqlite3 class methods (#95530) Message-ID: <mailman.504.1659643103.3313.python-checkins@python.org> https://github.com/python/cpython/commit/12d92c733cfc00ee630b30e4e0250da400c83395 commit: 12d92c733cfc00ee630b30e4e0250da400c83395 branch: main author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T21:58:10+02:00 summary: gh-95273: Improve documented return values and exceptions raised for sqlite3 class methods (#95530) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 9055e0307c8..ddb6407a864 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -295,15 +295,14 @@ Module functions and constants in RAM instead of on disk. :type database: :term:`path-like object` - :param timeout: + :param float timeout: How many seconds the connection should wait before raising an exception, if the database is locked by another connection. If another connection opens a transaction to modify the database, it will be locked until that transaction is committed. Default five seconds. - :type timeout: float - :param detect_types: + :param int detect_types: Control whether and how data types not :ref:`natively supported by SQLite <sqlite3-types>` are looked up to be converted to Python types, @@ -316,7 +315,6 @@ Module functions and constants even when the *detect_types* parameter is set; :class:`str` will be returned instead. By default (``0``), type detection is disabled. - :type detect_types: int :param isolation_level: The :attr:`~Connection.isolation_level` of the connection, @@ -326,25 +324,22 @@ Module functions and constants See :ref:`sqlite3-controlling-transactions` for more. :type isolation_level: str | None - :param check_same_thread: + :param bool check_same_thread: If ``True`` (default), only the creating thread may use the connection. If ``False``, the connection may be shared across multiple threads; if so, write operations should be serialized by the user to avoid data corruption. - :type check_same_thread: bool - :param factory: + :param Connection factory: A custom subclass of :class:`Connection` to create the connection with, if not the default :class:`Connection` class. - :type factory: :class:`Connection` - :param cached_statements: + :param int cached_statements: The number of statements that ``sqlite3`` should internally cache for this connection, to avoid parsing overhead. By default, 128 statements. - :type cached_statements: int - :param uri: + :param bool uri: If set to ``True``, *database* is interpreted as a :abbr:`URI (Uniform Resource Identifier)` with a file path and an optional query string. @@ -352,7 +347,6 @@ Module functions and constants and the path can be relative or absolute. The query string allows passing parameters to SQLite, enabling various :ref:`sqlite3-uri-tricks`. - :type uri: bool :rtype: Connection @@ -487,28 +481,23 @@ Connection objects Open a :class:`Blob` handle to an existing :abbr:`BLOB (Binary Large OBject)`. - :param table: + :param str table: The name of the table where the blob is located. - :type table: str - :param column: + :param str column: The name of the column where the blob is located. - :type column: str - :param row: + :param str row: The name of the row where the blob is located. - :type row: str - :param readonly: + :param bool readonly: Set to ``True`` if the blob should be opened without write permissions. Defaults to ``False``. - :type readonly: bool - :param name: + :param str name: The name of the database where the blob is located. Defaults to ``"main"``. - :type name: str :raises OperationalError: When trying to open a blob in a ``WITHOUT ROWID`` table. @@ -561,14 +550,12 @@ Connection objects Create or remove a user-defined SQL function. - :param name: + :param str name: The name of the SQL function. - :type name: str - :param narg: + :param int narg: The number of arguments the SQL function can accept. If ``-1``, it may take any number of arguments. - :type narg: int :param func: A callable that is called when the SQL function is invoked. @@ -577,11 +564,10 @@ Connection objects Set to ``None`` to remove an existing SQL function. :type func: :term:`callback` | None - :param deterministic: + :param bool deterministic: If ``True``, the created SQL function is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which allows SQLite to perform additional optimizations. - :type deterministic: bool :raises NotSupportedError: If *deterministic* is used with SQLite versions older than 3.8.3. @@ -598,14 +584,12 @@ Connection objects Create or remove a user-defined SQL aggregate function. - :param name: + :param str name: The name of the SQL aggregate function. - :type name: str - :param n_arg: + :param int n_arg: The number of arguments the SQL aggregate function can accept. If ``-1``, it may take any number of arguments. - :type n_arg: int :param aggregate_class: A class must implement the following methods: @@ -629,14 +613,12 @@ Connection objects Create or remove a user-defined aggregate window function. - :param name: + :param str name: The name of the SQL aggregate window function to create or remove. - :type name: str - :param num_params: + :param int num_params: The number of arguments the SQL aggregate window function can accept. If ``-1``, it may take any number of arguments. - :type num_params: int :param aggregate_class: A class that must implement the following methods: @@ -862,16 +844,14 @@ Connection objects Works even if the database is being accessed by other clients or concurrently by the same connection. - :param target: + :param Connection target: The database connection to save the backup to. - :type target: Connection - :param pages: + :param int pages: The number of pages to copy at a time. If equal to or less than ``0``, the entire database is copied in a single step. Defaults to ``-1``. - :type pages: int :param progress: If set to a callable, it is invoked with three integer arguments for @@ -882,18 +862,16 @@ Connection objects Defaults to ``None``. :type progress: :term:`callback` |?None - :param name: + :param str name: The name of the database to back up. Either ``"main"`` (the default) for the main database, ``"temp"`` for the temporary database, or the name of a custom database as attached using the ``ATTACH DATABASE`` SQL statement. - :type name: str - :param sleep: + :param float sleep: The number of seconds to sleep between successive attempts to back up remaining pages. - :type sleep: float Example 1, copy an existing database into another:: @@ -919,11 +897,17 @@ Connection objects .. versionadded:: 3.7 - .. method:: getlimit(category, /) - Get a connection runtime limit. *category* is the limit category to be - queried. + Get a connection runtime limit. + + :param int category: + The `SQLite limit category`_ to be queried. + + :rtype: int + + :raises ProgrammingError: + If *category* is not recognised by the underlying SQLite library. Example, query the maximum length of an SQL statement:: @@ -937,14 +921,23 @@ Connection objects .. method:: setlimit(category, limit, /) - Set a connection runtime limit. *category* is the limit category to be - set. *limit* is the new limit. If the new limit is a negative number, the - limit is unchanged. - + Set a connection runtime limit. Attempts to increase a limit above its hard upper bound are silently truncated to the hard upper bound. Regardless of whether or not the limit was changed, the prior value of the limit is returned. + :param int category: + The `SQLite limit category`_ to be set. + + :param int limit: + The value of the new limit. + If negative, the current limit is unchanged. + + :rtype: int + + :raises ProgrammingError: + If *category* is not recognised by the underlying SQLite library. + Example, limit the number of attached databases to 1:: import sqlite3 @@ -953,6 +946,8 @@ Connection objects .. versionadded:: 3.11 +.. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html + .. method:: serialize(*, name="main") @@ -962,8 +957,11 @@ Connection objects serialization is the same sequence of bytes which would be written to disk if that database were backed up to disk. - *name* is the database to be serialized, and defaults to the main - database. + :param str name: + The database name to be serialized. + Defaults to ``"main"``. + + :rtype: bytes .. note:: @@ -979,12 +977,24 @@ Connection objects :class:`Connection`. This method causes the database connection to disconnect from database *name*, and reopen *name* as an in-memory database based on the - serialization contained in *data*. Deserialization will raise - :exc:`OperationalError` if the database connection is currently involved - in a read transaction or a backup operation. :exc:`OverflowError` will be - raised if ``len(data)`` is larger than ``2**63 - 1``, and - :exc:`DatabaseError` will be raised if *data* does not contain a valid - SQLite database. + serialization contained in *data*. + + :param bytes data: + A serialized database. + + :param str name: + The database name to deserialize into. + Defaults to ``"main"``. + + :raises OperationalError: + If the database connection is currently involved in a read + transaction or a backup operation. + + :raises DatabaseError: + If *data* does not contain a valid SQLite database. + + :raises OverflowError: + If :func:`len(data) <len>` is larger than ``2**63 - 1``. .. note:: @@ -1081,13 +1091,13 @@ Cursor objects .. method:: fetchone() - Fetch the next row of a query result set as a :class:`tuple`. + Return the next row of a query result set as a :class:`tuple`. Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) - Fetch the next set of rows of a query result as a :class:`list`. + Return the next set of rows of a query result as a :class:`list`. Return an empty list if no more rows are available. The number of rows to fetch per call is specified by the *size* parameter. @@ -1103,7 +1113,7 @@ Cursor objects .. method:: fetchall() - Fetch all (remaining) rows of a query result as a :class:`list`. + Return all (remaining) rows of a query result as a :class:`list`. Return an empty list if no rows are available. Note that the :attr:`arraysize` attribute can affect the performance of this operation. From webhook-mailer at python.org Thu Aug 4 16:13:40 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 20:13:40 -0000 Subject: [Python-checkins] [3.11] gh-95273: Improve documented return values and exceptions raised for sqlite3 class methods (GH-95530) (#95673) Message-ID: <mailman.505.1659644021.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c9986be733a2c91454bbca95ca677755eea1d173 commit: c9986be733a2c91454bbca95ca677755eea1d173 branch: 3.11 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T22:13:22+02:00 summary: [3.11] gh-95273: Improve documented return values and exceptions raised for sqlite3 class methods (GH-95530) (#95673) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com> (cherry picked from commit 12d92c733cfc00ee630b30e4e0250da400c83395) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 96694c60544..f6496575bf0 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -285,15 +285,14 @@ Module functions and constants in RAM instead of on disk. :type database: :term:`path-like object` - :param timeout: + :param float timeout: How many seconds the connection should wait before raising an exception, if the database is locked by another connection. If another connection opens a transaction to modify the database, it will be locked until that transaction is committed. Default five seconds. - :type timeout: float - :param detect_types: + :param int detect_types: Control whether and how data types not :ref:`natively supported by SQLite <sqlite3-types>` are looked up to be converted to Python types, @@ -306,7 +305,6 @@ Module functions and constants even when the *detect_types* parameter is set; :class:`str` will be returned instead. By default (``0``), type detection is disabled. - :type detect_types: int :param isolation_level: The :attr:`~Connection.isolation_level` of the connection, @@ -316,25 +314,22 @@ Module functions and constants See :ref:`sqlite3-controlling-transactions` for more. :type isolation_level: str | None - :param check_same_thread: + :param bool check_same_thread: If ``True`` (default), only the creating thread may use the connection. If ``False``, the connection may be shared across multiple threads; if so, write operations should be serialized by the user to avoid data corruption. - :type check_same_thread: bool - :param factory: + :param Connection factory: A custom subclass of :class:`Connection` to create the connection with, if not the default :class:`Connection` class. - :type factory: :class:`Connection` - :param cached_statements: + :param int cached_statements: The number of statements that ``sqlite3`` should internally cache for this connection, to avoid parsing overhead. By default, 128 statements. - :type cached_statements: int - :param uri: + :param bool uri: If set to ``True``, *database* is interpreted as a :abbr:`URI (Uniform Resource Identifier)` with a file path and an optional query string. @@ -342,7 +337,6 @@ Module functions and constants and the path can be relative or absolute. The query string allows passing parameters to SQLite, enabling various :ref:`sqlite3-uri-tricks`. - :type uri: bool :rtype: Connection @@ -477,28 +471,23 @@ Connection objects Open a :class:`Blob` handle to an existing :abbr:`BLOB (Binary Large OBject)`. - :param table: + :param str table: The name of the table where the blob is located. - :type table: str - :param column: + :param str column: The name of the column where the blob is located. - :type column: str - :param row: + :param str row: The name of the row where the blob is located. - :type row: str - :param readonly: + :param bool readonly: Set to ``True`` if the blob should be opened without write permissions. Defaults to ``False``. - :type readonly: bool - :param name: + :param str name: The name of the database where the blob is located. Defaults to ``"main"``. - :type name: str :raises OperationalError: When trying to open a blob in a ``WITHOUT ROWID`` table. @@ -551,14 +540,12 @@ Connection objects Create or remove a user-defined SQL function. - :param name: + :param str name: The name of the SQL function. - :type name: str - :param narg: + :param int narg: The number of arguments the SQL function can accept. If ``-1``, it may take any number of arguments. - :type narg: int :param func: A callable that is called when the SQL function is invoked. @@ -567,11 +554,10 @@ Connection objects Set to ``None`` to remove an existing SQL function. :type func: :term:`callback` | None - :param deterministic: + :param bool deterministic: If ``True``, the created SQL function is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which allows SQLite to perform additional optimizations. - :type deterministic: bool :raises NotSupportedError: If *deterministic* is used with SQLite versions older than 3.8.3. @@ -588,14 +574,12 @@ Connection objects Create or remove a user-defined SQL aggregate function. - :param name: + :param str name: The name of the SQL aggregate function. - :type name: str - :param n_arg: + :param int n_arg: The number of arguments the SQL aggregate function can accept. If ``-1``, it may take any number of arguments. - :type n_arg: int :param aggregate_class: A class must implement the following methods: @@ -619,14 +603,12 @@ Connection objects Create or remove a user-defined aggregate window function. - :param name: + :param str name: The name of the SQL aggregate window function to create or remove. - :type name: str - :param num_params: + :param int num_params: The number of arguments the SQL aggregate window function can accept. If ``-1``, it may take any number of arguments. - :type num_params: int :param aggregate_class: A class that must implement the following methods: @@ -852,16 +834,14 @@ Connection objects Works even if the database is being accessed by other clients or concurrently by the same connection. - :param target: + :param Connection target: The database connection to save the backup to. - :type target: Connection - :param pages: + :param int pages: The number of pages to copy at a time. If equal to or less than ``0``, the entire database is copied in a single step. Defaults to ``-1``. - :type pages: int :param progress: If set to a callable, it is invoked with three integer arguments for @@ -872,18 +852,16 @@ Connection objects Defaults to ``None``. :type progress: :term:`callback` |?None - :param name: + :param str name: The name of the database to back up. Either ``"main"`` (the default) for the main database, ``"temp"`` for the temporary database, or the name of a custom database as attached using the ``ATTACH DATABASE`` SQL statement. - :type name: str - :param sleep: + :param float sleep: The number of seconds to sleep between successive attempts to back up remaining pages. - :type sleep: float Example 1, copy an existing database into another:: @@ -909,11 +887,17 @@ Connection objects .. versionadded:: 3.7 - .. method:: getlimit(category, /) - Get a connection runtime limit. *category* is the limit category to be - queried. + Get a connection runtime limit. + + :param int category: + The `SQLite limit category`_ to be queried. + + :rtype: int + + :raises ProgrammingError: + If *category* is not recognised by the underlying SQLite library. Example, query the maximum length of an SQL statement:: @@ -927,14 +911,23 @@ Connection objects .. method:: setlimit(category, limit, /) - Set a connection runtime limit. *category* is the limit category to be - set. *limit* is the new limit. If the new limit is a negative number, the - limit is unchanged. - + Set a connection runtime limit. Attempts to increase a limit above its hard upper bound are silently truncated to the hard upper bound. Regardless of whether or not the limit was changed, the prior value of the limit is returned. + :param int category: + The `SQLite limit category`_ to be set. + + :param int limit: + The value of the new limit. + If negative, the current limit is unchanged. + + :rtype: int + + :raises ProgrammingError: + If *category* is not recognised by the underlying SQLite library. + Example, limit the number of attached databases to 1:: import sqlite3 @@ -943,6 +936,8 @@ Connection objects .. versionadded:: 3.11 +.. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html + .. method:: serialize(*, name="main") @@ -952,8 +947,11 @@ Connection objects serialization is the same sequence of bytes which would be written to disk if that database were backed up to disk. - *name* is the database to be serialized, and defaults to the main - database. + :param str name: + The database name to be serialized. + Defaults to ``"main"``. + + :rtype: bytes .. note:: @@ -969,12 +967,24 @@ Connection objects :class:`Connection`. This method causes the database connection to disconnect from database *name*, and reopen *name* as an in-memory database based on the - serialization contained in *data*. Deserialization will raise - :exc:`OperationalError` if the database connection is currently involved - in a read transaction or a backup operation. :exc:`OverflowError` will be - raised if ``len(data)`` is larger than ``2**63 - 1``, and - :exc:`DatabaseError` will be raised if *data* does not contain a valid - SQLite database. + serialization contained in *data*. + + :param bytes data: + A serialized database. + + :param str name: + The database name to deserialize into. + Defaults to ``"main"``. + + :raises OperationalError: + If the database connection is currently involved in a read + transaction or a backup operation. + + :raises DatabaseError: + If *data* does not contain a valid SQLite database. + + :raises OverflowError: + If :func:`len(data) <len>` is larger than ``2**63 - 1``. .. note:: @@ -1071,13 +1081,13 @@ Cursor objects .. method:: fetchone() - Fetch the next row of a query result set as a :class:`tuple`. + Return the next row of a query result set as a :class:`tuple`. Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) - Fetch the next set of rows of a query result as a :class:`list`. + Return the next set of rows of a query result as a :class:`list`. Return an empty list if no more rows are available. The number of rows to fetch per call is specified by the *size* parameter. @@ -1093,7 +1103,7 @@ Cursor objects .. method:: fetchall() - Fetch all (remaining) rows of a query result as a :class:`list`. + Return all (remaining) rows of a query result as a :class:`list`. Return an empty list if no rows are available. Note that the :attr:`arraysize` attribute can affect the performance of this operation. From webhook-mailer at python.org Thu Aug 4 16:14:12 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 20:14:12 -0000 Subject: [Python-checkins] [3.10] gh-95273: Improve documented return values and exceptions raised for sqlite3 class methods (GH-95530) (#95674) Message-ID: <mailman.506.1659644053.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4a204c148605a327bd99bed87d0d5f5b02143ce5 commit: 4a204c148605a327bd99bed87d0d5f5b02143ce5 branch: 3.10 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T22:14:02+02:00 summary: [3.10] gh-95273: Improve documented return values and exceptions raised for sqlite3 class methods (GH-95530) (#95674) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com>. (cherry picked from commit 12d92c733cfc00ee630b30e4e0250da400c83395) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 6afda5934ad..52a5ecaab99 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -267,15 +267,14 @@ Module functions and constants in RAM instead of on disk. :type database: :term:`path-like object` - :param timeout: + :param float timeout: How many seconds the connection should wait before raising an exception, if the database is locked by another connection. If another connection opens a transaction to modify the database, it will be locked until that transaction is committed. Default five seconds. - :type timeout: float - :param detect_types: + :param int detect_types: Control whether and how data types not :ref:`natively supported by SQLite <sqlite3-types>` are looked up to be converted to Python types, @@ -288,7 +287,6 @@ Module functions and constants even when the *detect_types* parameter is set; :class:`str` will be returned instead. By default (``0``), type detection is disabled. - :type detect_types: int :param isolation_level: The :attr:`~Connection.isolation_level` of the connection, @@ -298,25 +296,22 @@ Module functions and constants See :ref:`sqlite3-controlling-transactions` for more. :type isolation_level: str | None - :param check_same_thread: + :param bool check_same_thread: If ``True`` (default), only the creating thread may use the connection. If ``False``, the connection may be shared across multiple threads; if so, write operations should be serialized by the user to avoid data corruption. - :type check_same_thread: bool - :param factory: + :param Connection factory: A custom subclass of :class:`Connection` to create the connection with, if not the default :class:`Connection` class. - :type factory: :class:`Connection` - :param cached_statements: + :param int cached_statements: The number of statements that ``sqlite3`` should internally cache for this connection, to avoid parsing overhead. By default, 100 statements. - :type cached_statements: int - :param uri: + :param bool uri: If set to ``True``, *database* is interpreted as a :abbr:`URI (Uniform Resource Identifier)` with a file path and an optional query string. @@ -324,7 +319,6 @@ Module functions and constants and the path can be relative or absolute. The query string allows passing parameters to SQLite, enabling various :ref:`sqlite3-uri-tricks`. - :type uri: bool :rtype: Connection @@ -475,14 +469,12 @@ Connection objects Create or remove a user-defined SQL function. - :param name: + :param str name: The name of the SQL function. - :type name: str - :param narg: + :param int narg: The number of arguments the SQL function can accept. If ``-1``, it may take any number of arguments. - :type narg: int :param func: A callable that is called when the SQL function is invoked. @@ -491,11 +483,10 @@ Connection objects Set to ``None`` to remove an existing SQL function. :type func: :term:`callback` | None - :param deterministic: + :param bool deterministic: If ``True``, the created SQL function is marked as `deterministic <https://sqlite.org/deterministic.html>`_, which allows SQLite to perform additional optimizations. - :type deterministic: bool :raises NotSupportedError: If *deterministic* is used with SQLite versions older than 3.8.3. @@ -512,14 +503,12 @@ Connection objects Create or remove a user-defined SQL aggregate function. - :param name: + :param str name: The name of the SQL aggregate function. - :type name: str - :param n_arg: + :param int n_arg: The number of arguments the SQL aggregate function can accept. If ``-1``, it may take any number of arguments. - :type n_arg: int :param aggregate_class: A class must implement the following methods: @@ -727,16 +716,14 @@ Connection objects Works even if the database is being accessed by other clients or concurrently by the same connection. - :param target: + :param Connection target: The database connection to save the backup to. - :type target: Connection - :param pages: + :param int pages: The number of pages to copy at a time. If equal to or less than ``0``, the entire database is copied in a single step. Defaults to ``-1``. - :type pages: int :param progress: If set to a callable, it is invoked with three integer arguments for @@ -747,18 +734,16 @@ Connection objects Defaults to ``None``. :type progress: :term:`callback` |?None - :param name: + :param str name: The name of the database to back up. Either ``"main"`` (the default) for the main database, ``"temp"`` for the temporary database, or the name of a custom database as attached using the ``ATTACH DATABASE`` SQL statement. - :type name: str - :param sleep: + :param float sleep: The number of seconds to sleep between successive attempts to back up remaining pages. - :type sleep: float Example 1, copy an existing database into another:: @@ -872,13 +857,13 @@ Cursor objects .. method:: fetchone() - Fetch the next row of a query result set as a :class:`tuple`. + Return the next row of a query result set as a :class:`tuple`. Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) - Fetch the next set of rows of a query result as a :class:`list`. + Return the next set of rows of a query result as a :class:`list`. Return an empty list if no more rows are available. The number of rows to fetch per call is specified by the *size* parameter. @@ -894,7 +879,7 @@ Cursor objects .. method:: fetchall() - Fetch all (remaining) rows of a query result as a :class:`list`. + Return all (remaining) rows of a query result as a :class:`list`. Return an empty list if no rows are available. Note that the :attr:`arraysize` attribute can affect the performance of this operation. From webhook-mailer at python.org Thu Aug 4 16:18:29 2022 From: webhook-mailer at python.org (vsajip) Date: Thu, 04 Aug 2022 20:18:29 -0000 Subject: [Python-checkins] Remove unnecessary text from documentation. (GH-95670) Message-ID: <mailman.507.1659644311.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c47d09a4accb84609bc56eeb6d77248c4e034833 commit: c47d09a4accb84609bc56eeb6d77248c4e034833 branch: main author: fluesvamp <105884371+fluesvamp at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-04T21:18:05+01:00 summary: Remove unnecessary text from documentation. (GH-95670) files: M Doc/using/venv-create.inc diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index b9785832864..c2a9f521a14 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -26,7 +26,7 @@ re-used. On Windows, invoke the ``venv`` command as follows:: - c:\>c:\Python35\python -m venv c:\path\to\myenv + c:\>Python35\python -m venv c:\path\to\myenv Alternatively, if you configured the ``PATH`` and ``PATHEXT`` variables for your :ref:`Python installation <using-on-windows>`:: From webhook-mailer at python.org Thu Aug 4 16:19:44 2022 From: webhook-mailer at python.org (ned-deily) Date: Thu, 04 Aug 2022 20:19:44 -0000 Subject: [Python-checkins] Remove 3.11 beta release notice from macOS installer displays (GH-95669) Message-ID: <mailman.508.1659644386.3313.python-checkins@python.org> https://github.com/python/cpython/commit/71ca01e470f37b95c3266e9b2944b980dd618ded commit: 71ca01e470f37b95c3266e9b2944b980dd618ded branch: 3.11 author: Ned Deily <nad at python.org> committer: ned-deily <nad at python.org> date: 2022-08-04T16:19:32-04:00 summary: Remove 3.11 beta release notice from macOS installer displays (GH-95669) files: M Mac/BuildScript/resources/ReadMe.rtf M Mac/BuildScript/resources/Welcome.rtf diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index a43ca9fc788a..2d6ca8f26189 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2638 +{\rtf1\ansi\ansicpg1252\cocoartf2639 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; \f3\fmodern\fcharset0 CourierNewPSMT;\f4\fmodern\fcharset0 Courier;} {\colortbl;\red255\green255\blue255;} @@ -8,12 +8,6 @@ \f0\fs24 \cf0 This package will install Python $FULL_VERSION for macOS $MACOSX_DEPLOYMENT_TARGET for the following architecture(s): $ARCHITECTURES.\ \ -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0 - -\f1\b \cf0 NOTE: -\f0\b0 This is a beta test preview of Python 3.11.0, the next feature release of Python 3. It is not intended for production use.\ -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\cf0 \ \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 \f1\b \cf0 \ul \ulc0 Certificate verification and OpenSSL\ diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf index 4ff8a0e874f2..4a0dac36320d 100644 --- a/Mac/BuildScript/resources/Welcome.rtf +++ b/Mac/BuildScript/resources/Welcome.rtf @@ -1,9 +1,9 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2638 +{\rtf1\ansi\ansicpg1252\cocoartf2639 \cocoascreenfonts1\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT; } {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} -\paperw11900\paperh16840\margl1440\margr1440\vieww12200\viewh10880\viewkind0 +\paperw11905\paperh16837\margl1440\margr1440\vieww12200\viewh10880\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0 \f0\fs24 \cf0 This package will install @@ -23,8 +23,4 @@ At the end of this install, click on \f2 Install Certificates \f0 to install a set of current SSL root certificates.\ -\ - -\f1\b NOTE: -\f0\b0 This is a beta test preview of Python 3.11.0, the next feature release of Python 3. It is not intended for production use.\ } \ No newline at end of file From webhook-mailer at python.org Thu Aug 4 16:41:36 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 20:41:36 -0000 Subject: [Python-checkins] gh-95271: Extract placeholders howto from sqlite3 tutorial (#95522) Message-ID: <mailman.509.1659645698.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b24e8b28a7dc585ba367a959be83393f2352d21d commit: b24e8b28a7dc585ba367a959be83393f2352d21d branch: main author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T22:41:18+02:00 summary: gh-95271: Extract placeholders howto from sqlite3 tutorial (#95522) Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index ddb6407a864..1ecb33b5ddf 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -94,6 +94,12 @@ using :meth:`~Cursor.executemany`:: ... ] >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data) +Notice that we used ``?`` placeholders to bind *data* to the query. +Always use placeholders instead of :ref:`string formatting <tut-formatting>` +to bind Python values to SQL statements, +to avoid `SQL injection attacks`_. +See the :ref:`placeholders how-to <sqlite3-placeholders>` for more details. + Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): @@ -104,33 +110,9 @@ Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: ('2006-04-06', 'SELL', 'IBM', 500, 53.0) ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) +You've now created an SQLite database using the :mod:`!sqlite3` module. -.. _sqlite3-placeholders: - -SQL operations usually need to use values from Python variables. However, -beware of using Python's string operations to assemble queries, as they -are vulnerable to SQL injection attacks (see the `xkcd webcomic -<https://xkcd.com/327/>`_ for a humorous example of what can go wrong):: - - # Never do this -- insecure! - symbol = 'RHAT' - cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) - -Instead, use the DB-API's parameter substitution. To insert a variable into a -query string, use a placeholder in the string, and substitute the actual values -into the query by providing them as a :class:`tuple` of values to the second -argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may -use one of two kinds of placeholders: question marks (qmark style) or named -placeholders (named style). For the qmark style, ``parameters`` must be a -:term:`sequence <sequence>`. For the named style, it can be either a -:term:`sequence <sequence>` or :class:`dict` instance. The length of the -:term:`sequence <sequence>` must match the number of placeholders, or a -:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain -keys for all named parameters. Any extra items are ignored. Here's an example of -both styles: - -.. literalinclude:: ../includes/sqlite3/execute_1.py - +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection .. seealso:: @@ -1479,6 +1461,36 @@ Type ``.quit`` or CTRL-D to exit the shell. How-to guides ------------- +.. _sqlite3-placeholders: + +Using placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SQL operations usually need to use values from Python variables. However, +beware of using Python's string operations to assemble queries, as they +are vulnerable to `SQL injection attacks`_ (see the `xkcd webcomic +<https://xkcd.com/327/>`_ for a humorous example of what can go wrong):: + + # Never do this -- insecure! + symbol = 'RHAT' + cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) + +Instead, use the DB-API's parameter substitution. To insert a variable into a +query string, use a placeholder in the string, and substitute the actual values +into the query by providing them as a :class:`tuple` of values to the second +argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may +use one of two kinds of placeholders: question marks (qmark style) or named +placeholders (named style). For the qmark style, ``parameters`` must be a +:term:`sequence <sequence>`. For the named style, it can be either a +:term:`sequence <sequence>` or :class:`dict` instance. The length of the +:term:`sequence <sequence>` must match the number of placeholders, or a +:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain +keys for all named parameters. Any extra items are ignored. Here's an example of +both styles: + +.. literalinclude:: ../includes/sqlite3/execute_1.py + + .. _sqlite3-adapters: Using adapters to store custom Python types in SQLite databases From webhook-mailer at python.org Thu Aug 4 16:54:01 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 20:54:01 -0000 Subject: [Python-checkins] [3.10] gh-95271: Extract placeholders howto from sqlite3 tutorial (GH-95522) (#95678) Message-ID: <mailman.510.1659646443.3313.python-checkins@python.org> https://github.com/python/cpython/commit/54ea127923eee1672fd67cc96a4a0b10961f52ed commit: 54ea127923eee1672fd67cc96a4a0b10961f52ed branch: 3.10 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T22:53:51+02:00 summary: [3.10] gh-95271: Extract placeholders howto from sqlite3 tutorial (GH-95522) (#95678) Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit b24e8b28a7dc585ba367a959be83393f2352d21d) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 52a5ecaab99..990071419c6 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -94,6 +94,12 @@ using :meth:`~Cursor.executemany`:: ... ] >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data) +Notice that we used ``?`` placeholders to bind *data* to the query. +Always use placeholders instead of :ref:`string formatting <tut-formatting>` +to bind Python values to SQL statements, +to avoid `SQL injection attacks`_. +See the :ref:`placeholders how-to <sqlite3-placeholders>` for more details. + Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): @@ -104,33 +110,9 @@ Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: ('2006-04-06', 'SELL', 'IBM', 500, 53.0) ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) +You've now created an SQLite database using the :mod:`!sqlite3` module. -.. _sqlite3-placeholders: - -SQL operations usually need to use values from Python variables. However, -beware of using Python's string operations to assemble queries, as they -are vulnerable to SQL injection attacks (see the `xkcd webcomic -<https://xkcd.com/327/>`_ for a humorous example of what can go wrong):: - - # Never do this -- insecure! - symbol = 'RHAT' - cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) - -Instead, use the DB-API's parameter substitution. To insert a variable into a -query string, use a placeholder in the string, and substitute the actual values -into the query by providing them as a :class:`tuple` of values to the second -argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may -use one of two kinds of placeholders: question marks (qmark style) or named -placeholders (named style). For the qmark style, ``parameters`` must be a -:term:`sequence <sequence>`. For the named style, it can be either a -:term:`sequence <sequence>` or :class:`dict` instance. The length of the -:term:`sequence <sequence>` must match the number of placeholders, or a -:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain -keys for all named parameters. Any extra items are ignored. Here's an example of -both styles: - -.. literalinclude:: ../includes/sqlite3/execute_1.py - +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection .. seealso:: @@ -1151,6 +1133,36 @@ Python types via :ref:`converters <sqlite3-converters>`. How-to guides ------------- +.. _sqlite3-placeholders: + +Using placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SQL operations usually need to use values from Python variables. However, +beware of using Python's string operations to assemble queries, as they +are vulnerable to `SQL injection attacks`_ (see the `xkcd webcomic +<https://xkcd.com/327/>`_ for a humorous example of what can go wrong):: + + # Never do this -- insecure! + symbol = 'RHAT' + cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) + +Instead, use the DB-API's parameter substitution. To insert a variable into a +query string, use a placeholder in the string, and substitute the actual values +into the query by providing them as a :class:`tuple` of values to the second +argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may +use one of two kinds of placeholders: question marks (qmark style) or named +placeholders (named style). For the qmark style, ``parameters`` must be a +:term:`sequence <sequence>`. For the named style, it can be either a +:term:`sequence <sequence>` or :class:`dict` instance. The length of the +:term:`sequence <sequence>` must match the number of placeholders, or a +:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain +keys for all named parameters. Any extra items are ignored. Here's an example of +both styles: + +.. literalinclude:: ../includes/sqlite3/execute_1.py + + .. _sqlite3-adapters: Using adapters to store custom Python types in SQLite databases From webhook-mailer at python.org Thu Aug 4 17:02:38 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 21:02:38 -0000 Subject: [Python-checkins] [3.11] gh-95271: Extract placeholders howto from sqlite3 tutorial (GH-95522) (#95677) Message-ID: <mailman.511.1659646959.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4d37b42295bf2c3373efe86e60d840e5b966c03a commit: 4d37b42295bf2c3373efe86e60d840e5b966c03a branch: 3.11 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-04T23:02:28+02:00 summary: [3.11] gh-95271: Extract placeholders howto from sqlite3 tutorial (GH-95522) (#95677) Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit b24e8b28a7dc585ba367a959be83393f2352d21d) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index f6496575bf0..f902a991232 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -94,6 +94,12 @@ using :meth:`~Cursor.executemany`:: ... ] >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data) +Notice that we used ``?`` placeholders to bind *data* to the query. +Always use placeholders instead of :ref:`string formatting <tut-formatting>` +to bind Python values to SQL statements, +to avoid `SQL injection attacks`_. +See the :ref:`placeholders how-to <sqlite3-placeholders>` for more details. + Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): @@ -104,33 +110,9 @@ Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: ('2006-04-06', 'SELL', 'IBM', 500, 53.0) ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) +You've now created an SQLite database using the :mod:`!sqlite3` module. -.. _sqlite3-placeholders: - -SQL operations usually need to use values from Python variables. However, -beware of using Python's string operations to assemble queries, as they -are vulnerable to SQL injection attacks (see the `xkcd webcomic -<https://xkcd.com/327/>`_ for a humorous example of what can go wrong):: - - # Never do this -- insecure! - symbol = 'RHAT' - cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) - -Instead, use the DB-API's parameter substitution. To insert a variable into a -query string, use a placeholder in the string, and substitute the actual values -into the query by providing them as a :class:`tuple` of values to the second -argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may -use one of two kinds of placeholders: question marks (qmark style) or named -placeholders (named style). For the qmark style, ``parameters`` must be a -:term:`sequence <sequence>`. For the named style, it can be either a -:term:`sequence <sequence>` or :class:`dict` instance. The length of the -:term:`sequence <sequence>` must match the number of placeholders, or a -:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain -keys for all named parameters. Any extra items are ignored. Here's an example of -both styles: - -.. literalinclude:: ../includes/sqlite3/execute_1.py - +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection .. seealso:: @@ -1447,6 +1429,36 @@ Python types via :ref:`converters <sqlite3-converters>`. How-to guides ------------- +.. _sqlite3-placeholders: + +Using placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SQL operations usually need to use values from Python variables. However, +beware of using Python's string operations to assemble queries, as they +are vulnerable to `SQL injection attacks`_ (see the `xkcd webcomic +<https://xkcd.com/327/>`_ for a humorous example of what can go wrong):: + + # Never do this -- insecure! + symbol = 'RHAT' + cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) + +Instead, use the DB-API's parameter substitution. To insert a variable into a +query string, use a placeholder in the string, and substitute the actual values +into the query by providing them as a :class:`tuple` of values to the second +argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may +use one of two kinds of placeholders: question marks (qmark style) or named +placeholders (named style). For the qmark style, ``parameters`` must be a +:term:`sequence <sequence>`. For the named style, it can be either a +:term:`sequence <sequence>` or :class:`dict` instance. The length of the +:term:`sequence <sequence>` must match the number of placeholders, or a +:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain +keys for all named parameters. Any extra items are ignored. Here's an example of +both styles: + +.. literalinclude:: ../includes/sqlite3/execute_1.py + + .. _sqlite3-adapters: Using adapters to store custom Python types in SQLite databases From webhook-mailer at python.org Thu Aug 4 17:44:27 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 04 Aug 2022 21:44:27 -0000 Subject: [Python-checkins] [3.11] gh-92678: Correct return values for errors in PyInit__testcapi (#95664) Message-ID: <mailman.512.1659649468.3313.python-checkins@python.org> https://github.com/python/cpython/commit/cb02dc0872195e79cf61616e29d3aefc8b0e664f commit: cb02dc0872195e79cf61616e29d3aefc8b0e664f branch: 3.11 author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-04T22:44:06+01:00 summary: [3.11] gh-92678: Correct return values for errors in PyInit__testcapi (#95664) files: M Modules/_testcapimodule.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 961616dae63..8087b444939 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -7824,7 +7824,7 @@ PyInit__testcapi(void) PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); if (HeapCTypeWithDict2 == NULL) { - return -1; + return NULL; } PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); @@ -7848,7 +7848,7 @@ PyInit__testcapi(void) PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); if (HeapCTypeWithWeakref2 == NULL) { - return -1; + return NULL; } PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); From webhook-mailer at python.org Thu Aug 4 18:06:57 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 04 Aug 2022 22:06:57 -0000 Subject: [Python-checkins] Docs: sqlite3 docs fixup (#95681) Message-ID: <mailman.513.1659650818.3313.python-checkins@python.org> https://github.com/python/cpython/commit/44f1f63ad5cf00b6f50cef0cc1a62c42632138be commit: 44f1f63ad5cf00b6f50cef0cc1a62c42632138be branch: main author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-05T00:06:46+02:00 summary: Docs: sqlite3 docs fixup (#95681) - Disable links to the module itself - Fix link indent - Consistent ref markup files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 1ecb33b5ddf..140dccfea94 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -146,12 +146,12 @@ Module functions and constants .. data:: paramstyle String constant stating the type of parameter marker formatting expected by - the :mod:`sqlite3` module. Required by the DB-API. Hard-coded to + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to ``"qmark"``. .. note:: - The :mod:`sqlite3` module supports both ``qmark`` and ``numeric`` DB-API + The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API parameter styles, because that is what the underlying SQLite library supports. However, the DB-API does not allow multiple values for the ``paramstyle`` attribute. @@ -164,7 +164,7 @@ Module functions and constants .. deprecated-removed:: 3.12 3.14 This constant used to reflect the version number of the ``pysqlite`` package, a third-party library which used to upstream changes to - ``sqlite3``. Today, it carries no meaning or practical value. + :mod:`!sqlite3`. Today, it carries no meaning or practical value. .. data:: version_info @@ -175,7 +175,7 @@ Module functions and constants .. deprecated-removed:: 3.12 3.14 This constant used to reflect the version number of the ``pysqlite`` package, a third-party library which used to upstream changes to - ``sqlite3``. Today, it carries no meaning or practical value. + :mod:`!sqlite3`. Today, it carries no meaning or practical value. .. data:: sqlite_version @@ -192,7 +192,7 @@ Module functions and constants .. data:: threadsafety Integer constant required by the DB-API 2.0, stating the level of thread - safety the :mod:`sqlite3` module supports. This attribute is set based on + safety the :mod:`!sqlite3` module supports. This attribute is set based on the default `threading mode <https://sqlite.org/threadsafe.html>`_ the underlying SQLite library is compiled with. The SQLite threading modes are: @@ -233,7 +233,7 @@ Module functions and constants :func:`connect` to look up a converter function using the declared types for each column. The types are declared when the database table is created. - ``sqlite3`` will look up a converter function using the first word of the + :mod:`!sqlite3` will look up a converter function using the first word of the declared type as the converter dictionary key. For example: @@ -317,7 +317,7 @@ Module functions and constants if not the default :class:`Connection` class. :param int cached_statements: - The number of statements that ``sqlite3`` + The number of statements that :mod:`!sqlite3` should internally cache for this connection, to avoid parsing overhead. By default, 128 statements. @@ -365,7 +365,7 @@ Module functions and constants SQLite type. The adapter is called with a Python object of type *type* as its sole argument, and must return a value of a - :ref:`type that SQLite natively understands<sqlite3-types>`. + :ref:`type that SQLite natively understands <sqlite3-types>`. .. function:: complete_statement(statement) @@ -431,7 +431,7 @@ Connection objects .. attribute:: isolation_level This attribute controls the :ref:`transaction handling - <sqlite3-controlling-transactions>` performed by ``sqlite3``. + <sqlite3-controlling-transactions>` performed by :mod:`!sqlite3`. If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, @@ -664,7 +664,7 @@ Connection objects :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL statement should be aborted with an error and :const:`SQLITE_IGNORE` if the column should be treated as a NULL value. These constants are available in the - :mod:`sqlite3` module. + :mod:`!sqlite3` module. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or ``None`` @@ -675,7 +675,7 @@ Connection objects Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first - one. All necessary constants are available in the :mod:`sqlite3` module. + one. All necessary constants are available in the :mod:`!sqlite3` module. Passing ``None`` as *authorizer_callback* will disable the authorizer. @@ -733,7 +733,7 @@ Connection objects .. note:: - The ``sqlite3`` module is not built with loadable extension support by + The :mod:`!sqlite3` module is not built with loadable extension support by default, because some platforms (notably macOS) have SQLite libraries which are compiled without this feature. To get loadable extension support, @@ -928,7 +928,7 @@ Connection objects .. versionadded:: 3.11 -.. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html + .. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html .. method:: serialize(*, name="main") @@ -1109,11 +1109,11 @@ Cursor objects .. method:: setinputsizes(sizes, /) - Required by the DB-API. Does nothing in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. method:: setoutputsize(size, column=None, /) - Required by the DB-API. Does nothing in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. attribute:: rowcount @@ -1301,8 +1301,8 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: Warning - This exception is not currently raised by the ``sqlite3`` module, - but may be raised by applications using ``sqlite3``, + This exception is not currently raised by the :mod:`!sqlite3` module, + but may be raised by applications using :mod:`!sqlite3`, for example if a user-defined function truncates data while inserting. ``Warning`` is a subclass of :exc:`Exception`. @@ -1333,7 +1333,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Exception raised for misuse of the low-level SQLite C API. In other words, if this exception is raised, it probably indicates a bug in the - ``sqlite3`` module. + :mod:`!sqlite3` module. ``InterfaceError`` is a subclass of :exc:`Error`. .. exception:: DatabaseError @@ -1371,7 +1371,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: ProgrammingError - Exception raised for ``sqlite3`` API programming errors, + Exception raised for :mod:`!sqlite3` API programming errors, for example supplying the wrong number of bindings to a query, or trying to operate on a closed :class:`Connection`. ``ProgrammingError`` is a subclass of :exc:`DatabaseError`. @@ -1427,10 +1427,10 @@ This is how SQLite types are converted to Python types by default: | ``BLOB`` | :class:`bytes` | +-------------+----------------------------------------------+ -The type system of the :mod:`sqlite3` module is extensible in two ways: you can +The type system of the :mod:`!sqlite3` module is extensible in two ways: you can store additional Python types in an SQLite database via :ref:`object adapters <sqlite3-adapters>`, -and you can let the ``sqlite3`` module convert SQLite types to +and you can let the :mod:`!sqlite3` module convert SQLite types to Python types via :ref:`converters <sqlite3-converters>`. @@ -1439,7 +1439,7 @@ Python types via :ref:`converters <sqlite3-converters>`. Command-line interface ^^^^^^^^^^^^^^^^^^^^^^ -The ``sqlite3`` module can be invoked as a script +The :mod:`!sqlite3` module can be invoked as a script in order to provide a simple SQLite shell. Type ``.quit`` or CTRL-D to exit the shell. @@ -1498,7 +1498,7 @@ Using adapters to store custom Python types in SQLite databases SQLite supports only a limited set of data types natively. To store custom Python types in SQLite databases, *adapt* them to one of the -:ref:`Python types SQLite natively understands<sqlite3-types>`. +:ref:`Python types SQLite natively understands <sqlite3-types>`. There are two ways to adapt Python objects to SQLite types: letting your object adapt itself, or using an *adapter callable*. @@ -1562,7 +1562,7 @@ and constructs a :class:`Point` object from it. x, y = map(float, s.split(b";")) return Point(x, y) -We now need to tell ``sqlite3`` when it should convert a given SQLite value. +We now need to tell :mod:`!sqlite3` when it should convert a given SQLite value. This is done when connecting to a database, using the *detect_types* parameter of :func:`connect`. There are three options: @@ -1679,7 +1679,7 @@ directly using only a single call on the :class:`Connection` object. Accessing columns by name instead of by index ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -One useful feature of the :mod:`sqlite3` module is the built-in +One useful feature of the :mod:`!sqlite3` module is the built-in :class:`sqlite3.Row` class designed to be used as a row factory. Rows wrapped with this class can be accessed both by index (like tuples) and @@ -1754,7 +1754,7 @@ Explanation Transaction control ^^^^^^^^^^^^^^^^^^^ -The ``sqlite3`` module does not adhere to the transaction handling recommended +The :mod:`!sqlite3` module does not adhere to the transaction handling recommended by :pep:`249`. If the connection attribute :attr:`~Connection.isolation_level` @@ -1765,7 +1765,7 @@ new transactions are implicitly opened before Use the :meth:`~Connection.commit` and :meth:`~Connection.rollback` methods to respectively commit and roll back pending transactions. You can choose the underlying `SQLite transaction behaviour`_ ? -that is, whether and what type of ``BEGIN`` statements ``sqlite3`` +that is, whether and what type of ``BEGIN`` statements :mod:`!sqlite3` implicitly executes ? via the :attr:`~Connection.isolation_level` attribute. @@ -1782,7 +1782,7 @@ any pending transaction before execution of the given SQL script, regardless of the value of :attr:`~Connection.isolation_level`. .. versionchanged:: 3.6 - :mod:`sqlite3` used to implicitly commit an open transaction before DDL + :mod:`!sqlite3` used to implicitly commit an open transaction before DDL statements. This is no longer the case. .. _autocommit mode: From webhook-mailer at python.org Thu Aug 4 20:24:34 2022 From: webhook-mailer at python.org (warsaw) Date: Fri, 05 Aug 2022 00:24:34 -0000 Subject: [Python-checkins] gh-94619: Remove long deprecated methods module_repr() and load_module() (#94624) Message-ID: <mailman.514.1659659074.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e1182bc3776ea7cfdd3f82d5ba4fdfee40ae57ee commit: e1182bc3776ea7cfdd3f82d5ba4fdfee40ae57ee branch: main author: Barry Warsaw <barry at python.org> committer: warsaw <barry at python.org> date: 2022-08-04T17:24:26-07:00 summary: gh-94619: Remove long deprecated methods module_repr() and load_module() (#94624) * gh-94619: Remove long deprecated methods module_repr() and load_module() Closes #94619 * Update Misc/NEWS.d/next/Library/2022-07-06-14-57-33.gh-issue-94619.PRqKVX.rst Fix typo Co-authored-by: Brett Cannon <brett at python.org> Co-authored-by: Brett Cannon <brett at python.org> files: A Misc/NEWS.d/next/Library/2022-07-06-14-57-33.gh-issue-94619.PRqKVX.rst M Doc/library/importlib.rst M Doc/reference/import.rst M Lib/importlib/_abc.py M Lib/importlib/_bootstrap.py M Lib/importlib/_bootstrap_external.py M Lib/test/test_importlib/frozen/test_loader.py M Lib/test/test_importlib/source/test_file_loader.py M Lib/test/test_importlib/test_abc.py M Lib/test/test_importlib/test_namespace_pkgs.py M Lib/test/test_importlib/test_spec.py M Lib/test/test_module.py diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index c29d69c143cf..0fd765f5985f 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -493,20 +493,6 @@ ABC hierarchy:: other responsibilities of :meth:`load_module` when :meth:`exec_module` is implemented. - .. method:: module_repr(module) - - A legacy method which when implemented calculates and returns the given - module's representation, as a string. The module type's default - :meth:`__repr__` will use the result of this method as appropriate. - - .. versionadded:: 3.3 - - .. versionchanged:: 3.4 - Made optional instead of an abstractmethod. - - .. deprecated:: 3.4 - The import machinery now takes care of this automatically. - .. class:: ResourceLoader diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 1e6b08f32a7a..507f2b3763ca 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -676,22 +676,10 @@ Here are the exact rules used: * Otherwise, just use the module's ``__name__`` in the repr. -.. versionchanged:: 3.4 - Use of :meth:`loader.module_repr() <importlib.abc.Loader.module_repr>` - has been deprecated and the module spec is now used by the import - machinery to generate a module repr. - - For backward compatibility with Python 3.3, the module repr will be - generated by calling the loader's - :meth:`~importlib.abc.Loader.module_repr` method, if defined, before - trying either approach described above. However, the method is deprecated. - -.. versionchanged:: 3.10 - - Calling :meth:`~importlib.abc.Loader.module_repr` now occurs after trying to - use a module's ``__spec__`` attribute but before falling back on - ``__file__``. Use of :meth:`~importlib.abc.Loader.module_repr` is slated to - stop in Python 3.12. +.. versionchanged:: 3.12 + Use of :meth:`module_repr`, having been deprecated since Python 3.4, was + removed in Python 3.12 and is no longer called during the resolution of a + module's repr. .. _pyc-invalidation: diff --git a/Lib/importlib/_abc.py b/Lib/importlib/_abc.py index f80348fc7ffd..083205638965 100644 --- a/Lib/importlib/_abc.py +++ b/Lib/importlib/_abc.py @@ -38,17 +38,3 @@ def load_module(self, fullname): raise ImportError # Warning implemented in _load_module_shim(). return _bootstrap._load_module_shim(self, fullname) - - def module_repr(self, module): - """Return a module's repr. - - Used by the module type when the method does not raise - NotImplementedError. - - This method is deprecated. - - """ - warnings.warn("importlib.abc.Loader.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - # The exception will cause ModuleType.__repr__ to ignore this method. - raise NotImplementedError diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index afb95f4e1df8..67989c500f21 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -296,11 +296,6 @@ def _module_repr(module): loader = getattr(module, '__loader__', None) if spec := getattr(module, "__spec__", None): return _module_repr_from_spec(spec) - elif hasattr(loader, 'module_repr'): - try: - return loader.module_repr(module) - except Exception: - pass # Fall through to a catch-all which always succeeds. try: name = module.__name__ @@ -582,7 +577,6 @@ def module_from_spec(spec): def _module_repr_from_spec(spec): """Return the repr to use for the module.""" - # We mostly replicate _module_repr() using the spec attributes. name = '?' if spec.name is None else spec.name if spec.origin is None: if spec.loader is None: diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index b6c6716e9077..82d204257ed7 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1339,22 +1339,11 @@ def append(self, item): # This class is actually exposed publicly in a namespace package's __loader__ # attribute, so it should be available through a non-private name. -# https://bugs.python.org/issue35673 +# https://github.com/python/cpython/issues/92054 class NamespaceLoader: def __init__(self, name, path, path_finder): self._path = _NamespacePath(name, path, path_finder) - @staticmethod - def module_repr(module): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("NamespaceLoader.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return '<module {!r} (namespace)>'.format(module.__name__) - def is_package(self, fullname): return True diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py index f2df7e60bf8e..32f951cb1aca 100644 --- a/Lib/test/test_importlib/frozen/test_loader.py +++ b/Lib/test/test_importlib/frozen/test_loader.py @@ -103,14 +103,6 @@ def test_lacking_parent(self): expected=value)) self.assertEqual(output, 'Hello world!\n') - def test_module_repr(self): - name = '__hello__' - module, output = self.exec_module(name) - with deprecated(): - repr_str = self.machinery.FrozenImporter.module_repr(module) - self.assertEqual(repr_str, - "<module '__hello__' (frozen)>") - def test_module_repr_indirect(self): name = '__hello__' module, output = self.exec_module(name) diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index 378dcbe08a80..f35adec1a8e8 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -51,7 +51,6 @@ class Tester(self.abc.FileLoader): def get_code(self, _): pass def get_source(self, _): pass def is_package(self, _): pass - def module_repr(self, _): pass path = 'some_path' name = 'some_name' diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index d59b663a43ed..88bf100efaad 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -221,8 +221,6 @@ def test_module_repr(self): mod = types.ModuleType('blah') with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) - with self.assertRaises(NotImplementedError): - self.ins.module_repr(mod) original_repr = repr(mod) mod.__loader__ = self.ins # Should still return a proper repr. diff --git a/Lib/test/test_importlib/test_namespace_pkgs.py b/Lib/test/test_importlib/test_namespace_pkgs.py index cd08498545e8..f451f7547b35 100644 --- a/Lib/test/test_importlib/test_namespace_pkgs.py +++ b/Lib/test/test_importlib/test_namespace_pkgs.py @@ -79,13 +79,6 @@ def test_cant_import_other(self): with self.assertRaises(ImportError): import foo.two - def test_module_repr(self): - import foo.one - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - self.assertEqual(foo.__spec__.loader.module_repr(foo), - "<module 'foo' (namespace)>") - class DynamicPathNamespacePackage(NamespacePackageTest): paths = ['portion1'] diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py index 21e2c02094f2..f1ab16c7b2a9 100644 --- a/Lib/test/test_importlib/test_spec.py +++ b/Lib/test/test_importlib/test_spec.py @@ -407,101 +407,6 @@ def test_reload_legacy(self): machinery=machinery) -class ModuleReprTests: - - @property - def bootstrap(self): - return self.init._bootstrap - - def setUp(self): - self.module = type(os)('spam') - self.spec = self.machinery.ModuleSpec('spam', TestLoader()) - - def test_module___loader___module_repr(self): - class Loader: - def module_repr(self, module): - return '<delicious {}>'.format(module.__name__) - self.module.__loader__ = Loader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<delicious spam>') - - def test_module___loader___module_repr_bad(self): - class Loader(TestLoader): - def module_repr(self, module): - raise Exception - self.module.__loader__ = Loader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} (<TestLoader object>)>'.format('spam')) - - def test_module___spec__(self): - origin = 'in a hole, in the ground' - self.spec.origin = origin - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r} ({})>'.format('spam', origin)) - - def test_module___spec___location(self): - location = 'in_a_galaxy_far_far_away.py' - self.spec.origin = location - self.spec._set_fileattr = True - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} from {!r}>'.format('spam', location)) - - def test_module___spec___no_origin(self): - self.spec.loader = TestLoader() - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} (<TestLoader object>)>'.format('spam')) - - def test_module___spec___no_origin_no_loader(self): - self.spec.loader = None - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r}>'.format('spam')) - - def test_module_no_name(self): - del self.module.__name__ - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r}>'.format('?')) - - def test_module_with_file(self): - filename = 'e/i/e/i/o/spam.py' - self.module.__file__ = filename - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} from {!r}>'.format('spam', filename)) - - def test_module_no_file(self): - self.module.__loader__ = TestLoader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} (<TestLoader object>)>'.format('spam')) - - def test_module_no_file_no_loader(self): - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r}>'.format('spam')) - - -(Frozen_ModuleReprTests, - Source_ModuleReprTests - ) = test_util.test_both(ModuleReprTests, init=init, util=util, - machinery=machinery) - - class FactoryTests: def setUp(self): diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index f72177dda370..6c83d76c8e3c 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -8,10 +8,10 @@ import sys ModuleType = type(sys) + class FullLoader: - @classmethod - def module_repr(cls, m): - return "<module '{}' (crafted)>".format(m.__name__) + pass + class BareLoader: pass @@ -236,7 +236,7 @@ def test_module_repr_with_full_loader(self): # Yes, a class not an instance. m.__loader__ = FullLoader self.assertEqual( - repr(m), "<module 'foo' (crafted)>") + repr(m), "<module 'foo' (<class 'test.test_module.FullLoader'>)>") def test_module_repr_with_bare_loader_and_filename(self): # Because the loader has no module_repr(), use the file name. @@ -252,7 +252,7 @@ def test_module_repr_with_full_loader_and_filename(self): # Yes, a class not an instance. m.__loader__ = FullLoader m.__file__ = '/tmp/foo.py' - self.assertEqual(repr(m), "<module 'foo' (crafted)>") + self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>") def test_module_repr_builtin(self): self.assertEqual(repr(sys), "<module 'sys' (built-in)>") diff --git a/Misc/NEWS.d/next/Library/2022-07-06-14-57-33.gh-issue-94619.PRqKVX.rst b/Misc/NEWS.d/next/Library/2022-07-06-14-57-33.gh-issue-94619.PRqKVX.rst new file mode 100644 index 000000000000..a79050344246 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-06-14-57-33.gh-issue-94619.PRqKVX.rst @@ -0,0 +1 @@ +Remove the long-deprecated `module_repr()` from `importlib`. From webhook-mailer at python.org Thu Aug 4 21:27:04 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Fri, 05 Aug 2022 01:27:04 -0000 Subject: [Python-checkins] gh-94673: Add Per-Interpreter tp_subclasses for Static Builtin Types (gh-95301) Message-ID: <mailman.515.1659662825.3313.python-checkins@python.org> https://github.com/python/cpython/commit/87154d8dd890af0e847e91b06c71c741c08510d0 commit: 87154d8dd890af0e847e91b06c71c741c08510d0 branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-04T19:26:59-06:00 summary: gh-94673: Add Per-Interpreter tp_subclasses for Static Builtin Types (gh-95301) files: M Doc/c-api/typeobj.rst M Doc/whatsnew/3.12.rst M Include/cpython/object.h M Include/internal/pycore_object.h M Include/internal/pycore_typeobject.h M Lib/test/test_sys.py M Objects/structseq.c M Objects/typeobject.c diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 44884ac2890a..3af48f408ea3 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -135,7 +135,7 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | | + | [:c:member:`~PyTypeObject.tp_subclasses`] | void * | __subclasses__ | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -1934,9 +1934,17 @@ and :c:type:`PyType_Type` effectively act as defaults.) This field is not inherited. -.. c:member:: PyObject* PyTypeObject.tp_subclasses +.. c:member:: void* PyTypeObject.tp_subclasses - List of weak references to subclasses. Internal use only. + A collection of subclasses. Internal use only. May be an invalid pointer. + + To get a list of subclasses, call the Python method + :py:meth:`~class.__subclasses__`. + + .. versionchanged:: 3.12 + + For some types, this field does not hold a valid :c:expr:`PyObject*`. + The type was changed to :c:expr:`void*` to indicate this. **Inheritance:** diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 97a52e27fec1..9ea4d0369e61 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -440,6 +440,16 @@ Porting to Python 3.12 using the existing public C-API instead, or, if necessary, the (internal-only) ``_PyObject_GET_WEAKREFS_LISTPTR()`` macro. +* This internal-only :c:member:`PyTypeObject.tp_subclasses` may now not be + a valid object pointer. Its type was changed to :c:expr:`void *` to + reflect this. We mention this in case someone happens to be accessing the + internal-only field directly. + + To get a list of subclasses, call the Python method + :py:meth:`~class.__subclasses__` (using :c:func:`PyObject_CallMethod`, + for example). + + Deprecated ---------- diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 60c7c3e2aa6b..a26fc7f6aadf 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -217,8 +217,8 @@ struct _typeobject { inquiry tp_is_gc; /* For PyObject_IS_GC */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ - PyObject *tp_cache; - PyObject *tp_subclasses; + PyObject *tp_cache; /* no longer used */ + void *tp_subclasses; /* for static builtin types this is an index */ PyObject *tp_weaklist; /* not used for static builtin types */ destructor tp_del; @@ -227,7 +227,6 @@ struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; - size_t tp_static_builtin_index; /* 0 means "not initialized" */ }; /* This struct is used by the specializer diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index b3b0b8464808..5a328f04bae7 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -351,6 +351,7 @@ _PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values) extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); extern void _PyObject_FreeInstanceAttributes(PyObject *obj); extern int _PyObject_IsInstanceDictEmpty(PyObject *); +extern int _PyType_HasSubclasses(PyTypeObject *); extern PyObject* _PyType_GetSubclasses(PyTypeObject *); // Access macro to the members which are floating "behind" the object diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 4f9d6b1c4d4b..4eb0efcedb5e 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -45,6 +45,7 @@ struct type_cache { typedef struct { PyTypeObject *type; + PyObject *tp_subclasses; /* We never clean up weakrefs for static builtin types since they will effectively never get triggered. However, there are also some diagnostic uses for the list of weakrefs, diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index c4798afc9201..05fbcc19b6b7 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1507,7 +1507,7 @@ def delx(self): del self.__x check((1,2,3), vsize('') + 3*self.P) # type # static type: PyTypeObject - fmt = 'P2nPI13Pl4Pn9Pn12PIPI' + fmt = 'P2nPI13Pl4Pn9Pn12PIP' s = vsize('2P' + fmt) check(int, s) # class diff --git a/Objects/structseq.c b/Objects/structseq.c index 24cd0e705969..9a7013372e68 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -580,7 +580,7 @@ _PyStructSequence_FiniType(PyTypeObject *type) assert(type->tp_base == &PyTuple_Type); // Cannot delete a type if it still has subclasses - if (type->tp_subclasses != NULL) { + if (_PyType_HasSubclasses(type)) { return; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1f56a5866e3d..b2df9e7fad38 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -73,7 +73,7 @@ static inline PyTypeObject * subclass_from_ref(PyObject *ref); static inline int static_builtin_index_is_set(PyTypeObject *self) { - return self->tp_static_builtin_index > 0; + return self->tp_subclasses != NULL; } static inline size_t @@ -81,7 +81,7 @@ static_builtin_index_get(PyTypeObject *self) { assert(static_builtin_index_is_set(self)); /* We store a 1-based index so 0 can mean "not initialized". */ - return self->tp_static_builtin_index - 1; + return (size_t)self->tp_subclasses - 1; } static inline void @@ -89,13 +89,13 @@ static_builtin_index_set(PyTypeObject *self, size_t index) { assert(index < _Py_MAX_STATIC_BUILTIN_TYPES); /* We store a 1-based index so 0 can mean "not initialized". */ - self->tp_static_builtin_index = index + 1; + self->tp_subclasses = (PyObject *)(index + 1); } static inline void static_builtin_index_clear(PyTypeObject *self) { - self->tp_static_builtin_index = 0; + self->tp_subclasses = NULL; } static inline static_builtin_state * @@ -127,6 +127,7 @@ static_builtin_state_init(PyTypeObject *self) static_builtin_state *state = static_builtin_state_get(interp, self); state->type = self; + /* state->tp_subclasses is left NULL until init_subclasses() sets it. */ /* state->tp_weaklist is left NULL until insert_head() or insert_after() (in weakrefobject.c) sets it. */ } @@ -373,6 +374,8 @@ _PyTypes_Fini(PyInterpreterState *interp) } +static PyObject * lookup_subclasses(PyTypeObject *); + void PyType_Modified(PyTypeObject *type) { @@ -395,7 +398,7 @@ PyType_Modified(PyTypeObject *type) return; } - PyObject *subclasses = type->tp_subclasses; + PyObject *subclasses = lookup_subclasses(type); if (subclasses != NULL) { assert(PyDict_CheckExact(subclasses)); @@ -783,7 +786,7 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) Py_XDECREF(old_mro); // Avoid creating an empty list if there is no subclass - if (type->tp_subclasses != NULL) { + if (_PyType_HasSubclasses(type)) { /* Obtain a copy of subclasses list to iterate over. Otherwise type->tp_subclasses might be altered @@ -4345,10 +4348,13 @@ type_dealloc_common(PyTypeObject *type) } +static void clear_subclasses(PyTypeObject *self); + static void clear_static_tp_subclasses(PyTypeObject *type) { - if (type->tp_subclasses == NULL) { + PyObject *subclasses = lookup_subclasses(type); + if (subclasses == NULL) { return; } @@ -4372,9 +4378,19 @@ clear_static_tp_subclasses(PyTypeObject *type) going to leak. This mostly only affects embedding scenarios. */ - // For now we just clear tp_subclasses. + // For now we just do a sanity check and then clear tp_subclasses. + Py_ssize_t i = 0; + PyObject *key, *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + // All static builtin subtypes should have been finalized already. + assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + } - Py_CLEAR(type->tp_subclasses); + clear_subclasses(type); } void @@ -4424,7 +4440,7 @@ type_dealloc(PyTypeObject *type) Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_cache); - Py_XDECREF(type->tp_subclasses); + clear_subclasses(type); /* A type's tp_doc is heap allocated, unlike the tp_doc slots * of most other objects. It's okay to cast it to char *. @@ -4444,6 +4460,30 @@ type_dealloc(PyTypeObject *type) } +static PyObject * +lookup_subclasses(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState(self); + assert(state != NULL); + return state->tp_subclasses; + } + return (PyObject *)self->tp_subclasses; +} + +int +_PyType_HasSubclasses(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN && + _PyStaticType_GetState(self) == NULL) { + return 0; + } + if (lookup_subclasses(self) == NULL) { + return 0; + } + return 1; +} + PyObject* _PyType_GetSubclasses(PyTypeObject *self) { @@ -4452,7 +4492,7 @@ _PyType_GetSubclasses(PyTypeObject *self) return NULL; } - PyObject *subclasses = self->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_subclasses(self); // borrowed ref if (subclasses == NULL) { return list; } @@ -6830,6 +6870,36 @@ _PyStaticType_InitBuiltin(PyTypeObject *self) } +static PyObject * +init_subclasses(PyTypeObject *self) +{ + PyObject *subclasses = PyDict_New(); + if (subclasses == NULL) { + return NULL; + } + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState(self); + state->tp_subclasses = subclasses; + return subclasses; + } + self->tp_subclasses = (void *)subclasses; + return subclasses; +} + +static void +clear_subclasses(PyTypeObject *self) +{ + /* Delete the dictionary to save memory. _PyStaticType_Dealloc() + callers also test if tp_subclasses is NULL to check if a static type + has no subclass. */ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState(self); + Py_CLEAR(state->tp_subclasses); + return; + } + Py_CLEAR(self->tp_subclasses); +} + static int add_subclass(PyTypeObject *base, PyTypeObject *type) { @@ -6846,9 +6916,9 @@ add_subclass(PyTypeObject *base, PyTypeObject *type) // Only get tp_subclasses after creating the key and value. // PyWeakref_NewRef() can trigger a garbage collection which can execute // arbitrary Python code and so modify base->tp_subclasses. - PyObject *subclasses = base->tp_subclasses; + PyObject *subclasses = lookup_subclasses(base); if (subclasses == NULL) { - base->tp_subclasses = subclasses = PyDict_New(); + subclasses = init_subclasses(base); if (subclasses == NULL) { Py_DECREF(key); Py_DECREF(ref); @@ -6905,10 +6975,13 @@ get_subclasses_key(PyTypeObject *type, PyTypeObject *base) We fall back to manually traversing the values. */ Py_ssize_t i = 0; PyObject *ref; // borrowed ref - while (PyDict_Next((PyObject *)base->tp_subclasses, &i, &key, &ref)) { - PyTypeObject *subclass = subclass_from_ref(ref); // borrowed - if (subclass == type) { - return Py_NewRef(key); + PyObject *subclasses = lookup_subclasses(base); + if (subclasses != NULL) { + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == type) { + return Py_NewRef(key); + } } } /* It wasn't found. */ @@ -6918,7 +6991,7 @@ get_subclasses_key(PyTypeObject *type, PyTypeObject *base) static void remove_subclass(PyTypeObject *base, PyTypeObject *type) { - PyObject *subclasses = base->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_subclasses(base); // borrowed ref if (subclasses == NULL) { return; } @@ -6934,10 +7007,7 @@ remove_subclass(PyTypeObject *base, PyTypeObject *type) Py_XDECREF(key); if (PyDict_Size(subclasses) == 0) { - // Delete the dictionary to save memory. _PyStaticType_Dealloc() - // callers also test if tp_subclasses is NULL to check if a static type - // has no subclass. - Py_CLEAR(base->tp_subclasses); + clear_subclasses(base); } } @@ -9022,7 +9092,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, // It is safe to use a borrowed reference because update_subclasses() is // only used with update_slots_callback() which doesn't modify // tp_subclasses. - PyObject *subclasses = type->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_subclasses(type); // borrowed ref if (subclasses == NULL) { return 0; } From webhook-mailer at python.org Thu Aug 4 21:51:31 2022 From: webhook-mailer at python.org (terryjreedy) Date: Fri, 05 Aug 2022 01:51:31 -0000 Subject: [Python-checkins] gh-65802: IDLE - explain SaveAs and extensions (#95690) Message-ID: <mailman.516.1659664292.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9890f86ae2001d19e7a18fee5b13aa0dd6069aef commit: 9890f86ae2001d19e7a18fee5b13aa0dd6069aef branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-04T21:51:14-04:00 summary: gh-65802: IDLE - explain SaveAs and extensions (#95690) File name extensions may or may not be shown for the current name and are added in an OS-dependent manner if not given for the new name. files: A Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index e91ec40c9add..2d52e5355749 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -87,11 +87,14 @@ Save Save As... Save the current window with a Save As dialog. The file saved becomes the - new associated file for the window. + new associated file for the window. (If your file namager is set to hide + extensions, the current extension will be omitted in the file name box. + If the new filename has no '.', '.py' and .'txt' will be added for Python + and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... Save the current window to different file without changing the associated - file. + file. (See Save As note above about filename extensions.) Print Window Print the current window to the default printer. diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index ce95e2f9948b..7fa7facf8cf7 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,8 @@ Released on 2022-10-03 ========================= +gh-65802: Document handling of extensions in Save As dialogs. + gh-95191: Include prompts when saving Shell (interactive input/output). gh-95511: Fix the Shell context menu copy-with-prompts bug of copying diff --git a/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst new file mode 100644 index 000000000000..a62a784b6e69 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst @@ -0,0 +1 @@ +Document handling of extensions in Save As dialogs. From webhook-mailer at python.org Fri Aug 5 00:41:22 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 05 Aug 2022 04:41:22 -0000 Subject: [Python-checkins] [3.10] Docs: sqlite3 docs fixup (GH-95681) (#95684) Message-ID: <mailman.517.1659674483.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c57666586bc831951affcaab43ba31f49279d0c9 commit: c57666586bc831951affcaab43ba31f49279d0c9 branch: 3.10 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-05T06:41:09+02:00 summary: [3.10] Docs: sqlite3 docs fixup (GH-95681) (#95684) - Disable links to the module itself - Consistent ref markup (cherry picked from commit 44f1f63ad5cf00b6f50cef0cc1a62c42632138be) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 990071419c67..88cd5527b492 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -146,12 +146,12 @@ Module functions and constants .. data:: paramstyle String constant stating the type of parameter marker formatting expected by - the :mod:`sqlite3` module. Required by the DB-API. Hard-coded to + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to ``"qmark"``. .. note:: - The :mod:`sqlite3` module supports both ``qmark`` and ``numeric`` DB-API + The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API parameter styles, because that is what the underlying SQLite library supports. However, the DB-API does not allow multiple values for the ``paramstyle`` attribute. @@ -182,7 +182,7 @@ Module functions and constants .. data:: threadsafety Integer constant required by the DB-API, stating the level of thread safety - the :mod:`sqlite3` module supports. Currently hard-coded to ``1``, meaning + the :mod:`!sqlite3` module supports. Currently hard-coded to ``1``, meaning *"Threads may share the module, but not connections."* However, this may not always be true. You can check the underlying SQLite library's compile-time threaded mode using the following query:: @@ -205,7 +205,7 @@ Module functions and constants :func:`connect` to look up a converter function using the declared types for each column. The types are declared when the database table is created. - ``sqlite3`` will look up a converter function using the first word of the + :mod:`!sqlite3` will look up a converter function using the first word of the declared type as the converter dictionary key. For example: @@ -289,7 +289,7 @@ Module functions and constants if not the default :class:`Connection` class. :param int cached_statements: - The number of statements that ``sqlite3`` + The number of statements that :mod:`!sqlite3` should internally cache for this connection, to avoid parsing overhead. By default, 100 statements. @@ -337,7 +337,7 @@ Module functions and constants SQLite type. The adapter is called with a Python object of type *type* as its sole argument, and must return a value of a - :ref:`type that SQLite natively understands<sqlite3-types>`. + :ref:`type that SQLite natively understands <sqlite3-types>`. .. function:: complete_statement(statement) @@ -385,7 +385,7 @@ Connection objects .. attribute:: isolation_level This attribute controls the :ref:`transaction handling - <sqlite3-controlling-transactions>` performed by ``sqlite3``. + <sqlite3-controlling-transactions>` performed by :mod:`!sqlite3`. If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, @@ -541,7 +541,7 @@ Connection objects :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL statement should be aborted with an error and :const:`SQLITE_IGNORE` if the column should be treated as a NULL value. These constants are available in the - :mod:`sqlite3` module. + :mod:`!sqlite3` module. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or ``None`` @@ -552,7 +552,7 @@ Connection objects Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first - one. All necessary constants are available in the :mod:`sqlite3` module. + one. All necessary constants are available in the :mod:`!sqlite3` module. .. method:: set_progress_handler(progress_handler, n) @@ -605,7 +605,7 @@ Connection objects .. note:: - The ``sqlite3`` module is not built with loadable extension support by + The :mod:`!sqlite3` module is not built with loadable extension support by default, because some platforms (notably macOS) have SQLite libraries which are compiled without this feature. To get loadable extension support, @@ -875,11 +875,11 @@ Cursor objects .. method:: setinputsizes(sizes, /) - Required by the DB-API. Does nothing in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. method:: setoutputsize(size, column=None, /) - Required by the DB-API. Does nothing in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. attribute:: rowcount @@ -1013,7 +1013,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: Warning - This exception is raised by ``sqlite3`` if an SQL query is not a + This exception is raised by :mod:`!sqlite3` if an SQL query is not a :class:`string <str>`, or if multiple statements are passed to :meth:`~Cursor.execute` or :meth:`~Cursor.executemany`. ``Warning`` is a subclass of :exc:`Exception`. @@ -1026,8 +1026,8 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: InterfaceError - This exception is raised by ``sqlite3`` for fetch across rollback, - or if ``sqlite3`` is unable to bind parameters. + This exception is raised by :mod:`!sqlite3` for fetch across rollback, + or if :mod:`!sqlite3` is unable to bind parameters. ``InterfaceError`` is a subclass of :exc:`Error`. .. exception:: DatabaseError @@ -1065,7 +1065,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: ProgrammingError - Exception raised for ``sqlite3`` API programming errors, + Exception raised for :mod:`!sqlite3` API programming errors, for example trying to operate on a closed :class:`Connection`, or trying to execute non-DML statements with :meth:`~Cursor.executemany`. ``ProgrammingError`` is a subclass of :exc:`DatabaseError`. @@ -1121,10 +1121,10 @@ This is how SQLite types are converted to Python types by default: | ``BLOB`` | :class:`bytes` | +-------------+----------------------------------------------+ -The type system of the :mod:`sqlite3` module is extensible in two ways: you can +The type system of the :mod:`!sqlite3` module is extensible in two ways: you can store additional Python types in an SQLite database via :ref:`object adapters <sqlite3-adapters>`, -and you can let the ``sqlite3`` module convert SQLite types to +and you can let the :mod:`!sqlite3` module convert SQLite types to Python types via :ref:`converters <sqlite3-converters>`. @@ -1170,7 +1170,7 @@ Using adapters to store custom Python types in SQLite databases SQLite supports only a limited set of data types natively. To store custom Python types in SQLite databases, *adapt* them to one of the -:ref:`Python types SQLite natively understands<sqlite3-types>`. +:ref:`Python types SQLite natively understands <sqlite3-types>`. There are two ways to adapt Python objects to SQLite types: letting your object adapt itself, or using an *adapter callable*. @@ -1234,7 +1234,7 @@ and constructs a :class:`Point` object from it. x, y = map(float, s.split(b";")) return Point(x, y) -We now need to tell ``sqlite3`` when it should convert a given SQLite value. +We now need to tell :mod:`!sqlite3` when it should convert a given SQLite value. This is done when connecting to a database, using the *detect_types* parameter of :func:`connect`. There are three options: @@ -1346,7 +1346,7 @@ directly using only a single call on the :class:`Connection` object. Accessing columns by name instead of by index ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -One useful feature of the :mod:`sqlite3` module is the built-in +One useful feature of the :mod:`!sqlite3` module is the built-in :class:`sqlite3.Row` class designed to be used as a row factory. Rows wrapped with this class can be accessed both by index (like tuples) and @@ -1421,7 +1421,7 @@ Explanation Transaction control ^^^^^^^^^^^^^^^^^^^ -The ``sqlite3`` module does not adhere to the transaction handling recommended +The :mod:`!sqlite3` module does not adhere to the transaction handling recommended by :pep:`249`. If the connection attribute :attr:`~Connection.isolation_level` @@ -1432,7 +1432,7 @@ new transactions are implicitly opened before Use the :meth:`~Connection.commit` and :meth:`~Connection.rollback` methods to respectively commit and roll back pending transactions. You can choose the underlying `SQLite transaction behaviour`_ ? -that is, whether and what type of ``BEGIN`` statements ``sqlite3`` +that is, whether and what type of ``BEGIN`` statements :mod:`!sqlite3` implicitly executes ? via the :attr:`~Connection.isolation_level` attribute. @@ -1449,7 +1449,7 @@ any pending transaction before execution of the given SQL script, regardless of the value of :attr:`~Connection.isolation_level`. .. versionchanged:: 3.6 - :mod:`sqlite3` used to implicitly commit an open transaction before DDL + :mod:`!sqlite3` used to implicitly commit an open transaction before DDL statements. This is no longer the case. .. _autocommit mode: From webhook-mailer at python.org Fri Aug 5 01:45:10 2022 From: webhook-mailer at python.org (brandtbucher) Date: Fri, 05 Aug 2022 05:45:10 -0000 Subject: [Python-checkins] GH-90997: Document CACHEs (GH-95694) Message-ID: <mailman.518.1659678311.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5f3c9fda1825737fa7b671b995f84a8ab9a4adb8 commit: 5f3c9fda1825737fa7b671b995f84a8ab9a4adb8 branch: main author: Brandt Bucher <brandtbucher at gmail.com> committer: brandtbucher <brandtbucher at gmail.com> date: 2022-08-04T22:45:05-07:00 summary: GH-90997: Document CACHEs (GH-95694) files: M Doc/library/dis.rst M Doc/whatsnew/3.11.rst diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 68c3d1c0a4b2..63b064e7b444 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -408,6 +408,24 @@ The Python compiler currently generates the following bytecode instructions. .. versionadded:: 3.11 +.. opcode:: CACHE + + Rather than being an actual instruction, this opcode is used to mark extra + space for the interpreter to cache useful data directly in the bytecode + itself. It is automatically hidden by all ``dis`` utilities, but can be + viewed with ``show_caches=True``. + + Logically, this space is part of the preceding instruction. Many opcodes + expect to be followed by an exact number of caches, and will instruct the + interpreter to skip over them at runtime. + + Populated caches can look like arbitrary instructions, so great care should + be taken when reading or modifying raw, adaptive bytecode containing + quickened data. + + .. versionadded:: 3.11 + + **Unary operations** Unary operations take the top of the stack, apply the operation, and push the diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index c976eddb08ba..f5d5d5f2be06 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1165,6 +1165,13 @@ contributors are volunteers from the community. CPython bytecode changes ======================== +* The bytecode now contains inline cache entries, which take the form of + :opcode:`CACHE` instructions. Many opcodes expect to be followed by an exact + number of caches, and instruct the interpreter to skip over them at runtime. + Populated caches can look like arbitrary instructions, so great care should be + taken when reading or modifying raw, adaptive bytecode containing quickened + data. + * Replaced all numeric ``BINARY_*`` and ``INPLACE_*`` instructions with a single :opcode:`BINARY_OP` implementation. From webhook-mailer at python.org Fri Aug 5 02:26:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 05 Aug 2022 06:26:31 -0000 Subject: [Python-checkins] gh-65802: IDLE - explain SaveAs and extensions (GH-95690) Message-ID: <mailman.519.1659680792.3313.python-checkins@python.org> https://github.com/python/cpython/commit/235159331927f8b3ff88cb67f4ca51b28f25a427 commit: 235159331927f8b3ff88cb67f4ca51b28f25a427 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-04T23:26:26-07:00 summary: gh-65802: IDLE - explain SaveAs and extensions (GH-95690) File name extensions may or may not be shown for the current name and are added in an OS-dependent manner if not given for the new name. (cherry picked from commit 9890f86ae2001d19e7a18fee5b13aa0dd6069aef) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: A Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index e91ec40c9add..2d52e5355749 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -87,11 +87,14 @@ Save Save As... Save the current window with a Save As dialog. The file saved becomes the - new associated file for the window. + new associated file for the window. (If your file namager is set to hide + extensions, the current extension will be omitted in the file name box. + If the new filename has no '.', '.py' and .'txt' will be added for Python + and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... Save the current window to different file without changing the associated - file. + file. (See Save As note above about filename extensions.) Print Window Print the current window to the default printer. diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 999b67181319..277fd9429a4c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,8 @@ Released 2023-04-03? ========================= +gh-65802: Document handling of extensions in Save As dialogs. + gh-95191: Include prompts when saving Shell (interactive input/output). gh-95511: Fix the Shell context menu copy-with-prompts bug of copying diff --git a/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst new file mode 100644 index 000000000000..a62a784b6e69 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst @@ -0,0 +1 @@ +Document handling of extensions in Save As dialogs. From webhook-mailer at python.org Fri Aug 5 03:34:01 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:34:01 -0000 Subject: [Python-checkins] gh-95573: Fix a mistake in asyncio ssl tests suppressing all logs (#95687) Message-ID: <mailman.520.1659684842.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e1d68b3ce71de76b3d7e5852e9bdfdbb4efea2f8 commit: e1d68b3ce71de76b3d7e5852e9bdfdbb4efea2f8 branch: main author: Fantix King <fantix.king at gmail.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:33:35+02:00 summary: gh-95573: Fix a mistake in asyncio ssl tests suppressing all logs (#95687) files: M Lib/test/test_asyncio/test_ssl.py diff --git a/Lib/test/test_asyncio/test_ssl.py b/Lib/test/test_asyncio/test_ssl.py index 5e3c1573c9c5..a2b5f8d258cd 100644 --- a/Lib/test/test_asyncio/test_ssl.py +++ b/Lib/test/test_asyncio/test_ssl.py @@ -58,6 +58,16 @@ def connection_lost(self, exc): self.done.set_result(None) +class MessageOutFilter(logging.Filter): + def __init__(self, msg): + self.msg = msg + + def filter(self, record): + if self.msg in record.msg: + return False + return True + + @unittest.skipIf(ssl is None, 'No ssl module') class TestSSL(test_utils.TestCase): @@ -149,7 +159,7 @@ def _create_client_ssl_context(self, *, disable_verify=True): def _silence_eof_received_warning(self): # TODO This warning has to be fixed in asyncio. logger = logging.getLogger('asyncio') - filter = logging.Filter('has no effect when using ssl') + filter = MessageOutFilter('has no effect when using ssl') logger.addFilter(filter) try: yield From webhook-mailer at python.org Fri Aug 5 03:41:06 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:41:06 -0000 Subject: [Python-checkins] GH-95685: Fix rendering of the string documentation (#95686) Message-ID: <mailman.521.1659685267.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a525f2ada407d6677bf8ca708f104694de0525e4 commit: a525f2ada407d6677bf8ca708f104694de0525e4 branch: main author: Mariatta Wijaya <Mariatta at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:41:02+02:00 summary: GH-95685: Fix rendering of the string documentation (#95686) There's an extra underlines that messed the rest of the documentation rendering. Closes #95685 files: M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 7d0d601799f..3b96813e683 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -8,6 +8,7 @@ -------------- + .. seealso:: :ref:`textseq` From webhook-mailer at python.org Fri Aug 5 03:41:58 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:41:58 -0000 Subject: [Python-checkins] [3.11] Docs: sqlite3 docs fixup (GH-95681) (GH-95683) Message-ID: <mailman.522.1659685320.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7dc0dafdf00be5c2e2ffcec1368df8d6e143d5c8 commit: 7dc0dafdf00be5c2e2ffcec1368df8d6e143d5c8 branch: 3.11 author: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:41:54+02:00 summary: [3.11] Docs: sqlite3 docs fixup (GH-95681) (GH-95683) - Disable links to the module itself - Fix link indent - Consistent ref markup. (cherry picked from commit 44f1f63ad5cf00b6f50cef0cc1a62c42632138be) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index f902a991232..b5af3091f73 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -146,12 +146,12 @@ Module functions and constants .. data:: paramstyle String constant stating the type of parameter marker formatting expected by - the :mod:`sqlite3` module. Required by the DB-API. Hard-coded to + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to ``"qmark"``. .. note:: - The :mod:`sqlite3` module supports both ``qmark`` and ``numeric`` DB-API + The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API parameter styles, because that is what the underlying SQLite library supports. However, the DB-API does not allow multiple values for the ``paramstyle`` attribute. @@ -182,7 +182,7 @@ Module functions and constants .. data:: threadsafety Integer constant required by the DB-API 2.0, stating the level of thread - safety the :mod:`sqlite3` module supports. This attribute is set based on + safety the :mod:`!sqlite3` module supports. This attribute is set based on the default `threading mode <https://sqlite.org/threadsafe.html>`_ the underlying SQLite library is compiled with. The SQLite threading modes are: @@ -223,7 +223,7 @@ Module functions and constants :func:`connect` to look up a converter function using the declared types for each column. The types are declared when the database table is created. - ``sqlite3`` will look up a converter function using the first word of the + :mod:`!sqlite3` will look up a converter function using the first word of the declared type as the converter dictionary key. For example: @@ -307,7 +307,7 @@ Module functions and constants if not the default :class:`Connection` class. :param int cached_statements: - The number of statements that ``sqlite3`` + The number of statements that :mod:`!sqlite3` should internally cache for this connection, to avoid parsing overhead. By default, 128 statements. @@ -355,7 +355,7 @@ Module functions and constants SQLite type. The adapter is called with a Python object of type *type* as its sole argument, and must return a value of a - :ref:`type that SQLite natively understands<sqlite3-types>`. + :ref:`type that SQLite natively understands <sqlite3-types>`. .. function:: complete_statement(statement) @@ -421,7 +421,7 @@ Connection objects .. attribute:: isolation_level This attribute controls the :ref:`transaction handling - <sqlite3-controlling-transactions>` performed by ``sqlite3``. + <sqlite3-controlling-transactions>` performed by :mod:`!sqlite3`. If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, @@ -654,7 +654,7 @@ Connection objects :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL statement should be aborted with an error and :const:`SQLITE_IGNORE` if the column should be treated as a NULL value. These constants are available in the - :mod:`sqlite3` module. + :mod:`!sqlite3` module. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or ``None`` @@ -665,7 +665,7 @@ Connection objects Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first - one. All necessary constants are available in the :mod:`sqlite3` module. + one. All necessary constants are available in the :mod:`!sqlite3` module. Passing ``None`` as *authorizer_callback* will disable the authorizer. @@ -723,7 +723,7 @@ Connection objects .. note:: - The ``sqlite3`` module is not built with loadable extension support by + The :mod:`!sqlite3` module is not built with loadable extension support by default, because some platforms (notably macOS) have SQLite libraries which are compiled without this feature. To get loadable extension support, @@ -918,7 +918,7 @@ Connection objects .. versionadded:: 3.11 -.. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html + .. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html .. method:: serialize(*, name="main") @@ -1099,11 +1099,11 @@ Cursor objects .. method:: setinputsizes(sizes, /) - Required by the DB-API. Does nothing in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. method:: setoutputsize(size, column=None, /) - Required by the DB-API. Does nothing in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. attribute:: rowcount @@ -1291,8 +1291,8 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: Warning - This exception is not currently raised by the ``sqlite3`` module, - but may be raised by applications using ``sqlite3``, + This exception is not currently raised by the :mod:`!sqlite3` module, + but may be raised by applications using :mod:`!sqlite3`, for example if a user-defined function truncates data while inserting. ``Warning`` is a subclass of :exc:`Exception`. @@ -1323,7 +1323,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). Exception raised for misuse of the low-level SQLite C API. In other words, if this exception is raised, it probably indicates a bug in the - ``sqlite3`` module. + :mod:`!sqlite3` module. ``InterfaceError`` is a subclass of :exc:`Error`. .. exception:: DatabaseError @@ -1361,7 +1361,7 @@ The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: ProgrammingError - Exception raised for ``sqlite3`` API programming errors, + Exception raised for :mod:`!sqlite3` API programming errors, for example supplying the wrong number of bindings to a query, or trying to operate on a closed :class:`Connection`. ``ProgrammingError`` is a subclass of :exc:`DatabaseError`. @@ -1417,10 +1417,10 @@ This is how SQLite types are converted to Python types by default: | ``BLOB`` | :class:`bytes` | +-------------+----------------------------------------------+ -The type system of the :mod:`sqlite3` module is extensible in two ways: you can +The type system of the :mod:`!sqlite3` module is extensible in two ways: you can store additional Python types in an SQLite database via :ref:`object adapters <sqlite3-adapters>`, -and you can let the ``sqlite3`` module convert SQLite types to +and you can let the :mod:`!sqlite3` module convert SQLite types to Python types via :ref:`converters <sqlite3-converters>`. @@ -1466,7 +1466,7 @@ Using adapters to store custom Python types in SQLite databases SQLite supports only a limited set of data types natively. To store custom Python types in SQLite databases, *adapt* them to one of the -:ref:`Python types SQLite natively understands<sqlite3-types>`. +:ref:`Python types SQLite natively understands <sqlite3-types>`. There are two ways to adapt Python objects to SQLite types: letting your object adapt itself, or using an *adapter callable*. @@ -1530,7 +1530,7 @@ and constructs a :class:`Point` object from it. x, y = map(float, s.split(b";")) return Point(x, y) -We now need to tell ``sqlite3`` when it should convert a given SQLite value. +We now need to tell :mod:`!sqlite3` when it should convert a given SQLite value. This is done when connecting to a database, using the *detect_types* parameter of :func:`connect`. There are three options: @@ -1642,7 +1642,7 @@ directly using only a single call on the :class:`Connection` object. Accessing columns by name instead of by index ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -One useful feature of the :mod:`sqlite3` module is the built-in +One useful feature of the :mod:`!sqlite3` module is the built-in :class:`sqlite3.Row` class designed to be used as a row factory. Rows wrapped with this class can be accessed both by index (like tuples) and @@ -1717,7 +1717,7 @@ Explanation Transaction control ^^^^^^^^^^^^^^^^^^^ -The ``sqlite3`` module does not adhere to the transaction handling recommended +The :mod:`!sqlite3` module does not adhere to the transaction handling recommended by :pep:`249`. If the connection attribute :attr:`~Connection.isolation_level` @@ -1728,7 +1728,7 @@ new transactions are implicitly opened before Use the :meth:`~Connection.commit` and :meth:`~Connection.rollback` methods to respectively commit and roll back pending transactions. You can choose the underlying `SQLite transaction behaviour`_ ? -that is, whether and what type of ``BEGIN`` statements ``sqlite3`` +that is, whether and what type of ``BEGIN`` statements :mod:`!sqlite3` implicitly executes ? via the :attr:`~Connection.isolation_level` attribute. @@ -1745,7 +1745,7 @@ any pending transaction before execution of the given SQL script, regardless of the value of :attr:`~Connection.isolation_level`. .. versionchanged:: 3.6 - :mod:`sqlite3` used to implicitly commit an open transaction before DDL + :mod:`!sqlite3` used to implicitly commit an open transaction before DDL statements. This is no longer the case. .. _autocommit mode: From webhook-mailer at python.org Fri Aug 5 03:42:26 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:42:26 -0000 Subject: [Python-checkins] gh-65802: IDLE - explain SaveAs and extensions (GH-95690) (GH-95692) Message-ID: <mailman.523.1659685347.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4512a160d045695ee0349fd91af7aaaa6fb71410 commit: 4512a160d045695ee0349fd91af7aaaa6fb71410 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:42:21+02:00 summary: gh-65802: IDLE - explain SaveAs and extensions (GH-95690) (GH-95692) File name extensions may or may not be shown for the current name and are added in an OS-dependent manner if not given for the new name. (cherry picked from commit 9890f86ae2001d19e7a18fee5b13aa0dd6069aef) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: A Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index e91ec40c9add..2d52e5355749 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -87,11 +87,14 @@ Save Save As... Save the current window with a Save As dialog. The file saved becomes the - new associated file for the window. + new associated file for the window. (If your file namager is set to hide + extensions, the current extension will be omitted in the file name box. + If the new filename has no '.', '.py' and .'txt' will be added for Python + and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... Save the current window to different file without changing the associated - file. + file. (See Save As note above about filename extensions.) Print Window Print the current window to the default printer. diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index ce95e2f9948b..7fa7facf8cf7 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,8 @@ Released on 2022-10-03 ========================= +gh-65802: Document handling of extensions in Save As dialogs. + gh-95191: Include prompts when saving Shell (interactive input/output). gh-95511: Fix the Shell context menu copy-with-prompts bug of copying diff --git a/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst new file mode 100644 index 000000000000..a62a784b6e69 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst @@ -0,0 +1 @@ +Document handling of extensions in Save As dialogs. From webhook-mailer at python.org Fri Aug 5 03:42:54 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:42:54 -0000 Subject: [Python-checkins] GH-90997: Document CACHEs (GH-95694) (GH-95696) Message-ID: <mailman.524.1659685374.3313.python-checkins@python.org> https://github.com/python/cpython/commit/07d97c9e5d674d5d309e789014dbe59cabf7a7dd commit: 07d97c9e5d674d5d309e789014dbe59cabf7a7dd branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:42:49+02:00 summary: GH-90997: Document CACHEs (GH-95694) (GH-95696) (cherry picked from commit 5f3c9fda1825737fa7b671b995f84a8ab9a4adb8) Co-authored-by: Brandt Bucher <brandtbucher at gmail.com> files: M Doc/library/dis.rst M Doc/whatsnew/3.11.rst diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index c303ab9a1ff8..f7989ea43dac 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -410,6 +410,24 @@ The Python compiler currently generates the following bytecode instructions. .. versionadded:: 3.11 +.. opcode:: CACHE + + Rather than being an actual instruction, this opcode is used to mark extra + space for the interpreter to cache useful data directly in the bytecode + itself. It is automatically hidden by all ``dis`` utilities, but can be + viewed with ``show_caches=True``. + + Logically, this space is part of the preceding instruction. Many opcodes + expect to be followed by an exact number of caches, and will instruct the + interpreter to skip over them at runtime. + + Populated caches can look like arbitrary instructions, so great care should + be taken when reading or modifying raw, adaptive bytecode containing + quickened data. + + .. versionadded:: 3.11 + + **Unary operations** Unary operations take the top of the stack, apply the operation, and push the diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index c57f8a0f3e9f..0ba88532442d 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1165,6 +1165,13 @@ contributors are volunteers from the community. CPython bytecode changes ======================== +* The bytecode now contains inline cache entries, which take the form of + :opcode:`CACHE` instructions. Many opcodes expect to be followed by an exact + number of caches, and instruct the interpreter to skip over them at runtime. + Populated caches can look like arbitrary instructions, so great care should be + taken when reading or modifying raw, adaptive bytecode containing quickened + data. + * Replaced all numeric ``BINARY_*`` and ``INPLACE_*`` instructions with a single :opcode:`BINARY_OP` implementation. From webhook-mailer at python.org Fri Aug 5 03:58:22 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:58:22 -0000 Subject: [Python-checkins] GH-95685: Fix rendering of the string documentation (GH-95686) (GH-95701) Message-ID: <mailman.525.1659686303.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9e859e125837e3a128b59b3a97a9523b83fa397b commit: 9e859e125837e3a128b59b3a97a9523b83fa397b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:58:17+02:00 summary: GH-95685: Fix rendering of the string documentation (GH-95686) (GH-95701) There's an extra underlines that messed the rest of the documentation rendering. Closes #95685 (cherry picked from commit a525f2ada407d6677bf8ca708f104694de0525e4) Co-authored-by: Mariatta Wijaya <Mariatta at users.noreply.github.com> files: M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index ccdda4a097d..e661faf5d33 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -8,6 +8,7 @@ -------------- + .. seealso:: :ref:`textseq` From webhook-mailer at python.org Fri Aug 5 03:58:44 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 07:58:44 -0000 Subject: [Python-checkins] GH-95685: Fix rendering of the string documentation (GH-95686) (GH-95700) Message-ID: <mailman.526.1659686325.3313.python-checkins@python.org> https://github.com/python/cpython/commit/82328126b4f8d092129d0608c9f488d0990f75fd commit: 82328126b4f8d092129d0608c9f488d0990f75fd branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T09:58:40+02:00 summary: GH-95685: Fix rendering of the string documentation (GH-95686) (GH-95700) There's an extra underlines that messed the rest of the documentation rendering. Closes #95685 (cherry picked from commit a525f2ada407d6677bf8ca708f104694de0525e4) Co-authored-by: Mariatta Wijaya <Mariatta at users.noreply.github.com> files: M Doc/library/string.rst diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 7d0d601799f..3b96813e683 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -8,6 +8,7 @@ -------------- + .. seealso:: :ref:`textseq` From webhook-mailer at python.org Fri Aug 5 04:07:29 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 08:07:29 -0000 Subject: [Python-checkins] gh-95573: Fix a mistake in asyncio ssl tests suppressing all logs (GH-95687) (GH-95699) Message-ID: <mailman.527.1659686851.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0e636e4e7b6bfb4c6e9b8e4b529a10302c59f62b commit: 0e636e4e7b6bfb4c6e9b8e4b529a10302c59f62b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T10:07:15+02:00 summary: gh-95573: Fix a mistake in asyncio ssl tests suppressing all logs (GH-95687) (GH-95699) (cherry picked from commit e1d68b3ce71de76b3d7e5852e9bdfdbb4efea2f8) Co-authored-by: Fantix King <fantix.king at gmail.com> files: M Lib/test/test_asyncio/test_ssl.py diff --git a/Lib/test/test_asyncio/test_ssl.py b/Lib/test/test_asyncio/test_ssl.py index 5e3c1573c9c5..a2b5f8d258cd 100644 --- a/Lib/test/test_asyncio/test_ssl.py +++ b/Lib/test/test_asyncio/test_ssl.py @@ -58,6 +58,16 @@ def connection_lost(self, exc): self.done.set_result(None) +class MessageOutFilter(logging.Filter): + def __init__(self, msg): + self.msg = msg + + def filter(self, record): + if self.msg in record.msg: + return False + return True + + @unittest.skipIf(ssl is None, 'No ssl module') class TestSSL(test_utils.TestCase): @@ -149,7 +159,7 @@ def _create_client_ssl_context(self, *, disable_verify=True): def _silence_eof_received_warning(self): # TODO This warning has to be fixed in asyncio. logger = logging.getLogger('asyncio') - filter = logging.Filter('has no effect when using ssl') + filter = MessageOutFilter('has no effect when using ssl') logger.addFilter(filter) try: yield From webhook-mailer at python.org Fri Aug 5 04:18:53 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 08:18:53 -0000 Subject: [Python-checkins] [3.11] Clarifying the documentation on library/syslog (GH-92587) (GH-95492) Message-ID: <mailman.528.1659687534.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6a36b8e58697a980f2d77f67ca00b06c82c3d6a8 commit: 6a36b8e58697a980f2d77f67ca00b06c82c3d6a8 branch: 3.11 author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T10:18:44+02:00 summary: [3.11] Clarifying the documentation on library/syslog (GH-92587) (GH-95492) (cherry picked from commit b7ce4625fe2a8a4d6c1db6b39b52c7f97d384caa) Co-authored-by: Nicolas Haller <nicolas at haller.im> files: M Doc/library/syslog.rst diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 16093d5aac7..766ff57cc66 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -31,10 +31,15 @@ The module defines the following functions: value given in the :func:`openlog` call is used. If :func:`openlog` has not been called prior to the call to :func:`syslog`, - ``openlog()`` will be called with no arguments. + :func:`openlog` will be called with no arguments. .. audit-event:: syslog.syslog priority,message syslog.syslog + .. versionchanged:: 3.2 + In previous versions, :func:`openlog` would not be called automatically if + it wasn't called prior to the call to :func:`syslog`, deferring to the syslog + implementation to call ``openlog()``. + .. function:: openlog([ident[, logoption[, facility]]]) @@ -53,8 +58,7 @@ The module defines the following functions: .. versionchanged:: 3.2 In previous versions, keyword arguments were not allowed, and *ident* was - required. The default for *ident* was dependent on the system libraries, - and often was ``python`` instead of the name of the Python program file. + required. .. function:: closelog() From webhook-mailer at python.org Fri Aug 5 04:20:34 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 08:20:34 -0000 Subject: [Python-checkins] bpo-42037: Corrected request dependencies in CookieJar functions (GH-23112) (GH-95515) Message-ID: <mailman.529.1659687635.3313.python-checkins@python.org> https://github.com/python/cpython/commit/57446f9e3321aedad8c1f7398f8b64d7ec54f2e7 commit: 57446f9e3321aedad8c1f7398f8b64d7ec54f2e7 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T10:20:29+02:00 summary: bpo-42037: Corrected request dependencies in CookieJar functions (GH-23112) (GH-95515) (cherry picked from commit d29e279de38e7bc3b7deda573ba23d65831d9351) Co-authored-by: markus-sus <73822103+markus-sus at users.noreply.github.com> files: M Doc/library/http.cookiejar.rst diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 3d59665be4f..ba2fa018499 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -160,11 +160,10 @@ contained :class:`Cookie` objects. respectively), the :mailheader:`Cookie2` header is also added when appropriate. The *request* object (usually a :class:`urllib.request.Request` instance) - must support the methods :meth:`get_full_url`, :meth:`get_host`, - :meth:`get_type`, :meth:`unverifiable`, :meth:`has_header`, + must support the methods :meth:`get_full_url`, :meth:`has_header`, :meth:`get_header`, :meth:`header_items`, :meth:`add_unredirected_header` - and :attr:`origin_req_host` attribute as documented by - :mod:`urllib.request`. + and the attributes :attr:`host`, :attr:`!type`, :attr:`unverifiable` + and :attr:`origin_req_host` as documented by :mod:`urllib.request`. .. versionchanged:: 3.3 @@ -186,11 +185,11 @@ contained :class:`Cookie` objects. method, which returns an :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) - must support the methods :meth:`get_full_url`, :meth:`get_host`, - :meth:`unverifiable`, and :attr:`origin_req_host` attribute, as documented - by :mod:`urllib.request`. The request is used to set default values for - cookie-attributes as well as for checking that the cookie is allowed to be - set. + must support the method :meth:`get_full_url` and the attributes + :attr:`host`, :attr:`unverifiable` and :attr:`origin_req_host`, + as documented by :mod:`urllib.request`. The request is used to set + default values for cookie-attributes as well as for checking that the + cookie is allowed to be set. .. versionchanged:: 3.3 From webhook-mailer at python.org Fri Aug 5 04:46:04 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 08:46:04 -0000 Subject: [Python-checkins] gh-95573: Reduce test data size in test_asyncio/test_ssl.py (GH-95668) Message-ID: <mailman.530.1659689165.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3a9e1fda7ab30e04545d3eceea1f2ccd37fa1f15 commit: 3a9e1fda7ab30e04545d3eceea1f2ccd37fa1f15 branch: main author: Fantix King <fantix.king at gmail.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T10:45:36+02:00 summary: gh-95573: Reduce test data size in test_asyncio/test_ssl.py (GH-95668) Co-authored-by: ?ukasz Langa <lukasz at langa.pl> files: A Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst M Lib/test/test_asyncio/test_ssl.py diff --git a/Lib/test/test_asyncio/test_ssl.py b/Lib/test/test_asyncio/test_ssl.py index a2b5f8d258c..5de9b7a14e8 100644 --- a/Lib/test/test_asyncio/test_ssl.py +++ b/Lib/test/test_asyncio/test_ssl.py @@ -5,6 +5,7 @@ import logging import select import socket +import sys import tempfile import threading import time @@ -20,6 +21,10 @@ from test.test_asyncio import utils as test_utils +MACOS = (sys.platform == 'darwin') +BUF_MULTIPLIER = 1024 if not MACOS else 64 + + def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -191,8 +196,8 @@ def test_create_server_ssl_1(self): TOTAL_CNT = 25 # total number of clients that test will create TIMEOUT = support.LONG_TIMEOUT # timeout for this test - A_DATA = b'A' * 1024 * 1024 - B_DATA = b'B' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER + B_DATA = b'B' * 1024 * BUF_MULTIPLIER sslctx = self._create_server_ssl_context( test_utils.ONLYCERT, test_utils.ONLYKEY @@ -287,8 +292,8 @@ def test_create_connection_ssl_1(self): CNT = 0 TOTAL_CNT = 25 - A_DATA = b'A' * 1024 * 1024 - B_DATA = b'B' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER + B_DATA = b'B' * 1024 * BUF_MULTIPLIER sslctx = self._create_server_ssl_context( test_utils.ONLYCERT, @@ -1034,8 +1039,8 @@ def test_create_server_ssl_over_ssl(self): TOTAL_CNT = 25 # total number of clients that test will create TIMEOUT = support.LONG_TIMEOUT # timeout for this test - A_DATA = b'A' * 1024 * 1024 - B_DATA = b'B' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER + B_DATA = b'B' * 1024 * BUF_MULTIPLIER sslctx_1 = self._create_server_ssl_context( test_utils.ONLYCERT, test_utils.ONLYKEY) @@ -1178,7 +1183,7 @@ def test_shutdown_cleanly(self): CNT = 0 TOTAL_CNT = 25 - A_DATA = b'A' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER sslctx = self._create_server_ssl_context( test_utils.ONLYCERT, test_utils.ONLYKEY) diff --git a/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst b/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst new file mode 100644 index 00000000000..8580556965e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst @@ -0,0 +1,6 @@ +:source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug in the macOS +kernel where intense concurrent load on non-blocking sockets occasionally +causes :const:`errno.ENOBUFS` ("No buffer space available") to be emitted. +FB11063974 filed with Apple, in the mean time as a workaround buffer size +used in tests on macOS is decreased to avoid intermittent failures. Patch +by Fantix King. From webhook-mailer at python.org Fri Aug 5 05:24:03 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 05 Aug 2022 09:24:03 -0000 Subject: [Python-checkins] gh-95573: Reduce test data size in test_asyncio/test_ssl.py (GH-95668) (GH-95705) Message-ID: <mailman.531.1659691444.3313.python-checkins@python.org> https://github.com/python/cpython/commit/954b8875a0fefc876aa734a825cbcd19ea5028ca commit: 954b8875a0fefc876aa734a825cbcd19ea5028ca branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-05T11:23:57+02:00 summary: gh-95573: Reduce test data size in test_asyncio/test_ssl.py (GH-95668) (GH-95705) Co-authored-by: ?ukasz Langa <lukasz at langa.pl> (cherry picked from commit 3a9e1fda7ab30e04545d3eceea1f2ccd37fa1f15) Co-authored-by: Fantix King <fantix.king at gmail.com> files: A Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst M Lib/test/test_asyncio/test_ssl.py diff --git a/Lib/test/test_asyncio/test_ssl.py b/Lib/test/test_asyncio/test_ssl.py index a2b5f8d258c..5de9b7a14e8 100644 --- a/Lib/test/test_asyncio/test_ssl.py +++ b/Lib/test/test_asyncio/test_ssl.py @@ -5,6 +5,7 @@ import logging import select import socket +import sys import tempfile import threading import time @@ -20,6 +21,10 @@ from test.test_asyncio import utils as test_utils +MACOS = (sys.platform == 'darwin') +BUF_MULTIPLIER = 1024 if not MACOS else 64 + + def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -191,8 +196,8 @@ def test_create_server_ssl_1(self): TOTAL_CNT = 25 # total number of clients that test will create TIMEOUT = support.LONG_TIMEOUT # timeout for this test - A_DATA = b'A' * 1024 * 1024 - B_DATA = b'B' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER + B_DATA = b'B' * 1024 * BUF_MULTIPLIER sslctx = self._create_server_ssl_context( test_utils.ONLYCERT, test_utils.ONLYKEY @@ -287,8 +292,8 @@ def test_create_connection_ssl_1(self): CNT = 0 TOTAL_CNT = 25 - A_DATA = b'A' * 1024 * 1024 - B_DATA = b'B' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER + B_DATA = b'B' * 1024 * BUF_MULTIPLIER sslctx = self._create_server_ssl_context( test_utils.ONLYCERT, @@ -1034,8 +1039,8 @@ def test_create_server_ssl_over_ssl(self): TOTAL_CNT = 25 # total number of clients that test will create TIMEOUT = support.LONG_TIMEOUT # timeout for this test - A_DATA = b'A' * 1024 * 1024 - B_DATA = b'B' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER + B_DATA = b'B' * 1024 * BUF_MULTIPLIER sslctx_1 = self._create_server_ssl_context( test_utils.ONLYCERT, test_utils.ONLYKEY) @@ -1178,7 +1183,7 @@ def test_shutdown_cleanly(self): CNT = 0 TOTAL_CNT = 25 - A_DATA = b'A' * 1024 * 1024 + A_DATA = b'A' * 1024 * BUF_MULTIPLIER sslctx = self._create_server_ssl_context( test_utils.ONLYCERT, test_utils.ONLYKEY) diff --git a/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst b/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst new file mode 100644 index 00000000000..8580556965e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst @@ -0,0 +1,6 @@ +:source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug in the macOS +kernel where intense concurrent load on non-blocking sockets occasionally +causes :const:`errno.ENOBUFS` ("No buffer space available") to be emitted. +FB11063974 filed with Apple, in the mean time as a workaround buffer size +used in tests on macOS is decreased to avoid intermittent failures. Patch +by Fantix King. From webhook-mailer at python.org Fri Aug 5 07:27:06 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 05 Aug 2022 11:27:06 -0000 Subject: [Python-checkins] gh-93744: Remove configure --with-cxx-main option (#95651) Message-ID: <mailman.532.1659698828.3313.python-checkins@python.org> https://github.com/python/cpython/commit/398ed84dc40abc58e16f5014d44c08f20cb4b5f6 commit: 398ed84dc40abc58e16f5014d44c08f20cb4b5f6 branch: main author: Victor Stinner <vstinner at python.org> committer: vstinner <vstinner at python.org> date: 2022-08-05T13:26:58+02:00 summary: gh-93744: Remove configure --with-cxx-main option (#95651) Remove the "configure --with-cxx-main" build option: it didn't work for many years. Remove the MAINCC variable from configure and Makefile. The MAINCC variable was added by the issue gh-42471: commit 0f48d98b740110a672b62d467af192ec160e56ba. Previously, --with-cxx-main was named --with-cxx. Keep CXX and LDCXXSHARED variables, even if they are no longer used by Python build system. files: A Misc/NEWS.d/next/Build/2022-08-04-15-29-35.gh-issue-93744.svRuqm.rst M Doc/using/configure.rst M Makefile.pre.in M configure M configure.ac diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 580cbd814f7..4e50e73a11b 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -41,12 +41,6 @@ General Options See :data:`sys.int_info.bits_per_digit <sys.int_info>`. -.. cmdoption:: --with-cxx-main -.. cmdoption:: --with-cxx-main=COMPILER - - Compile the Python ``main()`` function and link Python executable with C++ - compiler: ``$CXX``, or *COMPILER* if specified. - .. cmdoption:: --with-suffix=SUFFIX Set the Python executable suffix to *SUFFIX*. @@ -721,22 +715,10 @@ Compiler flags Example: ``gcc -pthread``. -.. envvar:: MAINCC - - C compiler command used to build the ``main()`` function of programs like - ``python``. - - Variable set by the :option:`--with-cxx-main` option of the configure - script. - - Default: ``$(CC)``. - .. envvar:: CXX C++ compiler command. - Used if the :option:`--with-cxx-main` option is used. - Example: ``g++ -pthread``. .. envvar:: CFLAGS @@ -854,7 +836,7 @@ Linker flags Linker command used to build programs like ``python`` and ``_testembed``. - Default: ``$(PURIFY) $(MAINCC)``. + Default: ``$(PURIFY) $(CC)``. .. envvar:: CONFIGURE_LDFLAGS diff --git a/Makefile.pre.in b/Makefile.pre.in index 746ff4226e6..79616160e49 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -36,7 +36,6 @@ abs_builddir= @abs_builddir@ CC= @CC@ CXX= @CXX@ -MAINCC= @MAINCC@ LINKCC= @LINKCC@ AR= @AR@ READELF= @READELF@ @@ -1222,10 +1221,10 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Python/frozen_modules/getpath.h M -o $@ $(srcdir)/Modules/getpath.c Programs/python.o: $(srcdir)/Programs/python.c - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c Programs/_testembed.o: $(srcdir)/Programs/_testembed.c Programs/test_frozenmain.h - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c Modules/_sre/sre.o: $(srcdir)/Modules/_sre/sre.c $(srcdir)/Modules/_sre/sre.h $(srcdir)/Modules/_sre/sre_constants.h $(srcdir)/Modules/_sre/sre_lib.h diff --git a/Misc/NEWS.d/next/Build/2022-08-04-15-29-35.gh-issue-93744.svRuqm.rst b/Misc/NEWS.d/next/Build/2022-08-04-15-29-35.gh-issue-93744.svRuqm.rst new file mode 100644 index 00000000000..fa9ade25718 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-08-04-15-29-35.gh-issue-93744.svRuqm.rst @@ -0,0 +1,3 @@ +Remove the ``configure --with-cxx-main`` build option: it didn't work for +many years. Remove the ``MAINCC`` variable from ``configure`` and +``Makefile``. Patch by Victor Stinner. diff --git a/configure b/configure index 5df9f83290d..3f25d43dde6 100755 --- a/configure +++ b/configure @@ -927,7 +927,6 @@ MULTIARCH_CPPFLAGS PLATFORM_TRIPLET MULTIARCH ac_ct_CXX -MAINCC CXX EGREP SED @@ -1036,7 +1035,6 @@ enable_universalsdk with_universal_archs with_framework_name enable_framework -with_cxx_main with_emscripten_target enable_wasm_dynamic_linking enable_wasm_pthreads @@ -1805,9 +1803,6 @@ Optional Packages: specify the name for the python framework on macOS only valid when --enable-framework is set. see Mac/README.rst (default is 'Python') - --with-cxx-main[=COMPILER] - compile main() and link Python executable with C++ - compiler specified in COMPILER (default is $CXX) --with-emscripten-target=[browser|node] Emscripten platform --with-suffix=SUFFIX set executable suffix to SUFFIX (default is empty, @@ -5550,35 +5545,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-cxx-main=<compiler>" >&5 -$as_echo_n "checking for --with-cxx-main=<compiler>... " >&6; } - -# Check whether --with-cxx_main was given. -if test "${with_cxx_main+set}" = set; then : - withval=$with_cxx_main; - - case $withval in - no) with_cxx_main=no - MAINCC='$(CC)';; - yes) with_cxx_main=yes - MAINCC='$(CXX)';; - *) with_cxx_main=yes - MAINCC=$withval - if test -z "$CXX" - then - CXX=$withval - fi;; - esac -else - - with_cxx_main=no - MAINCC='$(CC)' - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_cxx_main" >&5 -$as_echo "$with_cxx_main" >&6; } - preset_cxx="$CXX" if test -z "$CXX" then @@ -6661,7 +6627,7 @@ LDVERSION="$VERSION" $as_echo_n "checking LINKCC... " >&6; } if test -z "$LINKCC" then - LINKCC='$(PURIFY) $(MAINCC)' + LINKCC='$(PURIFY) $(CC)' case $ac_sys_system in QNX*) # qcc must be used because the other compilers do not diff --git a/configure.ac b/configure.ac index 38880fcc8cc..8decd9ebae8 100644 --- a/configure.ac +++ b/configure.ac @@ -865,29 +865,6 @@ rm -f conftest.c conftest.out AC_USE_SYSTEM_EXTENSIONS AC_SUBST(CXX) -AC_SUBST(MAINCC) -AC_MSG_CHECKING(for --with-cxx-main=<compiler>) -AC_ARG_WITH(cxx_main, - AS_HELP_STRING([--with-cxx-main@<:@=COMPILER@:>@], - [compile main() and link Python executable with C++ compiler specified in COMPILER (default is $CXX)]), -[ - - case $withval in - no) with_cxx_main=no - MAINCC='$(CC)';; - yes) with_cxx_main=yes - MAINCC='$(CXX)';; - *) with_cxx_main=yes - MAINCC=$withval - if test -z "$CXX" - then - CXX=$withval - fi;; - esac], [ - with_cxx_main=no - MAINCC='$(CC)' -]) -AC_MSG_RESULT($with_cxx_main) preset_cxx="$CXX" if test -z "$CXX" @@ -1358,7 +1335,7 @@ AC_SUBST(LINKCC) AC_MSG_CHECKING(LINKCC) if test -z "$LINKCC" then - LINKCC='$(PURIFY) $(MAINCC)' + LINKCC='$(PURIFY) $(CC)' case $ac_sys_system in QNX*) # qcc must be used because the other compilers do not From webhook-mailer at python.org Fri Aug 5 10:40:50 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 05 Aug 2022 14:40:50 -0000 Subject: [Python-checkins] Remove draft notice from 3.11 What's new (#95713) Message-ID: <mailman.533.1659710452.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bacbc35830a493198ea40e3ab81613d5d187c577 commit: bacbc35830a493198ea40e3ab81613d5d187c577 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-05T15:40:41+01:00 summary: Remove draft notice from 3.11 What's new (#95713) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index f5d5d5f2be06..88f62bc2d91b 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -49,13 +49,6 @@ This article explains the new features in Python 3.11, compared to 3.10. For full details, see the :ref:`changelog <changelog>`. -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.11 moves towards release, - so it's worth checking back even after reading earlier versions. - - Summary -- Release highlights ============================= From webhook-mailer at python.org Fri Aug 5 10:41:50 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 05 Aug 2022 14:41:50 -0000 Subject: [Python-checkins] [3.11] Remove draft notice from 3.11 What's new (GH-95713) (#95715) Message-ID: <mailman.534.1659710511.3313.python-checkins@python.org> https://github.com/python/cpython/commit/96555cb2fa920c7f3a2c6d3723b45b6a62c6e702 commit: 96555cb2fa920c7f3a2c6d3723b45b6a62c6e702 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-05T15:41:45+01:00 summary: [3.11] Remove draft notice from 3.11 What's new (GH-95713) (#95715) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 0ba88532442d..3ea3fa63d408 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -49,13 +49,6 @@ This article explains the new features in Python 3.11, compared to 3.10. For full details, see the :ref:`changelog <changelog>`. -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.11 moves towards release, - so it's worth checking back even after reading earlier versions. - - Summary -- Release highlights ============================= From webhook-mailer at python.org Fri Aug 5 10:42:43 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 05 Aug 2022 14:42:43 -0000 Subject: [Python-checkins] Update the magic number in test_util.py (#95714) Message-ID: <mailman.535.1659710564.3313.python-checkins@python.org> https://github.com/python/cpython/commit/787498cbbb7d1c7115a7af4435efb7f607b10ed1 commit: 787498cbbb7d1c7115a7af4435efb7f607b10ed1 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-05T15:42:39+01:00 summary: Update the magic number in test_util.py (#95714) files: M Lib/test/test_importlib/test_util.py diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index c77c7814a9cc..a62d68fcd8b3 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -860,7 +860,7 @@ def test_magic_number(self): # stakeholders such as OS package maintainers must be notified # in advance. Such exceptional releases will then require an # adjustment to this test case. - EXPECTED_MAGIC_NUMBER = 3413 + EXPECTED_MAGIC_NUMBER = 3495 actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') msg = ( From webhook-mailer at python.org Fri Aug 5 10:43:14 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 05 Aug 2022 14:43:14 -0000 Subject: [Python-checkins] [3.11] Update the magic number in test_util.py (GH-95714) (#95716) Message-ID: <mailman.536.1659710595.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d6cf9e4a3efaf34b2071b7e8b10c0fef3c0ba823 commit: d6cf9e4a3efaf34b2071b7e8b10c0fef3c0ba823 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-05T15:43:10+01:00 summary: [3.11] Update the magic number in test_util.py (GH-95714) (#95716) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: M Lib/test/test_importlib/test_util.py diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index c77c7814a9cc..a62d68fcd8b3 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -860,7 +860,7 @@ def test_magic_number(self): # stakeholders such as OS package maintainers must be notified # in advance. Such exceptional releases will then require an # adjustment to this test case. - EXPECTED_MAGIC_NUMBER = 3413 + EXPECTED_MAGIC_NUMBER = 3495 actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') msg = ( From webhook-mailer at python.org Fri Aug 5 11:31:00 2022 From: webhook-mailer at python.org (encukou) Date: Fri, 05 Aug 2022 15:31:00 -0000 Subject: [Python-checkins] gh-91271: Document which parts of structs are in limited API/stable ABI (GH-32196) (GH-95711) Message-ID: <mailman.537.1659713461.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b66b6e1cc0c18e7e1c5e64bed0b087dc61da57f5 commit: b66b6e1cc0c18e7e1c5e64bed0b087dc61da57f5 branch: 3.10 author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-05T17:30:51+02:00 summary: gh-91271: Document which parts of structs are in limited API/stable ABI (GH-32196) (GH-95711) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at innova.no> files: A Misc/NEWS.d/next/Documentation/2022-03-30-17-08-12.bpo-47115.R3wt3i.rst M Doc/data/stable_abi.dat M Doc/tools/extensions/c_annotations.py M Misc/stable_abi.txt M Tools/scripts/stable_abi.py diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index ea102b989c86..7334d989918d 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -1,863 +1,867 @@ -role,name,added,ifdef_note -function,PyAIter_Check,3.10, -function,PyArg_Parse,3.2, -function,PyArg_ParseTuple,3.2, -function,PyArg_ParseTupleAndKeywords,3.2, -function,PyArg_UnpackTuple,3.2, -function,PyArg_VaParse,3.2, -function,PyArg_VaParseTupleAndKeywords,3.2, -function,PyArg_ValidateKeywordArguments,3.2, -var,PyBaseObject_Type,3.2, -function,PyBool_FromLong,3.2, -var,PyBool_Type,3.2, -var,PyByteArrayIter_Type,3.2, -function,PyByteArray_AsString,3.2, -function,PyByteArray_Concat,3.2, -function,PyByteArray_FromObject,3.2, -function,PyByteArray_FromStringAndSize,3.2, -function,PyByteArray_Resize,3.2, -function,PyByteArray_Size,3.2, -var,PyByteArray_Type,3.2, -var,PyBytesIter_Type,3.2, -function,PyBytes_AsString,3.2, -function,PyBytes_AsStringAndSize,3.2, -function,PyBytes_Concat,3.2, -function,PyBytes_ConcatAndDel,3.2, -function,PyBytes_DecodeEscape,3.2, -function,PyBytes_FromFormat,3.2, -function,PyBytes_FromFormatV,3.2, -function,PyBytes_FromObject,3.2, -function,PyBytes_FromString,3.2, -function,PyBytes_FromStringAndSize,3.2, -function,PyBytes_Repr,3.2, -function,PyBytes_Size,3.2, -var,PyBytes_Type,3.2, -type,PyCFunction,3.2, -type,PyCFunctionWithKeywords,3.2, -function,PyCFunction_Call,3.2, -function,PyCFunction_GetFlags,3.2, -function,PyCFunction_GetFunction,3.2, -function,PyCFunction_GetSelf,3.2, -function,PyCFunction_New,3.4, -function,PyCFunction_NewEx,3.2, -var,PyCFunction_Type,3.2, -function,PyCMethod_New,3.9, -function,PyCallIter_New,3.2, -var,PyCallIter_Type,3.2, -function,PyCallable_Check,3.2, -type,PyCapsule_Destructor,3.2, -function,PyCapsule_GetContext,3.2, -function,PyCapsule_GetDestructor,3.2, -function,PyCapsule_GetName,3.2, -function,PyCapsule_GetPointer,3.2, -function,PyCapsule_Import,3.2, -function,PyCapsule_IsValid,3.2, -function,PyCapsule_New,3.2, -function,PyCapsule_SetContext,3.2, -function,PyCapsule_SetDestructor,3.2, -function,PyCapsule_SetName,3.2, -function,PyCapsule_SetPointer,3.2, -var,PyCapsule_Type,3.2, -var,PyClassMethodDescr_Type,3.2, -function,PyCodec_BackslashReplaceErrors,3.2, -function,PyCodec_Decode,3.2, -function,PyCodec_Decoder,3.2, -function,PyCodec_Encode,3.2, -function,PyCodec_Encoder,3.2, -function,PyCodec_IgnoreErrors,3.2, -function,PyCodec_IncrementalDecoder,3.2, -function,PyCodec_IncrementalEncoder,3.2, -function,PyCodec_KnownEncoding,3.2, -function,PyCodec_LookupError,3.2, -function,PyCodec_NameReplaceErrors,3.7, -function,PyCodec_Register,3.2, -function,PyCodec_RegisterError,3.2, -function,PyCodec_ReplaceErrors,3.2, -function,PyCodec_StreamReader,3.2, -function,PyCodec_StreamWriter,3.2, -function,PyCodec_StrictErrors,3.2, -function,PyCodec_Unregister,3.10, -function,PyCodec_XMLCharRefReplaceErrors,3.2, -function,PyComplex_FromDoubles,3.2, -function,PyComplex_ImagAsDouble,3.2, -function,PyComplex_RealAsDouble,3.2, -var,PyComplex_Type,3.2, -function,PyDescr_NewClassMethod,3.2, -function,PyDescr_NewGetSet,3.2, -function,PyDescr_NewMember,3.2, -function,PyDescr_NewMethod,3.2, -var,PyDictItems_Type,3.2, -var,PyDictIterItem_Type,3.2, -var,PyDictIterKey_Type,3.2, -var,PyDictIterValue_Type,3.2, -var,PyDictKeys_Type,3.2, -function,PyDictProxy_New,3.2, -var,PyDictProxy_Type,3.2, -var,PyDictRevIterItem_Type,3.8, -var,PyDictRevIterKey_Type,3.8, -var,PyDictRevIterValue_Type,3.8, -var,PyDictValues_Type,3.2, -function,PyDict_Clear,3.2, -function,PyDict_Contains,3.2, -function,PyDict_Copy,3.2, -function,PyDict_DelItem,3.2, -function,PyDict_DelItemString,3.2, -function,PyDict_GetItem,3.2, -function,PyDict_GetItemString,3.2, -function,PyDict_GetItemWithError,3.2, -function,PyDict_Items,3.2, -function,PyDict_Keys,3.2, -function,PyDict_Merge,3.2, -function,PyDict_MergeFromSeq2,3.2, -function,PyDict_New,3.2, -function,PyDict_Next,3.2, -function,PyDict_SetItem,3.2, -function,PyDict_SetItemString,3.2, -function,PyDict_Size,3.2, -var,PyDict_Type,3.2, -function,PyDict_Update,3.2, -function,PyDict_Values,3.2, -var,PyEllipsis_Type,3.2, -var,PyEnum_Type,3.2, -function,PyErr_BadArgument,3.2, -function,PyErr_BadInternalCall,3.2, -function,PyErr_CheckSignals,3.2, -function,PyErr_Clear,3.2, -function,PyErr_Display,3.2, -function,PyErr_ExceptionMatches,3.2, -function,PyErr_Fetch,3.2, -function,PyErr_Format,3.2, -function,PyErr_FormatV,3.5, -function,PyErr_GetExcInfo,3.7, -function,PyErr_GivenExceptionMatches,3.2, -function,PyErr_NewException,3.2, -function,PyErr_NewExceptionWithDoc,3.2, -function,PyErr_NoMemory,3.2, -function,PyErr_NormalizeException,3.2, -function,PyErr_Occurred,3.2, -function,PyErr_Print,3.2, -function,PyErr_PrintEx,3.2, -function,PyErr_ProgramText,3.2, -function,PyErr_ResourceWarning,3.6, -function,PyErr_Restore,3.2, -function,PyErr_SetExcFromWindowsErr,3.7,on Windows -function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows -function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows -function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows -function,PyErr_SetExcInfo,3.7, -function,PyErr_SetFromErrno,3.2, -function,PyErr_SetFromErrnoWithFilename,3.2, -function,PyErr_SetFromErrnoWithFilenameObject,3.2, -function,PyErr_SetFromErrnoWithFilenameObjects,3.7, -function,PyErr_SetFromWindowsErr,3.7,on Windows -function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows -function,PyErr_SetImportError,3.7, -function,PyErr_SetImportErrorSubclass,3.6, -function,PyErr_SetInterrupt,3.2, -function,PyErr_SetInterruptEx,3.10, -function,PyErr_SetNone,3.2, -function,PyErr_SetObject,3.2, -function,PyErr_SetString,3.2, -function,PyErr_SyntaxLocation,3.2, -function,PyErr_SyntaxLocationEx,3.7, -function,PyErr_WarnEx,3.2, -function,PyErr_WarnExplicit,3.2, -function,PyErr_WarnFormat,3.2, -function,PyErr_WriteUnraisable,3.2, -function,PyEval_AcquireLock,3.2, -function,PyEval_AcquireThread,3.2, -function,PyEval_CallFunction,3.2, -function,PyEval_CallMethod,3.2, -function,PyEval_CallObjectWithKeywords,3.2, -function,PyEval_EvalCode,3.2, -function,PyEval_EvalCodeEx,3.2, -function,PyEval_EvalFrame,3.2, -function,PyEval_EvalFrameEx,3.2, -function,PyEval_GetBuiltins,3.2, -function,PyEval_GetFrame,3.2, -function,PyEval_GetFuncDesc,3.2, -function,PyEval_GetFuncName,3.2, -function,PyEval_GetGlobals,3.2, -function,PyEval_GetLocals,3.2, -function,PyEval_InitThreads,3.2, -function,PyEval_ReleaseLock,3.2, -function,PyEval_ReleaseThread,3.2, -function,PyEval_RestoreThread,3.2, -function,PyEval_SaveThread,3.2, -function,PyEval_ThreadsInitialized,3.2, -var,PyExc_ArithmeticError,3.2, -var,PyExc_AssertionError,3.2, -var,PyExc_AttributeError,3.2, -var,PyExc_BaseException,3.2, -var,PyExc_BlockingIOError,3.7, -var,PyExc_BrokenPipeError,3.7, -var,PyExc_BufferError,3.2, -var,PyExc_BytesWarning,3.2, -var,PyExc_ChildProcessError,3.7, -var,PyExc_ConnectionAbortedError,3.7, -var,PyExc_ConnectionError,3.7, -var,PyExc_ConnectionRefusedError,3.7, -var,PyExc_ConnectionResetError,3.7, -var,PyExc_DeprecationWarning,3.2, -var,PyExc_EOFError,3.2, -var,PyExc_EncodingWarning,3.10, -var,PyExc_EnvironmentError,3.2, -var,PyExc_Exception,3.2, -var,PyExc_FileExistsError,3.7, -var,PyExc_FileNotFoundError,3.7, -var,PyExc_FloatingPointError,3.2, -var,PyExc_FutureWarning,3.2, -var,PyExc_GeneratorExit,3.2, -var,PyExc_IOError,3.2, -var,PyExc_ImportError,3.2, -var,PyExc_ImportWarning,3.2, -var,PyExc_IndentationError,3.2, -var,PyExc_IndexError,3.2, -var,PyExc_InterruptedError,3.7, -var,PyExc_IsADirectoryError,3.7, -var,PyExc_KeyError,3.2, -var,PyExc_KeyboardInterrupt,3.2, -var,PyExc_LookupError,3.2, -var,PyExc_MemoryError,3.2, -var,PyExc_ModuleNotFoundError,3.6, -var,PyExc_NameError,3.2, -var,PyExc_NotADirectoryError,3.7, -var,PyExc_NotImplementedError,3.2, -var,PyExc_OSError,3.2, -var,PyExc_OverflowError,3.2, -var,PyExc_PendingDeprecationWarning,3.2, -var,PyExc_PermissionError,3.7, -var,PyExc_ProcessLookupError,3.7, -var,PyExc_RecursionError,3.7, -var,PyExc_ReferenceError,3.2, -var,PyExc_ResourceWarning,3.7, -var,PyExc_RuntimeError,3.2, -var,PyExc_RuntimeWarning,3.2, -var,PyExc_StopAsyncIteration,3.7, -var,PyExc_StopIteration,3.2, -var,PyExc_SyntaxError,3.2, -var,PyExc_SyntaxWarning,3.2, -var,PyExc_SystemError,3.2, -var,PyExc_SystemExit,3.2, -var,PyExc_TabError,3.2, -var,PyExc_TimeoutError,3.7, -var,PyExc_TypeError,3.2, -var,PyExc_UnboundLocalError,3.2, -var,PyExc_UnicodeDecodeError,3.2, -var,PyExc_UnicodeEncodeError,3.2, -var,PyExc_UnicodeError,3.2, -var,PyExc_UnicodeTranslateError,3.2, -var,PyExc_UnicodeWarning,3.2, -var,PyExc_UserWarning,3.2, -var,PyExc_ValueError,3.2, -var,PyExc_Warning,3.2, -var,PyExc_WindowsError,3.7,on Windows -var,PyExc_ZeroDivisionError,3.2, -function,PyExceptionClass_Name,3.8, -function,PyException_GetCause,3.2, -function,PyException_GetContext,3.2, -function,PyException_GetTraceback,3.2, -function,PyException_SetCause,3.2, -function,PyException_SetContext,3.2, -function,PyException_SetTraceback,3.2, -function,PyFile_FromFd,3.2, -function,PyFile_GetLine,3.2, -function,PyFile_WriteObject,3.2, -function,PyFile_WriteString,3.2, -var,PyFilter_Type,3.2, -function,PyFloat_AsDouble,3.2, -function,PyFloat_FromDouble,3.2, -function,PyFloat_FromString,3.2, -function,PyFloat_GetInfo,3.2, -function,PyFloat_GetMax,3.2, -function,PyFloat_GetMin,3.2, -var,PyFloat_Type,3.2, -type,PyFrameObject,3.2, -function,PyFrame_GetCode,3.10, -function,PyFrame_GetLineNumber,3.10, -function,PyFrozenSet_New,3.2, -var,PyFrozenSet_Type,3.2, -function,PyGC_Collect,3.2, -function,PyGC_Disable,3.10, -function,PyGC_Enable,3.10, -function,PyGC_IsEnabled,3.10, -function,PyGILState_Ensure,3.2, -function,PyGILState_GetThisThreadState,3.2, -function,PyGILState_Release,3.2, -type,PyGILState_STATE,3.2, -type,PyGetSetDef,3.2, -var,PyGetSetDescr_Type,3.2, -function,PyImport_AddModule,3.2, -function,PyImport_AddModuleObject,3.7, -function,PyImport_AppendInittab,3.2, -function,PyImport_ExecCodeModule,3.2, -function,PyImport_ExecCodeModuleEx,3.2, -function,PyImport_ExecCodeModuleObject,3.7, -function,PyImport_ExecCodeModuleWithPathnames,3.2, -function,PyImport_GetImporter,3.2, -function,PyImport_GetMagicNumber,3.2, -function,PyImport_GetMagicTag,3.2, -function,PyImport_GetModule,3.8, -function,PyImport_GetModuleDict,3.2, -function,PyImport_Import,3.2, -function,PyImport_ImportFrozenModule,3.2, -function,PyImport_ImportFrozenModuleObject,3.7, -function,PyImport_ImportModule,3.2, -function,PyImport_ImportModuleLevel,3.2, -function,PyImport_ImportModuleLevelObject,3.7, -function,PyImport_ImportModuleNoBlock,3.2, -function,PyImport_ReloadModule,3.2, -function,PyIndex_Check,3.8, -type,PyInterpreterState,3.2, -function,PyInterpreterState_Clear,3.2, -function,PyInterpreterState_Delete,3.2, -function,PyInterpreterState_Get,3.9, -function,PyInterpreterState_GetDict,3.8, -function,PyInterpreterState_GetID,3.7, -function,PyInterpreterState_New,3.2, -function,PyIter_Check,3.8, -function,PyIter_Next,3.2, -function,PyIter_Send,3.10, -var,PyListIter_Type,3.2, -var,PyListRevIter_Type,3.2, -function,PyList_Append,3.2, -function,PyList_AsTuple,3.2, -function,PyList_GetItem,3.2, -function,PyList_GetSlice,3.2, -function,PyList_Insert,3.2, -function,PyList_New,3.2, -function,PyList_Reverse,3.2, -function,PyList_SetItem,3.2, -function,PyList_SetSlice,3.2, -function,PyList_Size,3.2, -function,PyList_Sort,3.2, -var,PyList_Type,3.2, -type,PyLongObject,3.2, -var,PyLongRangeIter_Type,3.2, -function,PyLong_AsDouble,3.2, -function,PyLong_AsLong,3.2, -function,PyLong_AsLongAndOverflow,3.2, -function,PyLong_AsLongLong,3.2, -function,PyLong_AsLongLongAndOverflow,3.2, -function,PyLong_AsSize_t,3.2, -function,PyLong_AsSsize_t,3.2, -function,PyLong_AsUnsignedLong,3.2, -function,PyLong_AsUnsignedLongLong,3.2, -function,PyLong_AsUnsignedLongLongMask,3.2, -function,PyLong_AsUnsignedLongMask,3.2, -function,PyLong_AsVoidPtr,3.2, -function,PyLong_FromDouble,3.2, -function,PyLong_FromLong,3.2, -function,PyLong_FromLongLong,3.2, -function,PyLong_FromSize_t,3.2, -function,PyLong_FromSsize_t,3.2, -function,PyLong_FromString,3.2, -function,PyLong_FromUnsignedLong,3.2, -function,PyLong_FromUnsignedLongLong,3.2, -function,PyLong_FromVoidPtr,3.2, -function,PyLong_GetInfo,3.2, -var,PyLong_Type,3.2, -var,PyMap_Type,3.2, -function,PyMapping_Check,3.2, -function,PyMapping_GetItemString,3.2, -function,PyMapping_HasKey,3.2, -function,PyMapping_HasKeyString,3.2, -function,PyMapping_Items,3.2, -function,PyMapping_Keys,3.2, -function,PyMapping_Length,3.2, -function,PyMapping_SetItemString,3.2, -function,PyMapping_Size,3.2, -function,PyMapping_Values,3.2, -function,PyMem_Calloc,3.7, -function,PyMem_Free,3.2, -function,PyMem_Malloc,3.2, -function,PyMem_Realloc,3.2, -type,PyMemberDef,3.2, -var,PyMemberDescr_Type,3.2, -function,PyMemoryView_FromMemory,3.7, -function,PyMemoryView_FromObject,3.2, -function,PyMemoryView_GetContiguous,3.2, -var,PyMemoryView_Type,3.2, -type,PyMethodDef,3.2, -var,PyMethodDescr_Type,3.2, -type,PyModuleDef,3.2, -type,PyModuleDef_Base,3.2, -function,PyModuleDef_Init,3.5, -var,PyModuleDef_Type,3.5, -function,PyModule_AddFunctions,3.7, -function,PyModule_AddIntConstant,3.2, -function,PyModule_AddObject,3.2, -function,PyModule_AddObjectRef,3.10, -function,PyModule_AddStringConstant,3.2, -function,PyModule_AddType,3.10, -function,PyModule_Create2,3.2, -function,PyModule_ExecDef,3.7, -function,PyModule_FromDefAndSpec2,3.7, -function,PyModule_GetDef,3.2, -function,PyModule_GetDict,3.2, -function,PyModule_GetFilename,3.2, -function,PyModule_GetFilenameObject,3.2, -function,PyModule_GetName,3.2, -function,PyModule_GetNameObject,3.7, -function,PyModule_GetState,3.2, -function,PyModule_New,3.2, -function,PyModule_NewObject,3.7, -function,PyModule_SetDocString,3.7, -var,PyModule_Type,3.2, -function,PyNumber_Absolute,3.2, -function,PyNumber_Add,3.2, -function,PyNumber_And,3.2, -function,PyNumber_AsSsize_t,3.2, -function,PyNumber_Check,3.2, -function,PyNumber_Divmod,3.2, -function,PyNumber_Float,3.2, -function,PyNumber_FloorDivide,3.2, -function,PyNumber_InPlaceAdd,3.2, -function,PyNumber_InPlaceAnd,3.2, -function,PyNumber_InPlaceFloorDivide,3.2, -function,PyNumber_InPlaceLshift,3.2, -function,PyNumber_InPlaceMatrixMultiply,3.7, -function,PyNumber_InPlaceMultiply,3.2, -function,PyNumber_InPlaceOr,3.2, -function,PyNumber_InPlacePower,3.2, -function,PyNumber_InPlaceRemainder,3.2, -function,PyNumber_InPlaceRshift,3.2, -function,PyNumber_InPlaceSubtract,3.2, -function,PyNumber_InPlaceTrueDivide,3.2, -function,PyNumber_InPlaceXor,3.2, -function,PyNumber_Index,3.2, -function,PyNumber_Invert,3.2, -function,PyNumber_Long,3.2, -function,PyNumber_Lshift,3.2, -function,PyNumber_MatrixMultiply,3.7, -function,PyNumber_Multiply,3.2, -function,PyNumber_Negative,3.2, -function,PyNumber_Or,3.2, -function,PyNumber_Positive,3.2, -function,PyNumber_Power,3.2, -function,PyNumber_Remainder,3.2, -function,PyNumber_Rshift,3.2, -function,PyNumber_Subtract,3.2, -function,PyNumber_ToBase,3.2, -function,PyNumber_TrueDivide,3.2, -function,PyNumber_Xor,3.2, -function,PyOS_AfterFork,3.2,on platforms with fork() -function,PyOS_AfterFork_Child,3.7,on platforms with fork() -function,PyOS_AfterFork_Parent,3.7,on platforms with fork() -function,PyOS_BeforeFork,3.7,on platforms with fork() -function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK -function,PyOS_FSPath,3.6, -var,PyOS_InputHook,3.2, -function,PyOS_InterruptOccurred,3.2, -function,PyOS_double_to_string,3.2, -function,PyOS_getsig,3.2, -function,PyOS_mystricmp,3.2, -function,PyOS_mystrnicmp,3.2, -function,PyOS_setsig,3.2, -type,PyOS_sighandler_t,3.2, -function,PyOS_snprintf,3.2, -function,PyOS_string_to_double,3.2, -function,PyOS_strtol,3.2, -function,PyOS_strtoul,3.2, -function,PyOS_vsnprintf,3.2, -type,PyObject,3.2, -function,PyObject_ASCII,3.2, -function,PyObject_AsCharBuffer,3.2, -function,PyObject_AsFileDescriptor,3.2, -function,PyObject_AsReadBuffer,3.2, -function,PyObject_AsWriteBuffer,3.2, -function,PyObject_Bytes,3.2, -function,PyObject_Call,3.2, -function,PyObject_CallFunction,3.2, -function,PyObject_CallFunctionObjArgs,3.2, -function,PyObject_CallMethod,3.2, -function,PyObject_CallMethodObjArgs,3.2, -function,PyObject_CallNoArgs,3.10, -function,PyObject_CallObject,3.2, -function,PyObject_Calloc,3.7, -function,PyObject_CheckReadBuffer,3.2, -function,PyObject_ClearWeakRefs,3.2, -function,PyObject_DelItem,3.2, -function,PyObject_DelItemString,3.2, -function,PyObject_Dir,3.2, -function,PyObject_Format,3.2, -function,PyObject_Free,3.2, -function,PyObject_GC_Del,3.2, -function,PyObject_GC_IsFinalized,3.9, -function,PyObject_GC_IsTracked,3.9, -function,PyObject_GC_Track,3.2, -function,PyObject_GC_UnTrack,3.2, -function,PyObject_GenericGetAttr,3.2, -function,PyObject_GenericGetDict,3.10, -function,PyObject_GenericSetAttr,3.2, -function,PyObject_GenericSetDict,3.7, -function,PyObject_GetAIter,3.10, -function,PyObject_GetAttr,3.2, -function,PyObject_GetAttrString,3.2, -function,PyObject_GetItem,3.2, -function,PyObject_GetIter,3.2, -function,PyObject_HasAttr,3.2, -function,PyObject_HasAttrString,3.2, -function,PyObject_Hash,3.2, -function,PyObject_HashNotImplemented,3.2, -function,PyObject_Init,3.2, -function,PyObject_InitVar,3.2, -function,PyObject_IsInstance,3.2, -function,PyObject_IsSubclass,3.2, -function,PyObject_IsTrue,3.2, -function,PyObject_Length,3.2, -function,PyObject_Malloc,3.2, -function,PyObject_Not,3.2, -function,PyObject_Realloc,3.2, -function,PyObject_Repr,3.2, -function,PyObject_RichCompare,3.2, -function,PyObject_RichCompareBool,3.2, -function,PyObject_SelfIter,3.2, -function,PyObject_SetAttr,3.2, -function,PyObject_SetAttrString,3.2, -function,PyObject_SetItem,3.2, -function,PyObject_Size,3.2, -function,PyObject_Str,3.2, -function,PyObject_Type,3.2, -var,PyProperty_Type,3.2, -var,PyRangeIter_Type,3.2, -var,PyRange_Type,3.2, -var,PyReversed_Type,3.2, -function,PySeqIter_New,3.2, -var,PySeqIter_Type,3.2, -function,PySequence_Check,3.2, -function,PySequence_Concat,3.2, -function,PySequence_Contains,3.2, -function,PySequence_Count,3.2, -function,PySequence_DelItem,3.2, -function,PySequence_DelSlice,3.2, -function,PySequence_Fast,3.2, -function,PySequence_GetItem,3.2, -function,PySequence_GetSlice,3.2, -function,PySequence_In,3.2, -function,PySequence_InPlaceConcat,3.2, -function,PySequence_InPlaceRepeat,3.2, -function,PySequence_Index,3.2, -function,PySequence_Length,3.2, -function,PySequence_List,3.2, -function,PySequence_Repeat,3.2, -function,PySequence_SetItem,3.2, -function,PySequence_SetSlice,3.2, -function,PySequence_Size,3.2, -function,PySequence_Tuple,3.2, -var,PySetIter_Type,3.2, -function,PySet_Add,3.2, -function,PySet_Clear,3.2, -function,PySet_Contains,3.2, -function,PySet_Discard,3.2, -function,PySet_New,3.2, -function,PySet_Pop,3.2, -function,PySet_Size,3.2, -var,PySet_Type,3.2, -function,PySlice_AdjustIndices,3.7, -function,PySlice_GetIndices,3.2, -function,PySlice_GetIndicesEx,3.2, -function,PySlice_New,3.2, -var,PySlice_Type,3.2, -function,PySlice_Unpack,3.7, -function,PyState_AddModule,3.3, -function,PyState_FindModule,3.2, -function,PyState_RemoveModule,3.3, -type,PyStructSequence_Desc,3.2, -type,PyStructSequence_Field,3.2, -function,PyStructSequence_GetItem,3.2, -function,PyStructSequence_New,3.2, -function,PyStructSequence_NewType,3.2, -function,PyStructSequence_SetItem,3.2, -var,PySuper_Type,3.2, -function,PySys_AddWarnOption,3.2, -function,PySys_AddWarnOptionUnicode,3.2, -function,PySys_AddXOption,3.7, -function,PySys_FormatStderr,3.2, -function,PySys_FormatStdout,3.2, -function,PySys_GetObject,3.2, -function,PySys_GetXOptions,3.7, -function,PySys_HasWarnOptions,3.2, -function,PySys_ResetWarnOptions,3.2, -function,PySys_SetArgv,3.2, -function,PySys_SetArgvEx,3.2, -function,PySys_SetObject,3.2, -function,PySys_SetPath,3.2, -function,PySys_WriteStderr,3.2, -function,PySys_WriteStdout,3.2, -type,PyThreadState,3.2, -function,PyThreadState_Clear,3.2, -function,PyThreadState_Delete,3.2, -function,PyThreadState_Get,3.2, -function,PyThreadState_GetDict,3.2, -function,PyThreadState_GetFrame,3.10, -function,PyThreadState_GetID,3.10, -function,PyThreadState_GetInterpreter,3.10, -function,PyThreadState_New,3.2, -function,PyThreadState_SetAsyncExc,3.2, -function,PyThreadState_Swap,3.2, -function,PyThread_GetInfo,3.3, -function,PyThread_ReInitTLS,3.2, -function,PyThread_acquire_lock,3.2, -function,PyThread_acquire_lock_timed,3.2, -function,PyThread_allocate_lock,3.2, -function,PyThread_create_key,3.2, -function,PyThread_delete_key,3.2, -function,PyThread_delete_key_value,3.2, -function,PyThread_exit_thread,3.2, -function,PyThread_free_lock,3.2, -function,PyThread_get_key_value,3.2, -function,PyThread_get_stacksize,3.2, -function,PyThread_get_thread_ident,3.2, -function,PyThread_get_thread_native_id,3.2, -function,PyThread_init_thread,3.2, -function,PyThread_release_lock,3.2, -function,PyThread_set_key_value,3.2, -function,PyThread_set_stacksize,3.2, -function,PyThread_start_new_thread,3.2, -function,PyThread_tss_alloc,3.7, -function,PyThread_tss_create,3.7, -function,PyThread_tss_delete,3.7, -function,PyThread_tss_free,3.7, -function,PyThread_tss_get,3.7, -function,PyThread_tss_is_created,3.7, -function,PyThread_tss_set,3.7, -function,PyTraceBack_Here,3.2, -function,PyTraceBack_Print,3.2, -var,PyTraceBack_Type,3.2, -var,PyTupleIter_Type,3.2, -function,PyTuple_GetItem,3.2, -function,PyTuple_GetSlice,3.2, -function,PyTuple_New,3.2, -function,PyTuple_Pack,3.2, -function,PyTuple_SetItem,3.2, -function,PyTuple_Size,3.2, -var,PyTuple_Type,3.2, -type,PyTypeObject,3.2, -function,PyType_ClearCache,3.2, -function,PyType_FromModuleAndSpec,3.10, -function,PyType_FromSpec,3.2, -function,PyType_FromSpecWithBases,3.3, -function,PyType_GenericAlloc,3.2, -function,PyType_GenericNew,3.2, -function,PyType_GetFlags,3.2, -function,PyType_GetModule,3.10, -function,PyType_GetModuleState,3.10, -function,PyType_GetSlot,3.4, -function,PyType_IsSubtype,3.2, -function,PyType_Modified,3.2, -function,PyType_Ready,3.2, -type,PyType_Slot,3.2, -type,PyType_Spec,3.2, -var,PyType_Type,3.2, -function,PyUnicodeDecodeError_Create,3.2, -function,PyUnicodeDecodeError_GetEncoding,3.2, -function,PyUnicodeDecodeError_GetEnd,3.2, -function,PyUnicodeDecodeError_GetObject,3.2, -function,PyUnicodeDecodeError_GetReason,3.2, -function,PyUnicodeDecodeError_GetStart,3.2, -function,PyUnicodeDecodeError_SetEnd,3.2, -function,PyUnicodeDecodeError_SetReason,3.2, -function,PyUnicodeDecodeError_SetStart,3.2, -function,PyUnicodeEncodeError_GetEncoding,3.2, -function,PyUnicodeEncodeError_GetEnd,3.2, -function,PyUnicodeEncodeError_GetObject,3.2, -function,PyUnicodeEncodeError_GetReason,3.2, -function,PyUnicodeEncodeError_GetStart,3.2, -function,PyUnicodeEncodeError_SetEnd,3.2, -function,PyUnicodeEncodeError_SetReason,3.2, -function,PyUnicodeEncodeError_SetStart,3.2, -var,PyUnicodeIter_Type,3.2, -function,PyUnicodeTranslateError_GetEnd,3.2, -function,PyUnicodeTranslateError_GetObject,3.2, -function,PyUnicodeTranslateError_GetReason,3.2, -function,PyUnicodeTranslateError_GetStart,3.2, -function,PyUnicodeTranslateError_SetEnd,3.2, -function,PyUnicodeTranslateError_SetReason,3.2, -function,PyUnicodeTranslateError_SetStart,3.2, -function,PyUnicode_Append,3.2, -function,PyUnicode_AppendAndDel,3.2, -function,PyUnicode_AsASCIIString,3.2, -function,PyUnicode_AsCharmapString,3.2, -function,PyUnicode_AsDecodedObject,3.2, -function,PyUnicode_AsDecodedUnicode,3.2, -function,PyUnicode_AsEncodedObject,3.2, -function,PyUnicode_AsEncodedString,3.2, -function,PyUnicode_AsEncodedUnicode,3.2, -function,PyUnicode_AsLatin1String,3.2, -function,PyUnicode_AsMBCSString,3.7,on Windows -function,PyUnicode_AsRawUnicodeEscapeString,3.2, -function,PyUnicode_AsUCS4,3.7, -function,PyUnicode_AsUCS4Copy,3.7, -function,PyUnicode_AsUTF16String,3.2, -function,PyUnicode_AsUTF32String,3.2, -function,PyUnicode_AsUTF8AndSize,3.10, -function,PyUnicode_AsUTF8String,3.2, -function,PyUnicode_AsUnicodeEscapeString,3.2, -function,PyUnicode_AsWideChar,3.2, -function,PyUnicode_AsWideCharString,3.7, -function,PyUnicode_BuildEncodingMap,3.2, -function,PyUnicode_Compare,3.2, -function,PyUnicode_CompareWithASCIIString,3.2, -function,PyUnicode_Concat,3.2, -function,PyUnicode_Contains,3.2, -function,PyUnicode_Count,3.2, -function,PyUnicode_Decode,3.2, -function,PyUnicode_DecodeASCII,3.2, -function,PyUnicode_DecodeCharmap,3.2, -function,PyUnicode_DecodeCodePageStateful,3.7,on Windows -function,PyUnicode_DecodeFSDefault,3.2, -function,PyUnicode_DecodeFSDefaultAndSize,3.2, -function,PyUnicode_DecodeLatin1,3.2, -function,PyUnicode_DecodeLocale,3.7, -function,PyUnicode_DecodeLocaleAndSize,3.7, -function,PyUnicode_DecodeMBCS,3.7,on Windows -function,PyUnicode_DecodeMBCSStateful,3.7,on Windows -function,PyUnicode_DecodeRawUnicodeEscape,3.2, -function,PyUnicode_DecodeUTF16,3.2, -function,PyUnicode_DecodeUTF16Stateful,3.2, -function,PyUnicode_DecodeUTF32,3.2, -function,PyUnicode_DecodeUTF32Stateful,3.2, -function,PyUnicode_DecodeUTF7,3.2, -function,PyUnicode_DecodeUTF7Stateful,3.2, -function,PyUnicode_DecodeUTF8,3.2, -function,PyUnicode_DecodeUTF8Stateful,3.2, -function,PyUnicode_DecodeUnicodeEscape,3.2, -function,PyUnicode_EncodeCodePage,3.7,on Windows -function,PyUnicode_EncodeFSDefault,3.2, -function,PyUnicode_EncodeLocale,3.7, -function,PyUnicode_FSConverter,3.2, -function,PyUnicode_FSDecoder,3.2, -function,PyUnicode_Find,3.2, -function,PyUnicode_FindChar,3.7, -function,PyUnicode_Format,3.2, -function,PyUnicode_FromEncodedObject,3.2, -function,PyUnicode_FromFormat,3.2, -function,PyUnicode_FromFormatV,3.2, -function,PyUnicode_FromObject,3.2, -function,PyUnicode_FromOrdinal,3.2, -function,PyUnicode_FromString,3.2, -function,PyUnicode_FromStringAndSize,3.2, -function,PyUnicode_FromWideChar,3.2, -function,PyUnicode_GetDefaultEncoding,3.2, -function,PyUnicode_GetLength,3.7, -function,PyUnicode_GetSize,3.2, -function,PyUnicode_InternFromString,3.2, -function,PyUnicode_InternImmortal,3.2, -function,PyUnicode_InternInPlace,3.2, -function,PyUnicode_IsIdentifier,3.2, -function,PyUnicode_Join,3.2, -function,PyUnicode_Partition,3.2, -function,PyUnicode_RPartition,3.2, -function,PyUnicode_RSplit,3.2, -function,PyUnicode_ReadChar,3.7, -function,PyUnicode_Replace,3.2, -function,PyUnicode_Resize,3.2, -function,PyUnicode_RichCompare,3.2, -function,PyUnicode_Split,3.2, -function,PyUnicode_Splitlines,3.2, -function,PyUnicode_Substring,3.7, -function,PyUnicode_Tailmatch,3.2, -function,PyUnicode_Translate,3.2, -var,PyUnicode_Type,3.2, -function,PyUnicode_WriteChar,3.7, -type,PyVarObject,3.2, -type,PyWeakReference,3.2, -function,PyWeakref_GetObject,3.2, -function,PyWeakref_NewProxy,3.2, -function,PyWeakref_NewRef,3.2, -var,PyWrapperDescr_Type,3.2, -function,PyWrapper_New,3.2, -var,PyZip_Type,3.2, -function,Py_AddPendingCall,3.2, -function,Py_AtExit,3.2, -macro,Py_BEGIN_ALLOW_THREADS,3.2, -macro,Py_BLOCK_THREADS,3.2, -function,Py_BuildValue,3.2, -function,Py_BytesMain,3.8, -function,Py_CompileString,3.2, -function,Py_DecRef,3.2, -function,Py_DecodeLocale,3.7, -macro,Py_END_ALLOW_THREADS,3.2, -function,Py_EncodeLocale,3.7, -function,Py_EndInterpreter,3.2, -function,Py_EnterRecursiveCall,3.9, -function,Py_Exit,3.2, -function,Py_FatalError,3.2, -var,Py_FileSystemDefaultEncodeErrors,3.10, -var,Py_FileSystemDefaultEncoding,3.2, -function,Py_Finalize,3.2, -function,Py_FinalizeEx,3.6, -function,Py_GenericAlias,3.9, -var,Py_GenericAliasType,3.9, -function,Py_GetBuildInfo,3.2, -function,Py_GetCompiler,3.2, -function,Py_GetCopyright,3.2, -function,Py_GetExecPrefix,3.2, -function,Py_GetPath,3.2, -function,Py_GetPlatform,3.2, -function,Py_GetPrefix,3.2, -function,Py_GetProgramFullPath,3.2, -function,Py_GetProgramName,3.2, -function,Py_GetPythonHome,3.2, -function,Py_GetRecursionLimit,3.2, -function,Py_GetVersion,3.2, -var,Py_HasFileSystemDefaultEncoding,3.2, -function,Py_IncRef,3.2, -function,Py_Initialize,3.2, -function,Py_InitializeEx,3.2, -function,Py_Is,3.10, -function,Py_IsFalse,3.10, -function,Py_IsInitialized,3.2, -function,Py_IsNone,3.10, -function,Py_IsTrue,3.10, -function,Py_LeaveRecursiveCall,3.9, -function,Py_Main,3.2, -function,Py_MakePendingCalls,3.2, -function,Py_NewInterpreter,3.2, -function,Py_NewRef,3.10, -function,Py_ReprEnter,3.2, -function,Py_ReprLeave,3.2, -function,Py_SetPath,3.7, -function,Py_SetProgramName,3.2, -function,Py_SetPythonHome,3.2, -function,Py_SetRecursionLimit,3.2, -type,Py_UCS4,3.2, -macro,Py_UNBLOCK_THREADS,3.2, -var,Py_UTF8Mode,3.8, -function,Py_VaBuildValue,3.2, -function,Py_XNewRef,3.10, -type,Py_intptr_t,3.2, -type,Py_ssize_t,3.2, -type,Py_uintptr_t,3.2, -type,allocfunc,3.2, -type,binaryfunc,3.2, -type,descrgetfunc,3.2, -type,descrsetfunc,3.2, -type,destructor,3.2, -type,getattrfunc,3.2, -type,getattrofunc,3.2, -type,getiterfunc,3.2, -type,getter,3.2, -type,hashfunc,3.2, -type,initproc,3.2, -type,inquiry,3.2, -type,iternextfunc,3.2, -type,lenfunc,3.2, -type,newfunc,3.2, -type,objobjargproc,3.2, -type,objobjproc,3.2, -type,reprfunc,3.2, -type,richcmpfunc,3.2, -type,setattrfunc,3.2, -type,setattrofunc,3.2, -type,setter,3.2, -type,ssizeargfunc,3.2, -type,ssizeobjargproc,3.2, -type,ssizessizeargfunc,3.2, -type,ssizessizeobjargproc,3.2, -type,symtable,3.2, -type,ternaryfunc,3.2, -type,traverseproc,3.2, -type,unaryfunc,3.2, -type,visitproc,3.2, +role,name,added,ifdef_note,struct_abi_kind +function,PyAIter_Check,3.10,, +function,PyArg_Parse,3.2,, +function,PyArg_ParseTuple,3.2,, +function,PyArg_ParseTupleAndKeywords,3.2,, +function,PyArg_UnpackTuple,3.2,, +function,PyArg_VaParse,3.2,, +function,PyArg_VaParseTupleAndKeywords,3.2,, +function,PyArg_ValidateKeywordArguments,3.2,, +var,PyBaseObject_Type,3.2,, +function,PyBool_FromLong,3.2,, +var,PyBool_Type,3.2,, +var,PyByteArrayIter_Type,3.2,, +function,PyByteArray_AsString,3.2,, +function,PyByteArray_Concat,3.2,, +function,PyByteArray_FromObject,3.2,, +function,PyByteArray_FromStringAndSize,3.2,, +function,PyByteArray_Resize,3.2,, +function,PyByteArray_Size,3.2,, +var,PyByteArray_Type,3.2,, +var,PyBytesIter_Type,3.2,, +function,PyBytes_AsString,3.2,, +function,PyBytes_AsStringAndSize,3.2,, +function,PyBytes_Concat,3.2,, +function,PyBytes_ConcatAndDel,3.2,, +function,PyBytes_DecodeEscape,3.2,, +function,PyBytes_FromFormat,3.2,, +function,PyBytes_FromFormatV,3.2,, +function,PyBytes_FromObject,3.2,, +function,PyBytes_FromString,3.2,, +function,PyBytes_FromStringAndSize,3.2,, +function,PyBytes_Repr,3.2,, +function,PyBytes_Size,3.2,, +var,PyBytes_Type,3.2,, +type,PyCFunction,3.2,, +type,PyCFunctionWithKeywords,3.2,, +function,PyCFunction_Call,3.2,, +function,PyCFunction_GetFlags,3.2,, +function,PyCFunction_GetFunction,3.2,, +function,PyCFunction_GetSelf,3.2,, +function,PyCFunction_New,3.4,, +function,PyCFunction_NewEx,3.2,, +var,PyCFunction_Type,3.2,, +function,PyCMethod_New,3.9,, +function,PyCallIter_New,3.2,, +var,PyCallIter_Type,3.2,, +function,PyCallable_Check,3.2,, +type,PyCapsule_Destructor,3.2,, +function,PyCapsule_GetContext,3.2,, +function,PyCapsule_GetDestructor,3.2,, +function,PyCapsule_GetName,3.2,, +function,PyCapsule_GetPointer,3.2,, +function,PyCapsule_Import,3.2,, +function,PyCapsule_IsValid,3.2,, +function,PyCapsule_New,3.2,, +function,PyCapsule_SetContext,3.2,, +function,PyCapsule_SetDestructor,3.2,, +function,PyCapsule_SetName,3.2,, +function,PyCapsule_SetPointer,3.2,, +var,PyCapsule_Type,3.2,, +var,PyClassMethodDescr_Type,3.2,, +function,PyCodec_BackslashReplaceErrors,3.2,, +function,PyCodec_Decode,3.2,, +function,PyCodec_Decoder,3.2,, +function,PyCodec_Encode,3.2,, +function,PyCodec_Encoder,3.2,, +function,PyCodec_IgnoreErrors,3.2,, +function,PyCodec_IncrementalDecoder,3.2,, +function,PyCodec_IncrementalEncoder,3.2,, +function,PyCodec_KnownEncoding,3.2,, +function,PyCodec_LookupError,3.2,, +function,PyCodec_NameReplaceErrors,3.7,, +function,PyCodec_Register,3.2,, +function,PyCodec_RegisterError,3.2,, +function,PyCodec_ReplaceErrors,3.2,, +function,PyCodec_StreamReader,3.2,, +function,PyCodec_StreamWriter,3.2,, +function,PyCodec_StrictErrors,3.2,, +function,PyCodec_Unregister,3.10,, +function,PyCodec_XMLCharRefReplaceErrors,3.2,, +function,PyComplex_FromDoubles,3.2,, +function,PyComplex_ImagAsDouble,3.2,, +function,PyComplex_RealAsDouble,3.2,, +var,PyComplex_Type,3.2,, +function,PyDescr_NewClassMethod,3.2,, +function,PyDescr_NewGetSet,3.2,, +function,PyDescr_NewMember,3.2,, +function,PyDescr_NewMethod,3.2,, +var,PyDictItems_Type,3.2,, +var,PyDictIterItem_Type,3.2,, +var,PyDictIterKey_Type,3.2,, +var,PyDictIterValue_Type,3.2,, +var,PyDictKeys_Type,3.2,, +function,PyDictProxy_New,3.2,, +var,PyDictProxy_Type,3.2,, +var,PyDictRevIterItem_Type,3.8,, +var,PyDictRevIterKey_Type,3.8,, +var,PyDictRevIterValue_Type,3.8,, +var,PyDictValues_Type,3.2,, +function,PyDict_Clear,3.2,, +function,PyDict_Contains,3.2,, +function,PyDict_Copy,3.2,, +function,PyDict_DelItem,3.2,, +function,PyDict_DelItemString,3.2,, +function,PyDict_GetItem,3.2,, +function,PyDict_GetItemString,3.2,, +function,PyDict_GetItemWithError,3.2,, +function,PyDict_Items,3.2,, +function,PyDict_Keys,3.2,, +function,PyDict_Merge,3.2,, +function,PyDict_MergeFromSeq2,3.2,, +function,PyDict_New,3.2,, +function,PyDict_Next,3.2,, +function,PyDict_SetItem,3.2,, +function,PyDict_SetItemString,3.2,, +function,PyDict_Size,3.2,, +var,PyDict_Type,3.2,, +function,PyDict_Update,3.2,, +function,PyDict_Values,3.2,, +var,PyEllipsis_Type,3.2,, +var,PyEnum_Type,3.2,, +function,PyErr_BadArgument,3.2,, +function,PyErr_BadInternalCall,3.2,, +function,PyErr_CheckSignals,3.2,, +function,PyErr_Clear,3.2,, +function,PyErr_Display,3.2,, +function,PyErr_ExceptionMatches,3.2,, +function,PyErr_Fetch,3.2,, +function,PyErr_Format,3.2,, +function,PyErr_FormatV,3.5,, +function,PyErr_GetExcInfo,3.7,, +function,PyErr_GivenExceptionMatches,3.2,, +function,PyErr_NewException,3.2,, +function,PyErr_NewExceptionWithDoc,3.2,, +function,PyErr_NoMemory,3.2,, +function,PyErr_NormalizeException,3.2,, +function,PyErr_Occurred,3.2,, +function,PyErr_Print,3.2,, +function,PyErr_PrintEx,3.2,, +function,PyErr_ProgramText,3.2,, +function,PyErr_ResourceWarning,3.6,, +function,PyErr_Restore,3.2,, +function,PyErr_SetExcFromWindowsErr,3.7,on Windows, +function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows, +function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows, +function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows, +function,PyErr_SetExcInfo,3.7,, +function,PyErr_SetFromErrno,3.2,, +function,PyErr_SetFromErrnoWithFilename,3.2,, +function,PyErr_SetFromErrnoWithFilenameObject,3.2,, +function,PyErr_SetFromErrnoWithFilenameObjects,3.7,, +function,PyErr_SetFromWindowsErr,3.7,on Windows, +function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows, +function,PyErr_SetImportError,3.7,, +function,PyErr_SetImportErrorSubclass,3.6,, +function,PyErr_SetInterrupt,3.2,, +function,PyErr_SetInterruptEx,3.10,, +function,PyErr_SetNone,3.2,, +function,PyErr_SetObject,3.2,, +function,PyErr_SetString,3.2,, +function,PyErr_SyntaxLocation,3.2,, +function,PyErr_SyntaxLocationEx,3.7,, +function,PyErr_WarnEx,3.2,, +function,PyErr_WarnExplicit,3.2,, +function,PyErr_WarnFormat,3.2,, +function,PyErr_WriteUnraisable,3.2,, +function,PyEval_AcquireLock,3.2,, +function,PyEval_AcquireThread,3.2,, +function,PyEval_CallFunction,3.2,, +function,PyEval_CallMethod,3.2,, +function,PyEval_CallObjectWithKeywords,3.2,, +function,PyEval_EvalCode,3.2,, +function,PyEval_EvalCodeEx,3.2,, +function,PyEval_EvalFrame,3.2,, +function,PyEval_EvalFrameEx,3.2,, +function,PyEval_GetBuiltins,3.2,, +function,PyEval_GetFrame,3.2,, +function,PyEval_GetFuncDesc,3.2,, +function,PyEval_GetFuncName,3.2,, +function,PyEval_GetGlobals,3.2,, +function,PyEval_GetLocals,3.2,, +function,PyEval_InitThreads,3.2,, +function,PyEval_ReleaseLock,3.2,, +function,PyEval_ReleaseThread,3.2,, +function,PyEval_RestoreThread,3.2,, +function,PyEval_SaveThread,3.2,, +function,PyEval_ThreadsInitialized,3.2,, +var,PyExc_ArithmeticError,3.2,, +var,PyExc_AssertionError,3.2,, +var,PyExc_AttributeError,3.2,, +var,PyExc_BaseException,3.2,, +var,PyExc_BlockingIOError,3.7,, +var,PyExc_BrokenPipeError,3.7,, +var,PyExc_BufferError,3.2,, +var,PyExc_BytesWarning,3.2,, +var,PyExc_ChildProcessError,3.7,, +var,PyExc_ConnectionAbortedError,3.7,, +var,PyExc_ConnectionError,3.7,, +var,PyExc_ConnectionRefusedError,3.7,, +var,PyExc_ConnectionResetError,3.7,, +var,PyExc_DeprecationWarning,3.2,, +var,PyExc_EOFError,3.2,, +var,PyExc_EncodingWarning,3.10,, +var,PyExc_EnvironmentError,3.2,, +var,PyExc_Exception,3.2,, +var,PyExc_FileExistsError,3.7,, +var,PyExc_FileNotFoundError,3.7,, +var,PyExc_FloatingPointError,3.2,, +var,PyExc_FutureWarning,3.2,, +var,PyExc_GeneratorExit,3.2,, +var,PyExc_IOError,3.2,, +var,PyExc_ImportError,3.2,, +var,PyExc_ImportWarning,3.2,, +var,PyExc_IndentationError,3.2,, +var,PyExc_IndexError,3.2,, +var,PyExc_InterruptedError,3.7,, +var,PyExc_IsADirectoryError,3.7,, +var,PyExc_KeyError,3.2,, +var,PyExc_KeyboardInterrupt,3.2,, +var,PyExc_LookupError,3.2,, +var,PyExc_MemoryError,3.2,, +var,PyExc_ModuleNotFoundError,3.6,, +var,PyExc_NameError,3.2,, +var,PyExc_NotADirectoryError,3.7,, +var,PyExc_NotImplementedError,3.2,, +var,PyExc_OSError,3.2,, +var,PyExc_OverflowError,3.2,, +var,PyExc_PendingDeprecationWarning,3.2,, +var,PyExc_PermissionError,3.7,, +var,PyExc_ProcessLookupError,3.7,, +var,PyExc_RecursionError,3.7,, +var,PyExc_ReferenceError,3.2,, +var,PyExc_ResourceWarning,3.7,, +var,PyExc_RuntimeError,3.2,, +var,PyExc_RuntimeWarning,3.2,, +var,PyExc_StopAsyncIteration,3.7,, +var,PyExc_StopIteration,3.2,, +var,PyExc_SyntaxError,3.2,, +var,PyExc_SyntaxWarning,3.2,, +var,PyExc_SystemError,3.2,, +var,PyExc_SystemExit,3.2,, +var,PyExc_TabError,3.2,, +var,PyExc_TimeoutError,3.7,, +var,PyExc_TypeError,3.2,, +var,PyExc_UnboundLocalError,3.2,, +var,PyExc_UnicodeDecodeError,3.2,, +var,PyExc_UnicodeEncodeError,3.2,, +var,PyExc_UnicodeError,3.2,, +var,PyExc_UnicodeTranslateError,3.2,, +var,PyExc_UnicodeWarning,3.2,, +var,PyExc_UserWarning,3.2,, +var,PyExc_ValueError,3.2,, +var,PyExc_Warning,3.2,, +var,PyExc_WindowsError,3.7,on Windows, +var,PyExc_ZeroDivisionError,3.2,, +function,PyExceptionClass_Name,3.8,, +function,PyException_GetCause,3.2,, +function,PyException_GetContext,3.2,, +function,PyException_GetTraceback,3.2,, +function,PyException_SetCause,3.2,, +function,PyException_SetContext,3.2,, +function,PyException_SetTraceback,3.2,, +function,PyFile_FromFd,3.2,, +function,PyFile_GetLine,3.2,, +function,PyFile_WriteObject,3.2,, +function,PyFile_WriteString,3.2,, +var,PyFilter_Type,3.2,, +function,PyFloat_AsDouble,3.2,, +function,PyFloat_FromDouble,3.2,, +function,PyFloat_FromString,3.2,, +function,PyFloat_GetInfo,3.2,, +function,PyFloat_GetMax,3.2,, +function,PyFloat_GetMin,3.2,, +var,PyFloat_Type,3.2,, +type,PyFrameObject,3.2,,opaque +function,PyFrame_GetCode,3.10,, +function,PyFrame_GetLineNumber,3.10,, +function,PyFrozenSet_New,3.2,, +var,PyFrozenSet_Type,3.2,, +function,PyGC_Collect,3.2,, +function,PyGC_Disable,3.10,, +function,PyGC_Enable,3.10,, +function,PyGC_IsEnabled,3.10,, +function,PyGILState_Ensure,3.2,, +function,PyGILState_GetThisThreadState,3.2,, +function,PyGILState_Release,3.2,, +type,PyGILState_STATE,3.2,, +type,PyGetSetDef,3.2,,full-abi +var,PyGetSetDescr_Type,3.2,, +function,PyImport_AddModule,3.2,, +function,PyImport_AddModuleObject,3.7,, +function,PyImport_AppendInittab,3.2,, +function,PyImport_ExecCodeModule,3.2,, +function,PyImport_ExecCodeModuleEx,3.2,, +function,PyImport_ExecCodeModuleObject,3.7,, +function,PyImport_ExecCodeModuleWithPathnames,3.2,, +function,PyImport_GetImporter,3.2,, +function,PyImport_GetMagicNumber,3.2,, +function,PyImport_GetMagicTag,3.2,, +function,PyImport_GetModule,3.8,, +function,PyImport_GetModuleDict,3.2,, +function,PyImport_Import,3.2,, +function,PyImport_ImportFrozenModule,3.2,, +function,PyImport_ImportFrozenModuleObject,3.7,, +function,PyImport_ImportModule,3.2,, +function,PyImport_ImportModuleLevel,3.2,, +function,PyImport_ImportModuleLevelObject,3.7,, +function,PyImport_ImportModuleNoBlock,3.2,, +function,PyImport_ReloadModule,3.2,, +function,PyIndex_Check,3.8,, +type,PyInterpreterState,3.2,,opaque +function,PyInterpreterState_Clear,3.2,, +function,PyInterpreterState_Delete,3.2,, +function,PyInterpreterState_Get,3.9,, +function,PyInterpreterState_GetDict,3.8,, +function,PyInterpreterState_GetID,3.7,, +function,PyInterpreterState_New,3.2,, +function,PyIter_Check,3.8,, +function,PyIter_Next,3.2,, +function,PyIter_Send,3.10,, +var,PyListIter_Type,3.2,, +var,PyListRevIter_Type,3.2,, +function,PyList_Append,3.2,, +function,PyList_AsTuple,3.2,, +function,PyList_GetItem,3.2,, +function,PyList_GetSlice,3.2,, +function,PyList_Insert,3.2,, +function,PyList_New,3.2,, +function,PyList_Reverse,3.2,, +function,PyList_SetItem,3.2,, +function,PyList_SetSlice,3.2,, +function,PyList_Size,3.2,, +function,PyList_Sort,3.2,, +var,PyList_Type,3.2,, +type,PyLongObject,3.2,,opaque +var,PyLongRangeIter_Type,3.2,, +function,PyLong_AsDouble,3.2,, +function,PyLong_AsLong,3.2,, +function,PyLong_AsLongAndOverflow,3.2,, +function,PyLong_AsLongLong,3.2,, +function,PyLong_AsLongLongAndOverflow,3.2,, +function,PyLong_AsSize_t,3.2,, +function,PyLong_AsSsize_t,3.2,, +function,PyLong_AsUnsignedLong,3.2,, +function,PyLong_AsUnsignedLongLong,3.2,, +function,PyLong_AsUnsignedLongLongMask,3.2,, +function,PyLong_AsUnsignedLongMask,3.2,, +function,PyLong_AsVoidPtr,3.2,, +function,PyLong_FromDouble,3.2,, +function,PyLong_FromLong,3.2,, +function,PyLong_FromLongLong,3.2,, +function,PyLong_FromSize_t,3.2,, +function,PyLong_FromSsize_t,3.2,, +function,PyLong_FromString,3.2,, +function,PyLong_FromUnsignedLong,3.2,, +function,PyLong_FromUnsignedLongLong,3.2,, +function,PyLong_FromVoidPtr,3.2,, +function,PyLong_GetInfo,3.2,, +var,PyLong_Type,3.2,, +var,PyMap_Type,3.2,, +function,PyMapping_Check,3.2,, +function,PyMapping_GetItemString,3.2,, +function,PyMapping_HasKey,3.2,, +function,PyMapping_HasKeyString,3.2,, +function,PyMapping_Items,3.2,, +function,PyMapping_Keys,3.2,, +function,PyMapping_Length,3.2,, +function,PyMapping_SetItemString,3.2,, +function,PyMapping_Size,3.2,, +function,PyMapping_Values,3.2,, +function,PyMem_Calloc,3.7,, +function,PyMem_Free,3.2,, +function,PyMem_Malloc,3.2,, +function,PyMem_Realloc,3.2,, +type,PyMemberDef,3.2,,full-abi +var,PyMemberDescr_Type,3.2,, +function,PyMemoryView_FromMemory,3.7,, +function,PyMemoryView_FromObject,3.2,, +function,PyMemoryView_GetContiguous,3.2,, +var,PyMemoryView_Type,3.2,, +type,PyMethodDef,3.2,,full-abi +var,PyMethodDescr_Type,3.2,, +type,PyModuleDef,3.2,,full-abi +type,PyModuleDef_Base,3.2,,full-abi +function,PyModuleDef_Init,3.5,, +var,PyModuleDef_Type,3.5,, +function,PyModule_AddFunctions,3.7,, +function,PyModule_AddIntConstant,3.2,, +function,PyModule_AddObject,3.2,, +function,PyModule_AddObjectRef,3.10,, +function,PyModule_AddStringConstant,3.2,, +function,PyModule_AddType,3.10,, +function,PyModule_Create2,3.2,, +function,PyModule_ExecDef,3.7,, +function,PyModule_FromDefAndSpec2,3.7,, +function,PyModule_GetDef,3.2,, +function,PyModule_GetDict,3.2,, +function,PyModule_GetFilename,3.2,, +function,PyModule_GetFilenameObject,3.2,, +function,PyModule_GetName,3.2,, +function,PyModule_GetNameObject,3.7,, +function,PyModule_GetState,3.2,, +function,PyModule_New,3.2,, +function,PyModule_NewObject,3.7,, +function,PyModule_SetDocString,3.7,, +var,PyModule_Type,3.2,, +function,PyNumber_Absolute,3.2,, +function,PyNumber_Add,3.2,, +function,PyNumber_And,3.2,, +function,PyNumber_AsSsize_t,3.2,, +function,PyNumber_Check,3.2,, +function,PyNumber_Divmod,3.2,, +function,PyNumber_Float,3.2,, +function,PyNumber_FloorDivide,3.2,, +function,PyNumber_InPlaceAdd,3.2,, +function,PyNumber_InPlaceAnd,3.2,, +function,PyNumber_InPlaceFloorDivide,3.2,, +function,PyNumber_InPlaceLshift,3.2,, +function,PyNumber_InPlaceMatrixMultiply,3.7,, +function,PyNumber_InPlaceMultiply,3.2,, +function,PyNumber_InPlaceOr,3.2,, +function,PyNumber_InPlacePower,3.2,, +function,PyNumber_InPlaceRemainder,3.2,, +function,PyNumber_InPlaceRshift,3.2,, +function,PyNumber_InPlaceSubtract,3.2,, +function,PyNumber_InPlaceTrueDivide,3.2,, +function,PyNumber_InPlaceXor,3.2,, +function,PyNumber_Index,3.2,, +function,PyNumber_Invert,3.2,, +function,PyNumber_Long,3.2,, +function,PyNumber_Lshift,3.2,, +function,PyNumber_MatrixMultiply,3.7,, +function,PyNumber_Multiply,3.2,, +function,PyNumber_Negative,3.2,, +function,PyNumber_Or,3.2,, +function,PyNumber_Positive,3.2,, +function,PyNumber_Power,3.2,, +function,PyNumber_Remainder,3.2,, +function,PyNumber_Rshift,3.2,, +function,PyNumber_Subtract,3.2,, +function,PyNumber_ToBase,3.2,, +function,PyNumber_TrueDivide,3.2,, +function,PyNumber_Xor,3.2,, +function,PyOS_AfterFork,3.2,on platforms with fork(), +function,PyOS_AfterFork_Child,3.7,on platforms with fork(), +function,PyOS_AfterFork_Parent,3.7,on platforms with fork(), +function,PyOS_BeforeFork,3.7,on platforms with fork(), +function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK, +function,PyOS_FSPath,3.6,, +var,PyOS_InputHook,3.2,, +function,PyOS_InterruptOccurred,3.2,, +function,PyOS_double_to_string,3.2,, +function,PyOS_getsig,3.2,, +function,PyOS_mystricmp,3.2,, +function,PyOS_mystrnicmp,3.2,, +function,PyOS_setsig,3.2,, +type,PyOS_sighandler_t,3.2,, +function,PyOS_snprintf,3.2,, +function,PyOS_string_to_double,3.2,, +function,PyOS_strtol,3.2,, +function,PyOS_strtoul,3.2,, +function,PyOS_vsnprintf,3.2,, +type,PyObject,3.2,,members +member,PyObject.ob_refcnt,3.2,, +member,PyObject.ob_type,3.2,, +function,PyObject_ASCII,3.2,, +function,PyObject_AsCharBuffer,3.2,, +function,PyObject_AsFileDescriptor,3.2,, +function,PyObject_AsReadBuffer,3.2,, +function,PyObject_AsWriteBuffer,3.2,, +function,PyObject_Bytes,3.2,, +function,PyObject_Call,3.2,, +function,PyObject_CallFunction,3.2,, +function,PyObject_CallFunctionObjArgs,3.2,, +function,PyObject_CallMethod,3.2,, +function,PyObject_CallMethodObjArgs,3.2,, +function,PyObject_CallNoArgs,3.10,, +function,PyObject_CallObject,3.2,, +function,PyObject_Calloc,3.7,, +function,PyObject_CheckReadBuffer,3.2,, +function,PyObject_ClearWeakRefs,3.2,, +function,PyObject_DelItem,3.2,, +function,PyObject_DelItemString,3.2,, +function,PyObject_Dir,3.2,, +function,PyObject_Format,3.2,, +function,PyObject_Free,3.2,, +function,PyObject_GC_Del,3.2,, +function,PyObject_GC_IsFinalized,3.9,, +function,PyObject_GC_IsTracked,3.9,, +function,PyObject_GC_Track,3.2,, +function,PyObject_GC_UnTrack,3.2,, +function,PyObject_GenericGetAttr,3.2,, +function,PyObject_GenericGetDict,3.10,, +function,PyObject_GenericSetAttr,3.2,, +function,PyObject_GenericSetDict,3.7,, +function,PyObject_GetAIter,3.10,, +function,PyObject_GetAttr,3.2,, +function,PyObject_GetAttrString,3.2,, +function,PyObject_GetItem,3.2,, +function,PyObject_GetIter,3.2,, +function,PyObject_HasAttr,3.2,, +function,PyObject_HasAttrString,3.2,, +function,PyObject_Hash,3.2,, +function,PyObject_HashNotImplemented,3.2,, +function,PyObject_Init,3.2,, +function,PyObject_InitVar,3.2,, +function,PyObject_IsInstance,3.2,, +function,PyObject_IsSubclass,3.2,, +function,PyObject_IsTrue,3.2,, +function,PyObject_Length,3.2,, +function,PyObject_Malloc,3.2,, +function,PyObject_Not,3.2,, +function,PyObject_Realloc,3.2,, +function,PyObject_Repr,3.2,, +function,PyObject_RichCompare,3.2,, +function,PyObject_RichCompareBool,3.2,, +function,PyObject_SelfIter,3.2,, +function,PyObject_SetAttr,3.2,, +function,PyObject_SetAttrString,3.2,, +function,PyObject_SetItem,3.2,, +function,PyObject_Size,3.2,, +function,PyObject_Str,3.2,, +function,PyObject_Type,3.2,, +var,PyProperty_Type,3.2,, +var,PyRangeIter_Type,3.2,, +var,PyRange_Type,3.2,, +var,PyReversed_Type,3.2,, +function,PySeqIter_New,3.2,, +var,PySeqIter_Type,3.2,, +function,PySequence_Check,3.2,, +function,PySequence_Concat,3.2,, +function,PySequence_Contains,3.2,, +function,PySequence_Count,3.2,, +function,PySequence_DelItem,3.2,, +function,PySequence_DelSlice,3.2,, +function,PySequence_Fast,3.2,, +function,PySequence_GetItem,3.2,, +function,PySequence_GetSlice,3.2,, +function,PySequence_In,3.2,, +function,PySequence_InPlaceConcat,3.2,, +function,PySequence_InPlaceRepeat,3.2,, +function,PySequence_Index,3.2,, +function,PySequence_Length,3.2,, +function,PySequence_List,3.2,, +function,PySequence_Repeat,3.2,, +function,PySequence_SetItem,3.2,, +function,PySequence_SetSlice,3.2,, +function,PySequence_Size,3.2,, +function,PySequence_Tuple,3.2,, +var,PySetIter_Type,3.2,, +function,PySet_Add,3.2,, +function,PySet_Clear,3.2,, +function,PySet_Contains,3.2,, +function,PySet_Discard,3.2,, +function,PySet_New,3.2,, +function,PySet_Pop,3.2,, +function,PySet_Size,3.2,, +var,PySet_Type,3.2,, +function,PySlice_AdjustIndices,3.7,, +function,PySlice_GetIndices,3.2,, +function,PySlice_GetIndicesEx,3.2,, +function,PySlice_New,3.2,, +var,PySlice_Type,3.2,, +function,PySlice_Unpack,3.7,, +function,PyState_AddModule,3.3,, +function,PyState_FindModule,3.2,, +function,PyState_RemoveModule,3.3,, +type,PyStructSequence_Desc,3.2,,full-abi +type,PyStructSequence_Field,3.2,,full-abi +function,PyStructSequence_GetItem,3.2,, +function,PyStructSequence_New,3.2,, +function,PyStructSequence_NewType,3.2,, +function,PyStructSequence_SetItem,3.2,, +var,PySuper_Type,3.2,, +function,PySys_AddWarnOption,3.2,, +function,PySys_AddWarnOptionUnicode,3.2,, +function,PySys_AddXOption,3.7,, +function,PySys_FormatStderr,3.2,, +function,PySys_FormatStdout,3.2,, +function,PySys_GetObject,3.2,, +function,PySys_GetXOptions,3.7,, +function,PySys_HasWarnOptions,3.2,, +function,PySys_ResetWarnOptions,3.2,, +function,PySys_SetArgv,3.2,, +function,PySys_SetArgvEx,3.2,, +function,PySys_SetObject,3.2,, +function,PySys_SetPath,3.2,, +function,PySys_WriteStderr,3.2,, +function,PySys_WriteStdout,3.2,, +type,PyThreadState,3.2,,opaque +function,PyThreadState_Clear,3.2,, +function,PyThreadState_Delete,3.2,, +function,PyThreadState_Get,3.2,, +function,PyThreadState_GetDict,3.2,, +function,PyThreadState_GetFrame,3.10,, +function,PyThreadState_GetID,3.10,, +function,PyThreadState_GetInterpreter,3.10,, +function,PyThreadState_New,3.2,, +function,PyThreadState_SetAsyncExc,3.2,, +function,PyThreadState_Swap,3.2,, +function,PyThread_GetInfo,3.3,, +function,PyThread_ReInitTLS,3.2,, +function,PyThread_acquire_lock,3.2,, +function,PyThread_acquire_lock_timed,3.2,, +function,PyThread_allocate_lock,3.2,, +function,PyThread_create_key,3.2,, +function,PyThread_delete_key,3.2,, +function,PyThread_delete_key_value,3.2,, +function,PyThread_exit_thread,3.2,, +function,PyThread_free_lock,3.2,, +function,PyThread_get_key_value,3.2,, +function,PyThread_get_stacksize,3.2,, +function,PyThread_get_thread_ident,3.2,, +function,PyThread_get_thread_native_id,3.2,, +function,PyThread_init_thread,3.2,, +function,PyThread_release_lock,3.2,, +function,PyThread_set_key_value,3.2,, +function,PyThread_set_stacksize,3.2,, +function,PyThread_start_new_thread,3.2,, +function,PyThread_tss_alloc,3.7,, +function,PyThread_tss_create,3.7,, +function,PyThread_tss_delete,3.7,, +function,PyThread_tss_free,3.7,, +function,PyThread_tss_get,3.7,, +function,PyThread_tss_is_created,3.7,, +function,PyThread_tss_set,3.7,, +function,PyTraceBack_Here,3.2,, +function,PyTraceBack_Print,3.2,, +var,PyTraceBack_Type,3.2,, +var,PyTupleIter_Type,3.2,, +function,PyTuple_GetItem,3.2,, +function,PyTuple_GetSlice,3.2,, +function,PyTuple_New,3.2,, +function,PyTuple_Pack,3.2,, +function,PyTuple_SetItem,3.2,, +function,PyTuple_Size,3.2,, +var,PyTuple_Type,3.2,, +type,PyTypeObject,3.2,,opaque +function,PyType_ClearCache,3.2,, +function,PyType_FromModuleAndSpec,3.10,, +function,PyType_FromSpec,3.2,, +function,PyType_FromSpecWithBases,3.3,, +function,PyType_GenericAlloc,3.2,, +function,PyType_GenericNew,3.2,, +function,PyType_GetFlags,3.2,, +function,PyType_GetModule,3.10,, +function,PyType_GetModuleState,3.10,, +function,PyType_GetSlot,3.4,, +function,PyType_IsSubtype,3.2,, +function,PyType_Modified,3.2,, +function,PyType_Ready,3.2,, +type,PyType_Slot,3.2,,full-abi +type,PyType_Spec,3.2,,full-abi +var,PyType_Type,3.2,, +function,PyUnicodeDecodeError_Create,3.2,, +function,PyUnicodeDecodeError_GetEncoding,3.2,, +function,PyUnicodeDecodeError_GetEnd,3.2,, +function,PyUnicodeDecodeError_GetObject,3.2,, +function,PyUnicodeDecodeError_GetReason,3.2,, +function,PyUnicodeDecodeError_GetStart,3.2,, +function,PyUnicodeDecodeError_SetEnd,3.2,, +function,PyUnicodeDecodeError_SetReason,3.2,, +function,PyUnicodeDecodeError_SetStart,3.2,, +function,PyUnicodeEncodeError_GetEncoding,3.2,, +function,PyUnicodeEncodeError_GetEnd,3.2,, +function,PyUnicodeEncodeError_GetObject,3.2,, +function,PyUnicodeEncodeError_GetReason,3.2,, +function,PyUnicodeEncodeError_GetStart,3.2,, +function,PyUnicodeEncodeError_SetEnd,3.2,, +function,PyUnicodeEncodeError_SetReason,3.2,, +function,PyUnicodeEncodeError_SetStart,3.2,, +var,PyUnicodeIter_Type,3.2,, +function,PyUnicodeTranslateError_GetEnd,3.2,, +function,PyUnicodeTranslateError_GetObject,3.2,, +function,PyUnicodeTranslateError_GetReason,3.2,, +function,PyUnicodeTranslateError_GetStart,3.2,, +function,PyUnicodeTranslateError_SetEnd,3.2,, +function,PyUnicodeTranslateError_SetReason,3.2,, +function,PyUnicodeTranslateError_SetStart,3.2,, +function,PyUnicode_Append,3.2,, +function,PyUnicode_AppendAndDel,3.2,, +function,PyUnicode_AsASCIIString,3.2,, +function,PyUnicode_AsCharmapString,3.2,, +function,PyUnicode_AsDecodedObject,3.2,, +function,PyUnicode_AsDecodedUnicode,3.2,, +function,PyUnicode_AsEncodedObject,3.2,, +function,PyUnicode_AsEncodedString,3.2,, +function,PyUnicode_AsEncodedUnicode,3.2,, +function,PyUnicode_AsLatin1String,3.2,, +function,PyUnicode_AsMBCSString,3.7,on Windows, +function,PyUnicode_AsRawUnicodeEscapeString,3.2,, +function,PyUnicode_AsUCS4,3.7,, +function,PyUnicode_AsUCS4Copy,3.7,, +function,PyUnicode_AsUTF16String,3.2,, +function,PyUnicode_AsUTF32String,3.2,, +function,PyUnicode_AsUTF8AndSize,3.10,, +function,PyUnicode_AsUTF8String,3.2,, +function,PyUnicode_AsUnicodeEscapeString,3.2,, +function,PyUnicode_AsWideChar,3.2,, +function,PyUnicode_AsWideCharString,3.7,, +function,PyUnicode_BuildEncodingMap,3.2,, +function,PyUnicode_Compare,3.2,, +function,PyUnicode_CompareWithASCIIString,3.2,, +function,PyUnicode_Concat,3.2,, +function,PyUnicode_Contains,3.2,, +function,PyUnicode_Count,3.2,, +function,PyUnicode_Decode,3.2,, +function,PyUnicode_DecodeASCII,3.2,, +function,PyUnicode_DecodeCharmap,3.2,, +function,PyUnicode_DecodeCodePageStateful,3.7,on Windows, +function,PyUnicode_DecodeFSDefault,3.2,, +function,PyUnicode_DecodeFSDefaultAndSize,3.2,, +function,PyUnicode_DecodeLatin1,3.2,, +function,PyUnicode_DecodeLocale,3.7,, +function,PyUnicode_DecodeLocaleAndSize,3.7,, +function,PyUnicode_DecodeMBCS,3.7,on Windows, +function,PyUnicode_DecodeMBCSStateful,3.7,on Windows, +function,PyUnicode_DecodeRawUnicodeEscape,3.2,, +function,PyUnicode_DecodeUTF16,3.2,, +function,PyUnicode_DecodeUTF16Stateful,3.2,, +function,PyUnicode_DecodeUTF32,3.2,, +function,PyUnicode_DecodeUTF32Stateful,3.2,, +function,PyUnicode_DecodeUTF7,3.2,, +function,PyUnicode_DecodeUTF7Stateful,3.2,, +function,PyUnicode_DecodeUTF8,3.2,, +function,PyUnicode_DecodeUTF8Stateful,3.2,, +function,PyUnicode_DecodeUnicodeEscape,3.2,, +function,PyUnicode_EncodeCodePage,3.7,on Windows, +function,PyUnicode_EncodeFSDefault,3.2,, +function,PyUnicode_EncodeLocale,3.7,, +function,PyUnicode_FSConverter,3.2,, +function,PyUnicode_FSDecoder,3.2,, +function,PyUnicode_Find,3.2,, +function,PyUnicode_FindChar,3.7,, +function,PyUnicode_Format,3.2,, +function,PyUnicode_FromEncodedObject,3.2,, +function,PyUnicode_FromFormat,3.2,, +function,PyUnicode_FromFormatV,3.2,, +function,PyUnicode_FromObject,3.2,, +function,PyUnicode_FromOrdinal,3.2,, +function,PyUnicode_FromString,3.2,, +function,PyUnicode_FromStringAndSize,3.2,, +function,PyUnicode_FromWideChar,3.2,, +function,PyUnicode_GetDefaultEncoding,3.2,, +function,PyUnicode_GetLength,3.7,, +function,PyUnicode_GetSize,3.2,, +function,PyUnicode_InternFromString,3.2,, +function,PyUnicode_InternImmortal,3.2,, +function,PyUnicode_InternInPlace,3.2,, +function,PyUnicode_IsIdentifier,3.2,, +function,PyUnicode_Join,3.2,, +function,PyUnicode_Partition,3.2,, +function,PyUnicode_RPartition,3.2,, +function,PyUnicode_RSplit,3.2,, +function,PyUnicode_ReadChar,3.7,, +function,PyUnicode_Replace,3.2,, +function,PyUnicode_Resize,3.2,, +function,PyUnicode_RichCompare,3.2,, +function,PyUnicode_Split,3.2,, +function,PyUnicode_Splitlines,3.2,, +function,PyUnicode_Substring,3.7,, +function,PyUnicode_Tailmatch,3.2,, +function,PyUnicode_Translate,3.2,, +var,PyUnicode_Type,3.2,, +function,PyUnicode_WriteChar,3.7,, +type,PyVarObject,3.2,,members +member,PyVarObject.ob_base,3.2,, +member,PyVarObject.ob_size,3.2,, +type,PyWeakReference,3.2,,opaque +function,PyWeakref_GetObject,3.2,, +function,PyWeakref_NewProxy,3.2,, +function,PyWeakref_NewRef,3.2,, +var,PyWrapperDescr_Type,3.2,, +function,PyWrapper_New,3.2,, +var,PyZip_Type,3.2,, +function,Py_AddPendingCall,3.2,, +function,Py_AtExit,3.2,, +macro,Py_BEGIN_ALLOW_THREADS,3.2,, +macro,Py_BLOCK_THREADS,3.2,, +function,Py_BuildValue,3.2,, +function,Py_BytesMain,3.8,, +function,Py_CompileString,3.2,, +function,Py_DecRef,3.2,, +function,Py_DecodeLocale,3.7,, +macro,Py_END_ALLOW_THREADS,3.2,, +function,Py_EncodeLocale,3.7,, +function,Py_EndInterpreter,3.2,, +function,Py_EnterRecursiveCall,3.9,, +function,Py_Exit,3.2,, +function,Py_FatalError,3.2,, +var,Py_FileSystemDefaultEncodeErrors,3.10,, +var,Py_FileSystemDefaultEncoding,3.2,, +function,Py_Finalize,3.2,, +function,Py_FinalizeEx,3.6,, +function,Py_GenericAlias,3.9,, +var,Py_GenericAliasType,3.9,, +function,Py_GetBuildInfo,3.2,, +function,Py_GetCompiler,3.2,, +function,Py_GetCopyright,3.2,, +function,Py_GetExecPrefix,3.2,, +function,Py_GetPath,3.2,, +function,Py_GetPlatform,3.2,, +function,Py_GetPrefix,3.2,, +function,Py_GetProgramFullPath,3.2,, +function,Py_GetProgramName,3.2,, +function,Py_GetPythonHome,3.2,, +function,Py_GetRecursionLimit,3.2,, +function,Py_GetVersion,3.2,, +var,Py_HasFileSystemDefaultEncoding,3.2,, +function,Py_IncRef,3.2,, +function,Py_Initialize,3.2,, +function,Py_InitializeEx,3.2,, +function,Py_Is,3.10,, +function,Py_IsFalse,3.10,, +function,Py_IsInitialized,3.2,, +function,Py_IsNone,3.10,, +function,Py_IsTrue,3.10,, +function,Py_LeaveRecursiveCall,3.9,, +function,Py_Main,3.2,, +function,Py_MakePendingCalls,3.2,, +function,Py_NewInterpreter,3.2,, +function,Py_NewRef,3.10,, +function,Py_ReprEnter,3.2,, +function,Py_ReprLeave,3.2,, +function,Py_SetPath,3.7,, +function,Py_SetProgramName,3.2,, +function,Py_SetPythonHome,3.2,, +function,Py_SetRecursionLimit,3.2,, +type,Py_UCS4,3.2,, +macro,Py_UNBLOCK_THREADS,3.2,, +var,Py_UTF8Mode,3.8,, +function,Py_VaBuildValue,3.2,, +function,Py_XNewRef,3.10,, +type,Py_intptr_t,3.2,, +type,Py_ssize_t,3.2,, +type,Py_uintptr_t,3.2,, +type,allocfunc,3.2,, +type,binaryfunc,3.2,, +type,descrgetfunc,3.2,, +type,descrsetfunc,3.2,, +type,destructor,3.2,, +type,getattrfunc,3.2,, +type,getattrofunc,3.2,, +type,getiterfunc,3.2,, +type,getter,3.2,, +type,hashfunc,3.2,, +type,initproc,3.2,, +type,inquiry,3.2,, +type,iternextfunc,3.2,, +type,lenfunc,3.2,, +type,newfunc,3.2,, +type,objobjargproc,3.2,, +type,objobjproc,3.2,, +type,reprfunc,3.2,, +type,richcmpfunc,3.2,, +type,setattrfunc,3.2,, +type,setattrofunc,3.2,, +type,setter,3.2,, +type,ssizeargfunc,3.2,, +type,ssizeobjargproc,3.2,, +type,ssizessizeargfunc,3.2,, +type,ssizessizeobjargproc,3.2,, +type,symtable,3.2,,opaque +type,ternaryfunc,3.2,, +type,traverseproc,3.2,, +type,unaryfunc,3.2,, +type,visitproc,3.2,, diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py index 489f06613eb3..9defb24a0331 100644 --- a/Doc/tools/extensions/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -36,6 +36,7 @@ 'type': 'type', 'macro': 'macro', 'type': 'type', + 'member': 'member', } @@ -100,6 +101,12 @@ def add_annotations(self, app, doctree): # Stable ABI annotation. These have two forms: # Part of the [Stable ABI](link). # Part of the [Stable ABI](link) since version X.Y. + # For structs, there's some more info in the message: + # Part of the [Limited API](link) (as an opaque struct). + # Part of the [Stable ABI](link) (including all members). + # Part of the [Limited API](link) (Only some members are part + # of the stable ABI.). + # ... all of which can have "since version X.Y" appended. record = self.stable_abi_data.get(name) if record: if record['role'] != objtype: @@ -113,15 +120,27 @@ def add_annotations(self, app, doctree): ref_node = addnodes.pending_xref( 'Stable ABI', refdomain="std", reftarget='stable', reftype='ref', refexplicit="False") - ref_node += nodes.Text('Stable ABI') + struct_abi_kind = record['struct_abi_kind'] + if struct_abi_kind in {'opaque', 'members'}: + ref_node += nodes.Text('Limited API') + else: + ref_node += nodes.Text('Stable ABI') emph_node += ref_node + if struct_abi_kind == 'opaque': + emph_node += nodes.Text(' (as an opaque struct)') + elif struct_abi_kind == 'full-abi': + emph_node += nodes.Text(' (including all members)') if record['ifdef_note']: emph_node += nodes.Text(' ' + record['ifdef_note']) if stable_added == '3.2': # Stable ABI was introduced in 3.2. - emph_node += nodes.Text('.') + pass else: - emph_node += nodes.Text(f' since version {stable_added}.') + emph_node += nodes.Text(f' since version {stable_added}') + emph_node += nodes.Text('.') + if struct_abi_kind == 'members': + emph_node += nodes.Text( + ' (Only some members are part of the stable ABI.)') node.insert(0, emph_node) # Return value annotation diff --git a/Misc/NEWS.d/next/Documentation/2022-03-30-17-08-12.bpo-47115.R3wt3i.rst b/Misc/NEWS.d/next/Documentation/2022-03-30-17-08-12.bpo-47115.R3wt3i.rst new file mode 100644 index 000000000000..ac7b6dcb32d5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-30-17-08-12.bpo-47115.R3wt3i.rst @@ -0,0 +1,2 @@ +The documentation now lists which members of C structs are part of the +:ref:`Limited API/Stable ABI <stable>`. diff --git a/Misc/stable_abi.txt b/Misc/stable_abi.txt index 4a2ee18e8e97..095ee7374b6f 100644 --- a/Misc/stable_abi.txt +++ b/Misc/stable_abi.txt @@ -10,44 +10,111 @@ # and PC/pythonXYstub.def +# The current format is a simple line-based one with significant indentation. +# Anything after a hash is a comment. + +# There are these kinds of top-level "items": +# - struct: A C struct. Currently this file does not distinguish between: +# - opaque structs, which the Limited API only handles via pointers +# (so these can change at any time) +# - structs where only certain members are part of the stable ABI (e.g. +# PyObject) +# - structs which must not be changed at all (e.g. PyType_Slot, which is +# fully defined and used in arrays) +# - function: A function that must be kept available (and exported, i.e. not +# converted to a macro). +# - const: A simple value, defined with `#define`. +# - macro: A preprocessor macro more complex than a simple `const` value. +# - data: An exported object, which must continue to be available but its exact +# value may change. +# - typedef: A C typedef which is used in other definitions in the limited API. +# Its size/layout/signature must not change. + +# Each top-level item can have details defined below it: +# - added: The version in which the item was added to the stable ABI. +# - ifdef: A feature macro: the item is only available if this macro is defined +# - abi_only: If present, the item is not part of the Limited API, but it *is* +# part of the stable ABI. The item will not show up in user-facing docs. +# Typically used for: +# - private functions called by public macros, e.g. _Py_BuildValue_SizeT +# - items that were part of the limited API in the past, and must remain part +# of the stable ABI. +# - a combination of the above (functions that were called by macros that +# were public in the past) + +# For structs, one of the following must be set: +# - opaque: The struct name is available in the Limited API, but its members +# are not. Users must manipulate it via pointers. +# - members: Space-separated list of members which are part of the +# Limited API and Stable ABI. +# Members that aren't listed are not accessible to applications. +# - full-abi: The entire struct -- all its members and its size -- is part of +# the Stable ABI, and must not change. + +# Removing items from this file is generally not allowed, and additions should +# be considered with that in mind. See the devguide for exact rules: +# https://devguide.python.org/c-api/#limited-api + +# User-facing docs are at: +# https://docs.python.org/3/c-api/stable.html#stable + + # Mentioned in PEP 384: struct PyObject added 3.2 + members ob_refcnt ob_type struct PyVarObject added 3.2 + members ob_base ob_size struct PyMethodDef added 3.2 + full-abi struct PyMemberDef added 3.2 + full-abi struct PyGetSetDef added 3.2 + full-abi struct PyModuleDef_Base added 3.2 + full-abi struct PyModuleDef added 3.2 + full-abi struct PyStructSequence_Field added 3.2 + full-abi struct PyStructSequence_Desc added 3.2 + full-abi struct PyType_Slot added 3.2 + full-abi struct PyType_Spec added 3.2 + full-abi struct PyThreadState added 3.2 + opaque struct PyInterpreterState added 3.2 + opaque struct PyFrameObject added 3.2 + opaque struct symtable added 3.2 + opaque struct PyWeakReference added 3.2 + opaque struct PyLongObject added 3.2 + opaque struct PyTypeObject added 3.2 + opaque function PyType_FromSpec added 3.2 @@ -259,11 +326,11 @@ typedef newfunc added 3.2 typedef allocfunc added 3.2 -struct PyCFunction +typedef PyCFunction added 3.2 -struct PyCFunctionWithKeywords +typedef PyCFunctionWithKeywords added 3.2 -struct PyCapsule_Destructor +typedef PyCapsule_Destructor added 3.2 typedef getter added 3.2 diff --git a/Tools/scripts/stable_abi.py b/Tools/scripts/stable_abi.py index 6d7034090f88..2820efdb44fb 100755 --- a/Tools/scripts/stable_abi.py +++ b/Tools/scripts/stable_abi.py @@ -119,6 +119,8 @@ class ABIItem: contents: list = dataclasses.field(default_factory=list) abi_only: bool = False ifdef: str = None + struct_abi_kind: str = None + members: list = None KINDS = frozenset({ 'struct', 'function', 'macro', 'data', 'const', 'typedef', @@ -173,6 +175,15 @@ def raise_error(msg): if parent.kind not in {'function', 'data'}: raise_error(f'{kind} cannot go in {parent.kind}') parent.abi_only = True + elif kind in {'members', 'full-abi', 'opaque'}: + if parent.kind not in {'struct'}: + raise_error(f'{kind} cannot go in {parent.kind}') + if prev := getattr(parent, 'struct_abi_kind', None): + raise_error( + f'{parent.name} already has {prev}, cannot add {kind}') + parent.struct_abi_kind = kind + if kind == 'members': + parent.members = content.split() else: raise_error(f"unknown kind {kind!r}") levels.append((entry, level)) @@ -246,7 +257,9 @@ def sort_key(item): def gen_doc_annotations(manifest, args, outfile): """Generate/check the stable ABI list for documentation annotations""" writer = csv.DictWriter( - outfile, ['role', 'name', 'added', 'ifdef_note'], lineterminator='\n') + outfile, + ['role', 'name', 'added', 'ifdef_note', 'struct_abi_kind'], + lineterminator='\n') writer.writeheader() for item in manifest.select(REST_ROLES.keys(), include_abi_only=False): if item.ifdef: @@ -257,7 +270,13 @@ def gen_doc_annotations(manifest, args, outfile): 'role': REST_ROLES[item.kind], 'name': item.name, 'added': item.added, - 'ifdef_note': ifdef_note}) + 'ifdef_note': ifdef_note, + 'struct_abi_kind': item.struct_abi_kind}) + for member_name in item.members or (): + writer.writerow({ + 'role': 'member', + 'name': f'{item.name}.{member_name}', + 'added': item.added}) def generate_or_check(manifest, args, path, func): """Generate/check a file with a single generator From webhook-mailer at python.org Fri Aug 5 12:21:50 2022 From: webhook-mailer at python.org (terryjreedy) Date: Fri, 05 Aug 2022 16:21:50 -0000 Subject: [Python-checkins] gh-89362: Doc IDLE menu and search (#95697) Message-ID: <mailman.538.1659716512.3313.python-checkins@python.org> https://github.com/python/cpython/commit/834064c19a110dad425dc290c91c0545eaa24471 commit: 834064c19a110dad425dc290c91c0545eaa24471 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-05T12:21:45-04:00 summary: gh-89362: Doc IDLE menu and search (#95697) Update menu item position and capitalization. Add paragraph about search. For help.html, include save-as addition. files: M Doc/library/idle.rst M Lib/idlelib/help.html diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 2d52e5355749..f2ef72d682bd 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -61,17 +61,17 @@ New File Open... Open an existing file with an Open dialog. -Recent Files - Open a list of recent files. Click one to open it. - Open Module... Open an existing module (searches sys.path). +Recent Files + Open a list of recent files. Click one to open it. + .. index:: - single: Class browser + single: Module browser single: Path browser -Class Browser +Module Browser Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first. @@ -89,7 +89,7 @@ Save As... Save the current window with a Save As dialog. The file saved becomes the new associated file for the window. (If your file namager is set to hide extensions, the current extension will be omitted in the file name box. - If the new filename has no '.', '.py' and .'txt' will be added for Python + If the new filename has no '.', '.py' and '.txt' will be added for Python and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... @@ -117,6 +117,9 @@ Undo Redo Redo the last undone change to the current window. +Select All + Select the entire contents of the current window. + Cut Copy selection into the system-wide clipboard; then delete the selection. @@ -128,9 +131,6 @@ Paste The clipboard functions are also available in context menus. -Select All - Select the entire contents of the current window. - Find... Open a search dialog with many options @@ -159,12 +159,12 @@ Expand Word Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion. -Show call tip +Show Call Tip After an unclosed parenthesis for a function, open a small window with function parameter hints. See :ref:`Calltips <calltips>` in the Editing and navigation section below. -Show surrounding parens +Show Surrounding Parens Highlight the surrounding parenthesis. .. _format-menu: @@ -172,6 +172,11 @@ Show surrounding parens Format menu (Editor window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Format Paragraph + Reformat the current blank-line-delimited paragraph in comment block or + multiline string or selected line in a string. All lines in the + paragraph will be formatted to less than N columns, where N defaults to 72. + Indent Region Shift selected lines right by the indent width (default 4 spaces). @@ -198,12 +203,7 @@ New Indent Width Open a dialog to change indent width. The accepted default by the Python community is 4 spaces. -Format Paragraph - Reformat the current blank-line-delimited paragraph in comment block or - multiline string or selected line in a string. All lines in the - paragraph will be formatted to less than N columns, where N defaults to 72. - -Strip trailing whitespace +Strip Trailing Chitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, @@ -474,6 +474,14 @@ are restricted to four spaces due to Tcl/Tk limitations. See also the indent/dedent region commands on the :ref:`Format menu <format-menu>`. +Search and Replace +^^^^^^^^^^^^^^^^^^ + +Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If ``[x] Regular expresion`` is checked, the +target is interpreted according to the Python re module. + .. _completions: Completions diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index e8e7d2876097..ac386122cc71 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -91,6 +91,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#editor-windows">Editor windows</a></li> <li><a class="reference internal" href="#key-bindings">Key bindings</a></li> <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li> +<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li> <li><a class="reference internal" href="#completions">Completions</a></li> <li><a class="reference internal" href="#calltips">Calltips</a></li> <li><a class="reference internal" href="#code-context">Code Context</a></li> @@ -237,13 +238,13 @@ <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and </dd> <dt>Open?</dt><dd><p>Open an existing file with an Open dialog.</p> </dd> -<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p> -</dd> <dt>Open Module?</dt><dd><p>Open an existing module (searches sys.path).</p> </dd> +<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p> +</dd> </dl> <dl class="simple" id="index-1"> -<dt>Class Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a +<dt>Module Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first.</p> </dd> <dt>Path Browser</dt><dd><p>Show sys.path directories, modules, functions, classes and methods in a @@ -255,10 +256,13 @@ <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and do Save As instead.</p> </dd> <dt>Save As?</dt><dd><p>Save the current window with a Save As dialog. The file saved becomes the -new associated file for the window.</p> +new associated file for the window. (If your file namager is set to hide +extensions, the current extension will be omitted in the file name box. +If the new filename has no ?.?, ?.py? and ?.txt? will be added for Python +and text files, except that on macOS Aqua,?.py? is added for all files.)</p> </dd> <dt>Save Copy As?</dt><dd><p>Save the current window to different file without changing the associated -file.</p> +file. (See Save As note above about filename extensions.)</p> </dd> <dt>Print Window</dt><dd><p>Print the current window to the default printer.</p> </dd> @@ -278,6 +282,8 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and </dd> <dt>Redo</dt><dd><p>Redo the last undone change to the current window.</p> </dd> +<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p> +</dd> <dt>Cut</dt><dd><p>Copy selection into the system-wide clipboard; then delete the selection.</p> </dd> <dt>Copy</dt><dd><p>Copy selection into the system-wide clipboard.</p> @@ -287,8 +293,6 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and </dl> <p>The clipboard functions are also available in context menus.</p> <dl class="simple"> -<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p> -</dd> <dt>Find?</dt><dd><p>Open a search dialog with many options</p> </dd> <dt>Find Again</dt><dd><p>Repeat the last search, if there is one.</p> @@ -309,17 +313,21 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and <dt>Expand Word</dt><dd><p>Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion.</p> </dd> -<dt>Show call tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with +<dt>Show Call Tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with function parameter hints. See <a class="reference internal" href="#calltips"><span class="std std-ref">Calltips</span></a> in the Editing and navigation section below.</p> </dd> -<dt>Show surrounding parens</dt><dd><p>Highlight the surrounding parenthesis.</p> +<dt>Show Surrounding Parens</dt><dd><p>Highlight the surrounding parenthesis.</p> </dd> </dl> </section> <section id="format-menu-editor-window-only"> <span id="format-menu"></span><h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this heading">?</a></h3> <dl class="simple"> +<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or +multiline string or selected line in a string. All lines in the +paragraph will be formatted to less than N columns, where N defaults to 72.</p> +</dd> <dt>Indent Region</dt><dd><p>Shift selected lines right by the indent width (default 4 spaces).</p> </dd> <dt>Dedent Region</dt><dd><p>Shift selected lines left by the indent width (default 4 spaces).</p> @@ -338,11 +346,7 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and <dt>New Indent Width</dt><dd><p>Open a dialog to change indent width. The accepted default by the Python community is 4 spaces.</p> </dd> -<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or -multiline string or selected line in a string. All lines in the -paragraph will be formatted to less than N columns, where N defaults to 72.</p> -</dd> -<dt>Strip trailing whitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last +<dt>Strip Trailing Chitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, remove extra newlines at the end of the file.</p> @@ -565,6 +569,13 @@ <h3>Automatic indentation<a class="headerlink" href="#automatic-indentation" tit <p>See also the indent/dedent region commands on the <a class="reference internal" href="#format-menu"><span class="std std-ref">Format menu</span></a>.</p> </section> +<section id="search-and-replace"> +<h3>Search and Replace<a class="headerlink" href="#search-and-replace" title="Permalink to this heading">?</a></h3> +<p>Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If <code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">Regular</span> <span class="pre">expresion</span></code> is checked, the +target is interpreted according to the Python re module.</p> +</section> <section id="completions"> <span id="id3"></span><h3>Completions<a class="headerlink" href="#completions" title="Permalink to this heading">?</a></h3> <p>Completions are supplied, when requested and available, for module @@ -1021,6 +1032,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#editor-windows">Editor windows</a></li> <li><a class="reference internal" href="#key-bindings">Key bindings</a></li> <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li> +<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li> <li><a class="reference internal" href="#completions">Completions</a></li> <li><a class="reference internal" href="#calltips">Calltips</a></li> <li><a class="reference internal" href="#code-context">Code Context</a></li> @@ -1141,7 +1153,7 @@ <h3>Navigation</h3> <br /> <br /> - Last updated on Jul 03, 2022. + Last updated on Aug 05, 2022. <a href="/bugs.html">Found a bug</a>? <br /> From webhook-mailer at python.org Fri Aug 5 12:51:58 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 05 Aug 2022 16:51:58 -0000 Subject: [Python-checkins] gh-89362: Doc IDLE menu and search (GH-95697) Message-ID: <mailman.539.1659718318.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7c711aecf669dacba17df1dd064d2d0a68d35bd7 commit: 7c711aecf669dacba17df1dd064d2d0a68d35bd7 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-05T09:51:53-07:00 summary: gh-89362: Doc IDLE menu and search (GH-95697) Update menu item position and capitalization. Add paragraph about search. For help.html, include save-as addition. (cherry picked from commit 834064c19a110dad425dc290c91c0545eaa24471) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/library/idle.rst M Lib/idlelib/help.html diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 2d52e5355749..f2ef72d682bd 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -61,17 +61,17 @@ New File Open... Open an existing file with an Open dialog. -Recent Files - Open a list of recent files. Click one to open it. - Open Module... Open an existing module (searches sys.path). +Recent Files + Open a list of recent files. Click one to open it. + .. index:: - single: Class browser + single: Module browser single: Path browser -Class Browser +Module Browser Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first. @@ -89,7 +89,7 @@ Save As... Save the current window with a Save As dialog. The file saved becomes the new associated file for the window. (If your file namager is set to hide extensions, the current extension will be omitted in the file name box. - If the new filename has no '.', '.py' and .'txt' will be added for Python + If the new filename has no '.', '.py' and '.txt' will be added for Python and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... @@ -117,6 +117,9 @@ Undo Redo Redo the last undone change to the current window. +Select All + Select the entire contents of the current window. + Cut Copy selection into the system-wide clipboard; then delete the selection. @@ -128,9 +131,6 @@ Paste The clipboard functions are also available in context menus. -Select All - Select the entire contents of the current window. - Find... Open a search dialog with many options @@ -159,12 +159,12 @@ Expand Word Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion. -Show call tip +Show Call Tip After an unclosed parenthesis for a function, open a small window with function parameter hints. See :ref:`Calltips <calltips>` in the Editing and navigation section below. -Show surrounding parens +Show Surrounding Parens Highlight the surrounding parenthesis. .. _format-menu: @@ -172,6 +172,11 @@ Show surrounding parens Format menu (Editor window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Format Paragraph + Reformat the current blank-line-delimited paragraph in comment block or + multiline string or selected line in a string. All lines in the + paragraph will be formatted to less than N columns, where N defaults to 72. + Indent Region Shift selected lines right by the indent width (default 4 spaces). @@ -198,12 +203,7 @@ New Indent Width Open a dialog to change indent width. The accepted default by the Python community is 4 spaces. -Format Paragraph - Reformat the current blank-line-delimited paragraph in comment block or - multiline string or selected line in a string. All lines in the - paragraph will be formatted to less than N columns, where N defaults to 72. - -Strip trailing whitespace +Strip Trailing Chitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, @@ -474,6 +474,14 @@ are restricted to four spaces due to Tcl/Tk limitations. See also the indent/dedent region commands on the :ref:`Format menu <format-menu>`. +Search and Replace +^^^^^^^^^^^^^^^^^^ + +Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If ``[x] Regular expresion`` is checked, the +target is interpreted according to the Python re module. + .. _completions: Completions diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index e8e7d2876097..ac386122cc71 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -91,6 +91,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#editor-windows">Editor windows</a></li> <li><a class="reference internal" href="#key-bindings">Key bindings</a></li> <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li> +<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li> <li><a class="reference internal" href="#completions">Completions</a></li> <li><a class="reference internal" href="#calltips">Calltips</a></li> <li><a class="reference internal" href="#code-context">Code Context</a></li> @@ -237,13 +238,13 @@ <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and </dd> <dt>Open?</dt><dd><p>Open an existing file with an Open dialog.</p> </dd> -<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p> -</dd> <dt>Open Module?</dt><dd><p>Open an existing module (searches sys.path).</p> </dd> +<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p> +</dd> </dl> <dl class="simple" id="index-1"> -<dt>Class Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a +<dt>Module Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first.</p> </dd> <dt>Path Browser</dt><dd><p>Show sys.path directories, modules, functions, classes and methods in a @@ -255,10 +256,13 @@ <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and do Save As instead.</p> </dd> <dt>Save As?</dt><dd><p>Save the current window with a Save As dialog. The file saved becomes the -new associated file for the window.</p> +new associated file for the window. (If your file namager is set to hide +extensions, the current extension will be omitted in the file name box. +If the new filename has no ?.?, ?.py? and ?.txt? will be added for Python +and text files, except that on macOS Aqua,?.py? is added for all files.)</p> </dd> <dt>Save Copy As?</dt><dd><p>Save the current window to different file without changing the associated -file.</p> +file. (See Save As note above about filename extensions.)</p> </dd> <dt>Print Window</dt><dd><p>Print the current window to the default printer.</p> </dd> @@ -278,6 +282,8 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and </dd> <dt>Redo</dt><dd><p>Redo the last undone change to the current window.</p> </dd> +<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p> +</dd> <dt>Cut</dt><dd><p>Copy selection into the system-wide clipboard; then delete the selection.</p> </dd> <dt>Copy</dt><dd><p>Copy selection into the system-wide clipboard.</p> @@ -287,8 +293,6 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and </dl> <p>The clipboard functions are also available in context menus.</p> <dl class="simple"> -<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p> -</dd> <dt>Find?</dt><dd><p>Open a search dialog with many options</p> </dd> <dt>Find Again</dt><dd><p>Repeat the last search, if there is one.</p> @@ -309,17 +313,21 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and <dt>Expand Word</dt><dd><p>Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion.</p> </dd> -<dt>Show call tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with +<dt>Show Call Tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with function parameter hints. See <a class="reference internal" href="#calltips"><span class="std std-ref">Calltips</span></a> in the Editing and navigation section below.</p> </dd> -<dt>Show surrounding parens</dt><dd><p>Highlight the surrounding parenthesis.</p> +<dt>Show Surrounding Parens</dt><dd><p>Highlight the surrounding parenthesis.</p> </dd> </dl> </section> <section id="format-menu-editor-window-only"> <span id="format-menu"></span><h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this heading">?</a></h3> <dl class="simple"> +<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or +multiline string or selected line in a string. All lines in the +paragraph will be formatted to less than N columns, where N defaults to 72.</p> +</dd> <dt>Indent Region</dt><dd><p>Shift selected lines right by the indent width (default 4 spaces).</p> </dd> <dt>Dedent Region</dt><dd><p>Shift selected lines left by the indent width (default 4 spaces).</p> @@ -338,11 +346,7 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and <dt>New Indent Width</dt><dd><p>Open a dialog to change indent width. The accepted default by the Python community is 4 spaces.</p> </dd> -<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or -multiline string or selected line in a string. All lines in the -paragraph will be formatted to less than N columns, where N defaults to 72.</p> -</dd> -<dt>Strip trailing whitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last +<dt>Strip Trailing Chitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, remove extra newlines at the end of the file.</p> @@ -565,6 +569,13 @@ <h3>Automatic indentation<a class="headerlink" href="#automatic-indentation" tit <p>See also the indent/dedent region commands on the <a class="reference internal" href="#format-menu"><span class="std std-ref">Format menu</span></a>.</p> </section> +<section id="search-and-replace"> +<h3>Search and Replace<a class="headerlink" href="#search-and-replace" title="Permalink to this heading">?</a></h3> +<p>Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If <code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">Regular</span> <span class="pre">expresion</span></code> is checked, the +target is interpreted according to the Python re module.</p> +</section> <section id="completions"> <span id="id3"></span><h3>Completions<a class="headerlink" href="#completions" title="Permalink to this heading">?</a></h3> <p>Completions are supplied, when requested and available, for module @@ -1021,6 +1032,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#editor-windows">Editor windows</a></li> <li><a class="reference internal" href="#key-bindings">Key bindings</a></li> <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li> +<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li> <li><a class="reference internal" href="#completions">Completions</a></li> <li><a class="reference internal" href="#calltips">Calltips</a></li> <li><a class="reference internal" href="#code-context">Code Context</a></li> @@ -1141,7 +1153,7 @@ <h3>Navigation</h3> <br /> <br /> - Last updated on Jul 03, 2022. + Last updated on Aug 05, 2022. <a href="/bugs.html">Found a bug</a>? <br /> From webhook-mailer at python.org Fri Aug 5 17:15:33 2022 From: webhook-mailer at python.org (terryjreedy) Date: Fri, 05 Aug 2022 21:15:33 -0000 Subject: [Python-checkins] gh-95251: IDLE - Add What's New section to README (#95688) Message-ID: <mailman.540.1659734135.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a302a274892f2dad4e1fa492c4886d55e4df0a80 commit: a302a274892f2dad4e1fa492c4886d55e4df0a80 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-05T17:15:18-04:00 summary: gh-95251: IDLE - Add What's New section to README (#95688) Document what I (TJR) currently do for 3.10/3.11. Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 67de2be26256..779b51c1b931 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -243,8 +243,8 @@ OTHER TOPICS Generally use PEP 8. -import ------- +import statements +----------------- Put imports at the top, unless there is a good reason otherwise. PEP 8 says to group stdlib, 3rd-party dependencies, and package imports. For idlelib, the groups are general stdlib, tkinter, and idlelib. @@ -259,3 +259,24 @@ htest function def or "if __name__ == '__main__'" clause. Within module imports like "from idlelib.mod import class" may cause circular imports to deadlock. Even without this, circular imports may require at least one of the imports to be delayed until a function call. + +What's New entries +------------------ + +Repository directory Doc/whatsnew/ has a file 3.n.rst for each 3.n +Python version. For the first entry in each file, add subsection +'IDLE and idlelib', in alphabetical position, to the 'Improved Modules' +section. For the rest of cpython, entries to 3.(n+1).rst begin with +the release of 3.n.0b1. For IDLE, entries for features backported from +'main' to '3.n' during its beta period do not got in 3.(n+1).rst. The +latter usually gets its first entry during the 3.n.0 candidate period +or after the 3.n.0 release. + +When, as per PEP 434, feature changes are backported, entries are placed +in the 3.n.rst file *in the main branch* for each Python version n that +gets the backport. (Note: the format of entries have varied between +versions.) Add a line "New in 3.n maintenance releases." before the +first back-ported feature after 3.n.0 is released. Since each older +version file gets a different number of backports, it is easiest to +make a separate PR for each file and label it with the backports +needed. From webhook-mailer at python.org Fri Aug 5 17:44:09 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 05 Aug 2022 21:44:09 -0000 Subject: [Python-checkins] gh-95251: IDLE - Add What's New section to README (GH-95688) Message-ID: <mailman.541.1659735850.3313.python-checkins@python.org> https://github.com/python/cpython/commit/426bf7bbf901fabe0f2b9b9241147864f5e66fc9 commit: 426bf7bbf901fabe0f2b9b9241147864f5e66fc9 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-05T14:43:53-07:00 summary: gh-95251: IDLE - Add What's New section to README (GH-95688) Document what I (TJR) currently do for 3.10/3.11. Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> (cherry picked from commit a302a274892f2dad4e1fa492c4886d55e4df0a80) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 67de2be2625..779b51c1b93 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -243,8 +243,8 @@ OTHER TOPICS Generally use PEP 8. -import ------- +import statements +----------------- Put imports at the top, unless there is a good reason otherwise. PEP 8 says to group stdlib, 3rd-party dependencies, and package imports. For idlelib, the groups are general stdlib, tkinter, and idlelib. @@ -259,3 +259,24 @@ htest function def or "if __name__ == '__main__'" clause. Within module imports like "from idlelib.mod import class" may cause circular imports to deadlock. Even without this, circular imports may require at least one of the imports to be delayed until a function call. + +What's New entries +------------------ + +Repository directory Doc/whatsnew/ has a file 3.n.rst for each 3.n +Python version. For the first entry in each file, add subsection +'IDLE and idlelib', in alphabetical position, to the 'Improved Modules' +section. For the rest of cpython, entries to 3.(n+1).rst begin with +the release of 3.n.0b1. For IDLE, entries for features backported from +'main' to '3.n' during its beta period do not got in 3.(n+1).rst. The +latter usually gets its first entry during the 3.n.0 candidate period +or after the 3.n.0 release. + +When, as per PEP 434, feature changes are backported, entries are placed +in the 3.n.rst file *in the main branch* for each Python version n that +gets the backport. (Note: the format of entries have varied between +versions.) Add a line "New in 3.n maintenance releases." before the +first back-ported feature after 3.n.0 is released. Since each older +version file gets a different number of backports, it is easiest to +make a separate PR for each file and label it with the backports +needed. From webhook-mailer at python.org Fri Aug 5 18:37:56 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 05 Aug 2022 22:37:56 -0000 Subject: [Python-checkins] gh-86943: implement `pathlib.WindowsPath.is_mount()` (GH-31458) Message-ID: <mailman.542.1659739077.3313.python-checkins@python.org> https://github.com/python/cpython/commit/29650fea9605bf1f48320487c6d5d6d70d97ad95 commit: 29650fea9605bf1f48320487c6d5d6d70d97ad95 branch: main author: Barney Gale <barney.gale at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-05T15:37:44-07:00 summary: gh-86943: implement `pathlib.WindowsPath.is_mount()` (GH-31458) Have `pathlib.WindowsPath.is_mount()` call `ntpath.ismount()`. Previously it raised `NotImplementedError` unconditionally. https://bugs.python.org/issue42777 files: A Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst M Doc/library/pathlib.rst M Lib/pathlib.py M Lib/test/test_pathlib.py diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 19944bd7bd0a..f7d7745eef52 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -876,10 +876,15 @@ call fails (for example because the path doesn't exist). function checks whether *path*'s parent, :file:`path/..`, is on a different device than *path*, or whether :file:`path/..` and *path* point to the same i-node on the same device --- this should detect mount points for all Unix - and POSIX variants. Not implemented on Windows. + and POSIX variants. On Windows, a mount point is considered to be a drive + letter root (e.g. ``c:\``), a UNC share (e.g. ``\\server\share``), or a + mounted filesystem directory. .. versionadded:: 3.7 + .. versionchanged:: 3.12 + Windows support was added. + .. method:: Path.is_symlink() diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 2aee71742b23..54da1c8a6253 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1211,23 +1211,9 @@ def is_file(self): def is_mount(self): """ - Check if this path is a POSIX mount point + Check if this path is a mount point """ - # Need to exist and be a dir - if not self.exists() or not self.is_dir(): - return False - - try: - parent_dev = self.parent.stat().st_dev - except OSError: - return False - - dev = self.stat().st_dev - if dev != parent_dev: - return True - ino = self.stat().st_ino - parent_ino = self.parent.stat().st_ino - return ino == parent_ino + return self._flavour.pathmod.ismount(self) def is_symlink(self): """ @@ -1378,6 +1364,3 @@ class WindowsPath(Path, PureWindowsPath): On a Windows system, instantiating a Path should return this object. """ __slots__ = () - - def is_mount(self): - raise NotImplementedError("Path.is_mount() is unsupported on this system") diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index e14b0fca5536..668af8030c0c 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2294,10 +2294,12 @@ def test_is_file(self): self.assertIs((P / 'fileA\udfff').is_file(), False) self.assertIs((P / 'fileA\x00').is_file(), False) - @only_posix def test_is_mount(self): P = self.cls(BASE) - R = self.cls('/') # TODO: Work out Windows. + if os.name == 'nt': + R = self.cls('c:\\') + else: + R = self.cls('/') self.assertFalse((P / 'fileA').is_mount()) self.assertFalse((P / 'dirA').is_mount()) self.assertFalse((P / 'non-existing').is_mount()) @@ -2305,8 +2307,7 @@ def test_is_mount(self): self.assertTrue(R.is_mount()) if os_helper.can_symlink(): self.assertFalse((P / 'linkA').is_mount()) - self.assertIs(self.cls('/\udfff').is_mount(), False) - self.assertIs(self.cls('/\x00').is_mount(), False) + self.assertIs((R / '\udfff').is_mount(), False) def test_is_symlink(self): P = self.cls(BASE) diff --git a/Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst b/Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst new file mode 100644 index 000000000000..24912380fb59 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-21-01-37-00.bpo-42777.nWK3E6.rst @@ -0,0 +1 @@ +Implement :meth:`pathlib.Path.is_mount` for Windows paths. From webhook-mailer at python.org Fri Aug 5 20:41:37 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 06 Aug 2022 00:41:37 -0000 Subject: [Python-checkins] gh-93243: Make smtpd private before porting its users (GH-93246) Message-ID: <mailman.543.1659746498.3313.python-checkins@python.org> https://github.com/python/cpython/commit/56d16e8cb4e7d7ab47efdec08a0dae8d21b155f5 commit: 56d16e8cb4e7d7ab47efdec08a0dae8d21b155f5 branch: main author: Oleg Iarygin <oleg at arhadthedev.net> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-05T17:41:29-07:00 summary: gh-93243: Make smtpd private before porting its users (GH-93246) gh-93243 This PR is required to reduce diffs of the following porting (no need to either maintain documentation and tests consistent with each porting step, or try to port everything and remove smtpd in a single PR). Automerge-Triggered-By: GH:warsaw files: A Lib/test/smtpd.py A Misc/NEWS.d/next/Library/2022-05-26-08-41-34.gh-issue-93243.uw6x5z.rst D Doc/library/smtpd.rst D Lib/smtpd.py D Lib/test/test_smtpd.py M Doc/library/email.rst M Doc/library/superseded.rst M Doc/whatsnew/3.12.rst M Lib/test/mock_socket.py M Lib/test/test_logging.py M Lib/test/test_smtplib.py M PCbuild/lib.pyproj M Python/stdlib_module_names.h M Tools/wasm/wasm_assets.py diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 5eebcd9e896..816fae991d2 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -147,6 +147,3 @@ Legacy API: Module :mod:`mailbox` Tools for creating, reading, and managing collections of messages on disk using a variety standard formats. - - Module :mod:`smtpd` - SMTP server framework (primarily useful for testing) diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst deleted file mode 100644 index ac0c9aeb236..00000000000 --- a/Doc/library/smtpd.rst +++ /dev/null @@ -1,268 +0,0 @@ -:mod:`smtpd` --- SMTP Server -============================ - -.. module:: smtpd - :synopsis: A SMTP server implementation in Python. - :deprecated: - -.. moduleauthor:: Barry Warsaw <barry at python.org> -.. sectionauthor:: Moshe Zadka <moshez at moshez.org> - -**Source code:** :source:`Lib/smtpd.py` - --------------- - -This module offers several classes to implement SMTP (email) servers. - -.. deprecated-removed:: 3.6 3.12 - The :mod:`smtpd` module is deprecated - (see :pep:`PEP 594 <594#smtpd>` for details). - The `aiosmtpd <https://aiosmtpd.readthedocs.io/>`_ package is a recommended - replacement for this module. It is based on :mod:`asyncio` and provides a - more straightforward API. - -Several server implementations are present; one is a generic -do-nothing implementation, which can be overridden, while the other two offer -specific mail-sending strategies. - -Additionally the SMTPChannel may be extended to implement very specific -interaction behaviour with SMTP clients. - -The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` -SMTPUTF8 extensions. - -.. include:: ../includes/wasm-notavail.rst - -SMTPServer Objects ------------------- - - -.. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\ - map=None, enable_SMTPUTF8=False, decode_data=False) - - Create a new :class:`SMTPServer` object, which binds to local address - *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. Both - *localaddr* and *remoteaddr* should be a :ref:`(host, port) <host_port>` - tuple. The object inherits from :class:`asyncore.dispatcher`, and so will - insert itself into :mod:`asyncore`'s event loop on instantiation. - - *data_size_limit* specifies the maximum number of bytes that will be - accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no - limit. - - *map* is the socket map to use for connections (an initially empty - dictionary is a suitable value). If not specified the :mod:`asyncore` - global socket map is used. - - *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined - in :RFC:`6531`) should be enabled. The default is ``False``. - When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL`` - command and when present is passed to :meth:`process_message` in the - ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* - cannot be set to ``True`` at the same time. - - *decode_data* specifies whether the data portion of the SMTP transaction - should be decoded using UTF-8. When *decode_data* is ``False`` (the - default), the server advertises the ``8BITMIME`` - extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to - the ``MAIL`` command, and when present passes it to :meth:`process_message` - in the ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* - cannot be set to ``True`` at the same time. - - .. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs) - - Raise a :exc:`NotImplementedError` exception. Override this in subclasses to - do something useful with this message. Whatever was passed in the - constructor as *remoteaddr* will be available as the :attr:`_remoteaddr` - attribute. *peer* is the remote host's address, *mailfrom* is the envelope - originator, *rcpttos* are the envelope recipients and *data* is a string - containing the contents of the e-mail (which should be in :rfc:`5321` - format). - - If the *decode_data* constructor keyword is set to ``True``, the *data* - argument will be a unicode string. If it is set to ``False``, it - will be a bytes object. - - *kwargs* is a dictionary containing additional information. It is empty - if ``decode_data=True`` was given as an init argument, otherwise - it contains the following keys: - - *mail_options*: - a list of all received parameters to the ``MAIL`` - command (the elements are uppercase strings; example: - ``['BODY=8BITMIME', 'SMTPUTF8']``). - - *rcpt_options*: - same as *mail_options* but for the ``RCPT`` command. - Currently no ``RCPT TO`` options are supported, so for now - this will always be an empty list. - - Implementations of ``process_message`` should use the ``**kwargs`` - signature to accept arbitrary keyword arguments, since future feature - enhancements may add keys to the kwargs dictionary. - - Return ``None`` to request a normal ``250 Ok`` response; otherwise - return the desired response string in :RFC:`5321` format. - - .. attribute:: channel_class - - Override this in subclasses to use a custom :class:`SMTPChannel` for - managing SMTP clients. - - .. versionadded:: 3.4 - The *map* constructor argument. - - .. versionchanged:: 3.5 - *localaddr* and *remoteaddr* may now contain IPv6 addresses. - - .. versionadded:: 3.5 - The *decode_data* and *enable_SMTPUTF8* constructor parameters, and the - *kwargs* parameter to :meth:`process_message` when *decode_data* is - ``False``. - - .. versionchanged:: 3.6 - *decode_data* is now ``False`` by default. - - -DebuggingServer Objects ------------------------ - - -.. class:: DebuggingServer(localaddr, remoteaddr) - - Create a new debugging server. Arguments are as per :class:`SMTPServer`. - Messages will be discarded, and printed on stdout. - - -PureProxy Objects ------------------ - - -.. class:: PureProxy(localaddr, remoteaddr) - - Create a new pure proxy server. Arguments are as per :class:`SMTPServer`. - Everything will be relayed to *remoteaddr*. Note that running this has a good - chance to make you into an open relay, so please be careful. - - -SMTPChannel Objects -------------------- - -.. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\ - map=None, enable_SMTPUTF8=False, decode_data=False) - - Create a new :class:`SMTPChannel` object which manages the communication - between the server and a single SMTP client. - - *conn* and *addr* are as per the instance variables described below. - - *data_size_limit* specifies the maximum number of bytes that will be - accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no - limit. - - *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined - in :RFC:`6531`) should be enabled. The default is ``False``. - *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same - time. - - A dictionary can be specified in *map* to avoid using a global socket map. - - *decode_data* specifies whether the data portion of the SMTP transaction - should be decoded using UTF-8. The default is ``False``. - *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same - time. - - To use a custom SMTPChannel implementation you need to override the - :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`. - - .. versionchanged:: 3.5 - The *decode_data* and *enable_SMTPUTF8* parameters were added. - - .. versionchanged:: 3.6 - *decode_data* is now ``False`` by default. - - The :class:`SMTPChannel` has the following instance variables: - - .. attribute:: smtp_server - - Holds the :class:`SMTPServer` that spawned this channel. - - .. attribute:: conn - - Holds the socket object connecting to the client. - - .. attribute:: addr - - Holds the address of the client, the second value returned by - :func:`socket.accept <socket.socket.accept>` - - .. attribute:: received_lines - - Holds a list of the line strings (decoded using UTF-8) received from - the client. The lines have their ``"\r\n"`` line ending translated to - ``"\n"``. - - .. attribute:: smtp_state - - Holds the current state of the channel. This will be either - :attr:`COMMAND` initially and then :attr:`DATA` after the client sends - a "DATA" line. - - .. attribute:: seen_greeting - - Holds a string containing the greeting sent by the client in its "HELO". - - .. attribute:: mailfrom - - Holds a string containing the address identified in the "MAIL FROM:" line - from the client. - - .. attribute:: rcpttos - - Holds a list of strings containing the addresses identified in the - "RCPT TO:" lines from the client. - - .. attribute:: received_data - - Holds a string containing all of the data sent by the client during the - DATA state, up to but not including the terminating ``"\r\n.\r\n"``. - - .. attribute:: fqdn - - Holds the fully qualified domain name of the server as returned by - :func:`socket.getfqdn`. - - .. attribute:: peer - - Holds the name of the client peer as returned by ``conn.getpeername()`` - where ``conn`` is :attr:`conn`. - - The :class:`SMTPChannel` operates by invoking methods named ``smtp_<command>`` - upon reception of a command line from the client. Built into the base - :class:`SMTPChannel` class are methods for handling the following commands - (and responding to them appropriately): - - ======== =================================================================== - Command Action taken - ======== =================================================================== - HELO Accepts the greeting from the client and stores it in - :attr:`seen_greeting`. Sets server to base command mode. - EHLO Accepts the greeting from the client and stores it in - :attr:`seen_greeting`. Sets server to extended command mode. - NOOP Takes no action. - QUIT Closes the connection cleanly. - MAIL Accepts the "MAIL FROM:" syntax and stores the supplied address as - :attr:`mailfrom`. In extended command mode, accepts the - :rfc:`1870` SIZE attribute and responds appropriately based on the - value of *data_size_limit*. - RCPT Accepts the "RCPT TO:" syntax and stores the supplied addresses in - the :attr:`rcpttos` list. - RSET Resets the :attr:`mailfrom`, :attr:`rcpttos`, and - :attr:`received_data`, but not the greeting. - DATA Sets the internal state to :attr:`DATA` and stores remaining lines - from the client in :attr:`received_data` until the terminator - ``"\r\n.\r\n"`` is received. - HELP Returns minimal information on command syntax - VRFY Returns code 252 (the server doesn't know if the address is valid) - EXPN Reports that the command is not implemented. - ======== =================================================================== diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index b38f16691f6..57ef9638d05 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -27,7 +27,6 @@ backwards compatibility. They have been superseded by other modules. optparse.rst ossaudiodev.rst pipes.rst - smtpd.rst sndhdr.rst spwd.rst sunau.rst diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 9ea4d0369e6..ddf9e1f6a59 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -299,6 +299,14 @@ Removed (and corresponding ``EXPERIMENTAL_ISOLATED_SUBINTERPRETERS``) have been removed. +* ``smtpd`` has been removed according to the schedule in :pep:`594`, + having been deprecated in Python 3.4.7 and 3.5.4. + Use aiosmtpd_ PyPI module or any other + :mod:`asyncio`-based server instead. + (Contributed by Oleg Iarygin in :gh:`93243`.) + +.. _aiosmtpd: https://pypi.org/project/aiosmtpd/ + * Remove ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python 3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) function is a built-in function. Since Python 3.10, :func:`_pyio.open` is @@ -382,6 +390,10 @@ Changes in the Python API to :term:`filesystem encoding and error handler`. Argument files should be encoded in UTF-8 instead of ANSI Codepage on Windows. +* Removed the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 + and 3.5.4. A recommended replacement is the + :mod:`asyncio`-based aiosmtpd_ PyPI module. + * :func:`shlex.split`: Passing ``None`` for *s* argument now raises an exception, rather than reading :data:`sys.stdin`. The feature was deprecated in Python 3.9. diff --git a/Lib/test/mock_socket.py b/Lib/test/mock_socket.py index c7abddcf5fa..b85b955d7f6 100644 --- a/Lib/test/mock_socket.py +++ b/Lib/test/mock_socket.py @@ -1,4 +1,4 @@ -"""Mock socket module used by the smtpd and smtplib tests. +"""Mock socket module used by the smtplib tests. """ # imported for _GLOBAL_DEFAULT_TIMEOUT @@ -33,7 +33,7 @@ def close(self): class MockSocket: - """Mock socket object used by smtpd and smtplib tests. + """Mock socket object used by the smtplib tests. """ def __init__(self, family=None): global _reply_data diff --git a/Lib/smtpd.py b/Lib/test/smtpd.py similarity index 98% rename from Lib/smtpd.py rename to Lib/test/smtpd.py index b23579f1207..f9d4b048a83 100755 --- a/Lib/smtpd.py +++ b/Lib/test/smtpd.py @@ -77,25 +77,16 @@ import time import socket import collections -from warnings import _deprecated, warn +from test.support.import_helper import import_module +from warnings import warn from email._header_value_parser import get_addr_spec, get_angle_addr __all__ = [ "SMTPChannel", "SMTPServer", "DebuggingServer", "PureProxy", ] -_DEPRECATION_MSG = ('The {name} module is deprecated and unmaintained and will ' - 'be removed in Python {remove}. Please see aiosmtpd ' - '(https://aiosmtpd.readthedocs.io/) for the recommended ' - 'replacement.') -_deprecated(__name__, _DEPRECATION_MSG, remove=(3, 12)) - - -# These are imported after the above warning so that users get the correct -# deprecation warning. -import asyncore -import asynchat - +asyncore = import_module('asyncore', deprecated=True) +asynchat = import_module('asynchat', deprecated=True) program = sys.argv[0] __version__ = 'Python SMTP proxy version 0.3' diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index a900dabec67..a505e8000da 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -61,9 +61,10 @@ from socketserver import (ThreadingUDPServer, DatagramRequestHandler, ThreadingTCPServer, StreamRequestHandler) +with warnings.catch_warnings(): + from . import smtpd asyncore = warnings_helper.import_deprecated('asyncore') -smtpd = warnings_helper.import_deprecated('smtpd') try: diff --git a/Lib/test/test_smtpd.py b/Lib/test/test_smtpd.py deleted file mode 100644 index 39ff8793648..00000000000 --- a/Lib/test/test_smtpd.py +++ /dev/null @@ -1,1019 +0,0 @@ -import unittest -import textwrap -from test import support, mock_socket -from test.support import socket_helper -from test.support import warnings_helper -import socket -import io - - -smtpd = warnings_helper.import_deprecated('smtpd') -asyncore = warnings_helper.import_deprecated('asyncore') - -if not socket_helper.has_gethostname: - raise unittest.SkipTest("test requires gethostname()") - - -class DummyServer(smtpd.SMTPServer): - def __init__(self, *args, **kwargs): - smtpd.SMTPServer.__init__(self, *args, **kwargs) - self.messages = [] - if self._decode_data: - self.return_status = 'return status' - else: - self.return_status = b'return status' - - def process_message(self, peer, mailfrom, rcpttos, data, **kw): - self.messages.append((peer, mailfrom, rcpttos, data)) - if data == self.return_status: - return '250 Okish' - if 'mail_options' in kw and 'SMTPUTF8' in kw['mail_options']: - return '250 SMTPUTF8 message okish' - - -class DummyDispatcherBroken(Exception): - pass - - -class BrokenDummyServer(DummyServer): - def listen(self, num): - raise DummyDispatcherBroken() - - -class SMTPDServerTest(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - - def test_process_message_unimplemented(self): - server = smtpd.SMTPServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) - - def write_line(line): - channel.socket.queue_recv(line) - channel.handle_read() - - write_line(b'HELO example') - write_line(b'MAIL From:eggs at example') - write_line(b'RCPT To:spam at example') - write_line(b'DATA') - self.assertRaises(NotImplementedError, write_line, b'spam\r\n.\r\n') - - def test_decode_data_and_enable_SMTPUTF8_raises(self): - self.assertRaises( - ValueError, - smtpd.SMTPServer, - (socket_helper.HOST, 0), - ('b', 0), - enable_SMTPUTF8=True, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - - -class DebuggingServerTest(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - - def send_data(self, channel, data, enable_SMTPUTF8=False): - def write_line(line): - channel.socket.queue_recv(line) - channel.handle_read() - write_line(b'EHLO example') - if enable_SMTPUTF8: - write_line(b'MAIL From:eggs at example BODY=8BITMIME SMTPUTF8') - else: - write_line(b'MAIL From:eggs at example') - write_line(b'RCPT To:spam at example') - write_line(b'DATA') - write_line(data) - write_line(b'.') - - def test_process_message_with_decode_data_true(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nhello\n') - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - From: test - X-Peer: peer-address - - hello - ------------ END MESSAGE ------------ - """)) - - def test_process_message_with_decode_data_false(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n') - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - b'From: test' - b'X-Peer: peer-address' - b'' - b'h\\xc3\\xa9llo\\xff' - ------------ END MESSAGE ------------ - """)) - - def test_process_message_with_enable_SMTPUTF8_true(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0), - enable_SMTPUTF8=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n') - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - b'From: test' - b'X-Peer: peer-address' - b'' - b'h\\xc3\\xa9llo\\xff' - ------------ END MESSAGE ------------ - """)) - - def test_process_SMTPUTF8_message_with_enable_SMTPUTF8_true(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0), - enable_SMTPUTF8=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n', - enable_SMTPUTF8=True) - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - mail options: ['BODY=8BITMIME', 'SMTPUTF8'] - b'From: test' - b'X-Peer: peer-address' - b'' - b'h\\xc3\\xa9llo\\xff' - ------------ END MESSAGE ------------ - """)) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - - -class TestFamilyDetection(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - - @unittest.skipUnless(socket_helper.IPV6_ENABLED, "IPv6 not enabled") - def test_socket_uses_IPv6(self): - server = smtpd.SMTPServer((socket_helper.HOSTv6, 0), (socket_helper.HOSTv4, 0)) - self.assertEqual(server.socket.family, socket.AF_INET6) - - def test_socket_uses_IPv4(self): - server = smtpd.SMTPServer((socket_helper.HOSTv4, 0), (socket_helper.HOSTv6, 0)) - self.assertEqual(server.socket.family, socket.AF_INET) - - -class TestRcptOptionParsing(unittest.TestCase): - error_response = (b'555 RCPT TO parameters not recognized or not ' - b'implemented\r\n') - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, channel, line): - channel.socket.queue_recv(line) - channel.handle_read() - - def test_params_rejected(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - self.write_line(channel, b'EHLO example') - self.write_line(channel, b'MAIL from: <foo at example.com> size=20') - self.write_line(channel, b'RCPT to: <foo at example.com> foo=bar') - self.assertEqual(channel.socket.last, self.error_response) - - def test_nothing_accepted(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - self.write_line(channel, b'EHLO example') - self.write_line(channel, b'MAIL from: <foo at example.com> size=20') - self.write_line(channel, b'RCPT to: <foo at example.com>') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - -class TestMailOptionParsing(unittest.TestCase): - error_response = (b'555 MAIL FROM parameters not recognized or not ' - b'implemented\r\n') - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, channel, line): - channel.socket.queue_recv(line) - channel.handle_read() - - def test_with_decode_data_true(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0), decode_data=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) - self.write_line(channel, b'EHLO example') - for line in [ - b'MAIL from: <foo at example.com> size=20 SMTPUTF8', - b'MAIL from: <foo at example.com> size=20 SMTPUTF8 BODY=8BITMIME', - b'MAIL from: <foo at example.com> size=20 BODY=UNKNOWN', - b'MAIL from: <foo at example.com> size=20 body=8bitmime', - ]: - self.write_line(channel, line) - self.assertEqual(channel.socket.last, self.error_response) - self.write_line(channel, b'MAIL from: <foo at example.com> size=20') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - def test_with_decode_data_false(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - self.write_line(channel, b'EHLO example') - for line in [ - b'MAIL from: <foo at example.com> size=20 SMTPUTF8', - b'MAIL from: <foo at example.com> size=20 SMTPUTF8 BODY=8BITMIME', - ]: - self.write_line(channel, line) - self.assertEqual(channel.socket.last, self.error_response) - self.write_line( - channel, - b'MAIL from: <foo at example.com> size=20 SMTPUTF8 BODY=UNKNOWN') - self.assertEqual( - channel.socket.last, - b'501 Error: BODY can only be one of 7BIT, 8BITMIME\r\n') - self.write_line( - channel, b'MAIL from: <foo at example.com> size=20 body=8bitmime') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - def test_with_enable_smtputf8_true(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0), enable_SMTPUTF8=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) - self.write_line(channel, b'EHLO example') - self.write_line( - channel, - b'MAIL from: <foo at example.com> size=20 body=8bitmime smtputf8') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - -class SMTPDChannelTest(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_broken_connect(self): - self.assertRaises( - DummyDispatcherBroken, BrokenDummyServer, - (socket_helper.HOST, 0), ('b', 0), decode_data=True) - - def test_decode_data_and_enable_SMTPUTF8_raises(self): - self.assertRaises( - ValueError, smtpd.SMTPChannel, - self.server, self.channel.conn, self.channel.addr, - enable_SMTPUTF8=True, decode_data=True) - - def test_server_accept(self): - self.server.handle_accept() - - def test_missing_data(self): - self.write_line(b'') - self.assertEqual(self.channel.socket.last, - b'500 Error: bad syntax\r\n') - - def test_EHLO(self): - self.write_line(b'EHLO example') - self.assertEqual(self.channel.socket.last, b'250 HELP\r\n') - - def test_EHLO_bad_syntax(self): - self.write_line(b'EHLO') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: EHLO hostname\r\n') - - def test_EHLO_duplicate(self): - self.write_line(b'EHLO example') - self.write_line(b'EHLO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_EHLO_HELO_duplicate(self): - self.write_line(b'EHLO example') - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_HELO(self): - name = smtpd.socket.getfqdn() - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - '250 {}\r\n'.format(name).encode('ascii')) - - def test_HELO_EHLO_duplicate(self): - self.write_line(b'HELO example') - self.write_line(b'EHLO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_HELP(self): - self.write_line(b'HELP') - self.assertEqual(self.channel.socket.last, - b'250 Supported commands: EHLO HELO MAIL RCPT ' + \ - b'DATA RSET NOOP QUIT VRFY\r\n') - - def test_HELP_command(self): - self.write_line(b'HELP MAIL') - self.assertEqual(self.channel.socket.last, - b'250 Syntax: MAIL FROM: <address>\r\n') - - def test_HELP_command_unknown(self): - self.write_line(b'HELP SPAM') - self.assertEqual(self.channel.socket.last, - b'501 Supported commands: EHLO HELO MAIL RCPT ' + \ - b'DATA RSET NOOP QUIT VRFY\r\n') - - def test_HELO_bad_syntax(self): - self.write_line(b'HELO') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: HELO hostname\r\n') - - def test_HELO_duplicate(self): - self.write_line(b'HELO example') - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_HELO_parameter_rejected_when_extensions_not_enabled(self): - self.extended_smtp = False - self.write_line(b'HELO example') - self.write_line(b'MAIL from:<foo at example.com> SIZE=1234') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address>\r\n') - - def test_MAIL_allows_space_after_colon(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from: <foo at example.com>') - self.assertEqual(self.channel.socket.last, - b'250 OK\r\n') - - def test_extended_MAIL_allows_space_after_colon(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: <foo at example.com> size=20') - self.assertEqual(self.channel.socket.last, - b'250 OK\r\n') - - def test_NOOP(self): - self.write_line(b'NOOP') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_HELO_NOOP(self): - self.write_line(b'HELO example') - self.write_line(b'NOOP') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_NOOP_bad_syntax(self): - self.write_line(b'NOOP hi') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: NOOP\r\n') - - def test_QUIT(self): - self.write_line(b'QUIT') - self.assertEqual(self.channel.socket.last, b'221 Bye\r\n') - - def test_HELO_QUIT(self): - self.write_line(b'HELO example') - self.write_line(b'QUIT') - self.assertEqual(self.channel.socket.last, b'221 Bye\r\n') - - def test_QUIT_arg_ignored(self): - self.write_line(b'QUIT bye bye') - self.assertEqual(self.channel.socket.last, b'221 Bye\r\n') - - def test_bad_state(self): - self.channel.smtp_state = 'BAD STATE' - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - b'451 Internal confusion\r\n') - - def test_command_too_long(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from: ' + - b'a' * self.channel.command_size_limit + - b'@example') - self.assertEqual(self.channel.socket.last, - b'500 Error: line too long\r\n') - - def test_MAIL_command_limit_extended_with_SIZE(self): - self.write_line(b'EHLO example') - fill_len = self.channel.command_size_limit - len('MAIL from:<@example>') - self.write_line(b'MAIL from:<' + - b'a' * fill_len + - b'@example> SIZE=1234') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'MAIL from:<' + - b'a' * (fill_len + 26) + - b'@example> SIZE=1234') - self.assertEqual(self.channel.socket.last, - b'500 Error: line too long\r\n') - - def test_MAIL_command_rejects_SMTPUTF8_by_default(self): - self.write_line(b'EHLO example') - self.write_line( - b'MAIL from: <naive at example.com> BODY=8BITMIME SMTPUTF8') - self.assertEqual(self.channel.socket.last[0:1], b'5') - - def test_data_longer_than_default_data_size_limit(self): - # Hack the default so we don't have to generate so much data. - self.channel.data_size_limit = 1048 - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'A' * self.channel.data_size_limit + - b'A\r\n.') - self.assertEqual(self.channel.socket.last, - b'552 Error: Too much mail data\r\n') - - def test_MAIL_size_parameter(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs at example> SIZE=512') - self.assertEqual(self.channel.socket.last, - b'250 OK\r\n') - - def test_MAIL_invalid_size_parameter(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs at example> SIZE=invalid') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address> [SP <mail-parameters>]\r\n') - - def test_MAIL_RCPT_unknown_parameters(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs at example> ham=green') - self.assertEqual(self.channel.socket.last, - b'555 MAIL FROM parameters not recognized or not implemented\r\n') - - self.write_line(b'MAIL FROM:<eggs at example>') - self.write_line(b'RCPT TO:<eggs at example> ham=green') - self.assertEqual(self.channel.socket.last, - b'555 RCPT TO parameters not recognized or not implemented\r\n') - - def test_MAIL_size_parameter_larger_than_default_data_size_limit(self): - self.channel.data_size_limit = 1048 - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs at example> SIZE=2096') - self.assertEqual(self.channel.socket.last, - b'552 Error: message size exceeds fixed maximum message size\r\n') - - def test_need_MAIL(self): - self.write_line(b'HELO example') - self.write_line(b'RCPT to:spam at example') - self.assertEqual(self.channel.socket.last, - b'503 Error: need MAIL command\r\n') - - def test_MAIL_syntax_HELO(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from eggs at example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address>\r\n') - - def test_MAIL_syntax_EHLO(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from eggs at example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address> [SP <mail-parameters>]\r\n') - - def test_MAIL_missing_address(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from:') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address>\r\n') - - def test_MAIL_chevrons(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from:<eggs at example>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_MAIL_empty_chevrons(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from:<>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_MAIL_quoted_localpart(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: <"Fred Blogs"@example.com>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_MAIL_quoted_localpart_no_angles(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: "Fred Blogs"@example.com') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_MAIL_quoted_localpart_with_size(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: <"Fred Blogs"@example.com> SIZE=1000') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_MAIL_quoted_localpart_with_size_no_angles(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: "Fred Blogs"@example.com SIZE=1000') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_nested_MAIL(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from:eggs at example') - self.write_line(b'MAIL from:spam at example') - self.assertEqual(self.channel.socket.last, - b'503 Error: nested MAIL command\r\n') - - def test_VRFY(self): - self.write_line(b'VRFY eggs at example') - self.assertEqual(self.channel.socket.last, - b'252 Cannot VRFY user, but will accept message and attempt ' + \ - b'delivery\r\n') - - def test_VRFY_syntax(self): - self.write_line(b'VRFY') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: VRFY <address>\r\n') - - def test_EXPN_not_implemented(self): - self.write_line(b'EXPN') - self.assertEqual(self.channel.socket.last, - b'502 EXPN not implemented\r\n') - - def test_no_HELO_MAIL(self): - self.write_line(b'MAIL from:<foo at example.com>') - self.assertEqual(self.channel.socket.last, - b'503 Error: send HELO first\r\n') - - def test_need_RCPT(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'503 Error: need RCPT command\r\n') - - def test_RCPT_syntax_HELO(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From: eggs at example') - self.write_line(b'RCPT to eggs at example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: RCPT TO: <address>\r\n') - - def test_RCPT_syntax_EHLO(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL From: eggs at example') - self.write_line(b'RCPT to eggs at example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: RCPT TO: <address> [SP <mail-parameters>]\r\n') - - def test_RCPT_lowercase_to_OK(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From: eggs at example') - self.write_line(b'RCPT to: <eggs at example>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_no_HELO_RCPT(self): - self.write_line(b'RCPT to eggs at example') - self.assertEqual(self.channel.socket.last, - b'503 Error: send HELO first\r\n') - - def test_data_dialog(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'RCPT To:spam at example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'354 End data with <CR><LF>.<CR><LF>\r\n') - self.write_line(b'data\r\nmore\r\n.') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'eggs at example', - ['spam at example'], - 'data\nmore')]) - - def test_DATA_syntax(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA spam') - self.assertEqual(self.channel.socket.last, b'501 Syntax: DATA\r\n') - - def test_no_HELO_DATA(self): - self.write_line(b'DATA spam') - self.assertEqual(self.channel.socket.last, - b'503 Error: send HELO first\r\n') - - def test_data_transparency_section_4_5_2(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'..\r\n.\r\n') - self.assertEqual(self.channel.received_data, '.') - - def test_multiple_RCPT(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'RCPT To:ham at example') - self.write_line(b'DATA') - self.write_line(b'data\r\n.') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'eggs at example', - ['spam at example','ham at example'], - 'data')]) - - def test_manual_status(self): - # checks that the Channel is able to return a custom status message - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'return status\r\n.') - self.assertEqual(self.channel.socket.last, b'250 Okish\r\n') - - def test_RSET(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'RSET') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'MAIL From:foo at example') - self.write_line(b'RCPT To:eggs at example') - self.write_line(b'DATA') - self.write_line(b'data\r\n.') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'foo at example', - ['eggs at example'], - 'data')]) - - def test_HELO_RSET(self): - self.write_line(b'HELO example') - self.write_line(b'RSET') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_RSET_syntax(self): - self.write_line(b'RSET hi') - self.assertEqual(self.channel.socket.last, b'501 Syntax: RSET\r\n') - - def test_unknown_command(self): - self.write_line(b'UNKNOWN_CMD') - self.assertEqual(self.channel.socket.last, - b'500 Error: command "UNKNOWN_CMD" not ' + \ - b'recognized\r\n') - - def test_attribute_deprecations(self): - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__server - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__server = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__line - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__line = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__state - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__state = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__greeting - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__greeting = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__mailfrom - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__mailfrom = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__rcpttos - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__rcpttos = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__data - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__data = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__fqdn - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__fqdn = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__peer - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__peer = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__conn - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__conn = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__addr - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__addr = 'spam' - - at unittest.skipUnless(socket_helper.IPV6_ENABLED, "IPv6 not enabled") -class SMTPDChannelIPv6Test(SMTPDChannelTest): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOSTv6, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - decode_data=True) - -class SMTPDChannelWithDataSizeLimitTest(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - # Set DATA size limit to 32 bytes for easy testing - self.channel = smtpd.SMTPChannel(self.server, conn, addr, 32, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_data_limit_dialog(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'RCPT To:spam at example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'354 End data with <CR><LF>.<CR><LF>\r\n') - self.write_line(b'data\r\nmore\r\n.') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'eggs at example', - ['spam at example'], - 'data\nmore')]) - - def test_data_limit_dialog_too_much_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'RCPT To:spam at example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'354 End data with <CR><LF>.<CR><LF>\r\n') - self.write_line(b'This message is longer than 32 bytes\r\n.') - self.assertEqual(self.channel.socket.last, - b'552 Error: Too much mail data\r\n') - - -class SMTPDChannelWithDecodeDataFalse(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_ascii_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'plain ascii text') - self.write_line(b'.') - self.assertEqual(self.channel.received_data, b'plain ascii text') - - def test_utf8_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - self.write_line(b'and some plain ascii') - self.write_line(b'.') - self.assertEqual( - self.channel.received_data, - b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87\n' - b'and some plain ascii') - - -class SMTPDChannelWithDecodeDataTrue(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - # Set decode_data to True - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_ascii_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'plain ascii text') - self.write_line(b'.') - self.assertEqual(self.channel.received_data, 'plain ascii text') - - def test_utf8_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs at example') - self.write_line(b'RCPT To:spam at example') - self.write_line(b'DATA') - self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - self.write_line(b'and some plain ascii') - self.write_line(b'.') - self.assertEqual( - self.channel.received_data, - 'utf8 enriched text: ???\nand some plain ascii') - - -class SMTPDChannelTestWithEnableSMTPUTF8True(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - enable_SMTPUTF8=True) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - enable_SMTPUTF8=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_MAIL_command_accepts_SMTPUTF8_when_announced(self): - self.write_line(b'EHLO example') - self.write_line( - 'MAIL from: <nai?ve at example.com> BODY=8BITMIME SMTPUTF8'.encode( - 'utf-8') - ) - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_process_smtputf8_message(self): - self.write_line(b'EHLO example') - for mail_parameters in [b'', b'BODY=8BITMIME SMTPUTF8']: - self.write_line(b'MAIL from: <a at example> ' + mail_parameters) - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'rcpt to:<b at example.com>') - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'data') - self.assertEqual(self.channel.socket.last[0:3], b'354') - self.write_line(b'c\r\n.') - if mail_parameters == b'': - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - else: - self.assertEqual(self.channel.socket.last, - b'250 SMTPUTF8 message okish\r\n') - - def test_utf8_data(self): - self.write_line(b'EHLO example') - self.write_line( - 'MAIL From: nai?ve at exampl? BODY=8BITMIME SMTPUTF8'.encode('utf-8')) - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line('RCPT To:sp?m at exampl?'.encode('utf-8')) - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last[0:3], b'354') - self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - self.write_line(b'.') - self.assertEqual( - self.channel.received_data, - b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - - def test_MAIL_command_limit_extended_with_SIZE_and_SMTPUTF8(self): - self.write_line(b'ehlo example') - fill_len = (512 + 26 + 10) - len('mail from:<@example>') - self.write_line(b'MAIL from:<' + - b'a' * (fill_len + 1) + - b'@example>') - self.assertEqual(self.channel.socket.last, - b'500 Error: line too long\r\n') - self.write_line(b'MAIL from:<' + - b'a' * fill_len + - b'@example>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_multiple_emails_with_extended_command_length(self): - self.write_line(b'ehlo example') - fill_len = (512 + 26 + 10) - len('mail from:<@example>') - for char in [b'a', b'b', b'c']: - self.write_line(b'MAIL from:<' + char * fill_len + b'a at example>') - self.assertEqual(self.channel.socket.last[0:3], b'500') - self.write_line(b'MAIL from:<' + char * fill_len + b'@example>') - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'rcpt to:<hans at example.com>') - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'data') - self.assertEqual(self.channel.socket.last[0:3], b'354') - self.write_line(b'test\r\n.') - self.assertEqual(self.channel.socket.last[0:3], b'250') - - -class MiscTestCase(unittest.TestCase): - def test__all__(self): - not_exported = { - "program", "Devnull", "DEBUGSTREAM", "NEWLINE", "COMMASPACE", - "DATA_SIZE_DEFAULT", "usage", "Options", "parseargs", - } - support.check__all__(self, smtpd, not_exported=not_exported) - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index a4074c02f19..3210ef21770 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -24,9 +24,9 @@ from test.support import warnings_helper from unittest.mock import Mock +from . import smtpd asyncore = warnings_helper.import_deprecated('asyncore') -smtpd = warnings_helper.import_deprecated('smtpd') support.requires_working_socket(module=True) diff --git a/Misc/NEWS.d/next/Library/2022-05-26-08-41-34.gh-issue-93243.uw6x5z.rst b/Misc/NEWS.d/next/Library/2022-05-26-08-41-34.gh-issue-93243.uw6x5z.rst new file mode 100644 index 00000000000..f03ed7b5efc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-26-08-41-34.gh-issue-93243.uw6x5z.rst @@ -0,0 +1 @@ +The :mod:`smtpd` module was removed per the schedule in :pep:`594`. diff --git a/PCbuild/lib.pyproj b/PCbuild/lib.pyproj index 0556efe1a77..e8c99f6b246 100644 --- a/PCbuild/lib.pyproj +++ b/PCbuild/lib.pyproj @@ -642,7 +642,6 @@ <Compile Include="shutil.py" /> <Compile Include="signal.py" /> <Compile Include="site.py" /> - <Compile Include="smtpd.py" /> <Compile Include="smtplib.py" /> <Compile Include="sndhdr.py" /> <Compile Include="socket.py" /> @@ -760,6 +759,7 @@ <Compile Include="test\sample_doctest_no_doctests.py" /> <Compile Include="test\seq_tests.py" /> <Compile Include="test\signalinterproctester.py" /> + <Compile Include="test\smtpd.py" /> <Compile Include="test\sortperf.py" /> <Compile Include="test\ssltests.py" /> <Compile Include="test\ssl_servers.py" /> @@ -1261,7 +1261,6 @@ <Compile Include="test\test_signal.py" /> <Compile Include="test\test_site.py" /> <Compile Include="test\test_slice.py" /> - <Compile Include="test\test_smtpd.py" /> <Compile Include="test\test_smtplib.py" /> <Compile Include="test\test_smtpnet.py" /> <Compile Include="test\test_sndhdr.py" /> diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index ff422e72301..b28156608d1 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -241,7 +241,6 @@ static const char* _Py_stdlib_module_names[] = { "shutil", "signal", "site", -"smtpd", "smtplib", "sndhdr", "socket", diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py index 07450ac928d..695e6ffc31f 100755 --- a/Tools/wasm/wasm_assets.py +++ b/Tools/wasm/wasm_assets.py @@ -77,7 +77,6 @@ "mailcap.py", "nntplib.py", "poplib.py", - "smtpd.py", "smtplib.py", "socketserver.py", "telnetlib.py", From webhook-mailer at python.org Sat Aug 6 02:55:42 2022 From: webhook-mailer at python.org (corona10) Date: Sat, 06 Aug 2022 06:55:42 -0000 Subject: [Python-checkins] gh-95385 Fastpath for encoding dict to JSON (gh-95374) Message-ID: <mailman.544.1659768942.3313.python-checkins@python.org> https://github.com/python/cpython/commit/15f4a35487d5ed9eb1edfdb9169eae6f5ad0874a commit: 15f4a35487d5ed9eb1edfdb9169eae6f5ad0874a branch: main author: Aivars Kalv?ns <aivars.kalvans at gmail.com> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-06T15:55:24+09:00 summary: gh-95385 Fastpath for encoding dict to JSON (gh-95374) files: A Misc/NEWS.d/next/Library/2022-07-28-17-14-38.gh-issue-95385.6YlsDI.rst M Modules/_json.c diff --git a/Misc/NEWS.d/next/Library/2022-07-28-17-14-38.gh-issue-95385.6YlsDI.rst b/Misc/NEWS.d/next/Library/2022-07-28-17-14-38.gh-issue-95385.6YlsDI.rst new file mode 100644 index 00000000000..89fa9c2b276 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-28-17-14-38.gh-issue-95385.6YlsDI.rst @@ -0,0 +1 @@ +Faster ``json.dumps()`` when sorting of keys is not requested (default). diff --git a/Modules/_json.c b/Modules/_json.c index 7ea84efdb91..1c39b46937d 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -12,6 +12,7 @@ #include "Python.h" #include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "structmember.h" // PyMemberDef +#include <stdbool.h> // bool typedef struct _PyScannerObject { @@ -1491,17 +1492,79 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, } } +static int +encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *first, + PyObject *key, PyObject *value, Py_ssize_t indent_level) +{ + PyObject *keystr = NULL; + PyObject *encoded; + + if (PyUnicode_Check(key)) { + Py_INCREF(key); + keystr = key; + } + else if (PyFloat_Check(key)) { + keystr = encoder_encode_float(s, key); + } + else if (key == Py_True || key == Py_False || key == Py_None) { + /* This must come before the PyLong_Check because + True and False are also 1 and 0.*/ + keystr = _encoded_const(key); + } + else if (PyLong_Check(key)) { + keystr = PyLong_Type.tp_repr(key); + } + else if (s->skipkeys) { + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "keys must be str, int, float, bool or None, " + "not %.100s", Py_TYPE(key)->tp_name); + return -1; + } + + if (keystr == NULL) { + return -1; + } + + if (*first) { + *first = false; + } + else { + if (_PyUnicodeWriter_WriteStr(writer, s->item_separator) < 0) { + Py_DECREF(keystr); + return -1; + } + } + + encoded = encoder_encode_string(s, keystr); + Py_DECREF(keystr); + if (encoded == NULL) { + return -1; + } + + if (_steal_accumulate(writer, encoded) < 0) { + return -1; + } + if (_PyUnicodeWriter_WriteStr(writer, s->key_separator) < 0) { + return -1; + } + if (encoder_listencode_obj(s, writer, value, indent_level) < 0) { + return -1; + } + return 0; +} + static int encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *dct, Py_ssize_t indent_level) { /* Encode Python dict dct a JSON term */ - PyObject *kstr = NULL; PyObject *ident = NULL; - PyObject *it = NULL; - PyObject *items; - PyObject *item = NULL; - Py_ssize_t idx; + PyObject *items = NULL; + PyObject *key, *value; + bool first = true; if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ return _PyUnicodeWriter_WriteASCIIString(writer, "{}", 2); @@ -1535,84 +1598,34 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, */ } - items = PyMapping_Items(dct); - if (items == NULL) - goto bail; - if (s->sort_keys && PyList_Sort(items) < 0) { - Py_DECREF(items); - goto bail; - } - it = PyObject_GetIter(items); - Py_DECREF(items); - if (it == NULL) - goto bail; - idx = 0; - while ((item = PyIter_Next(it)) != NULL) { - PyObject *encoded, *key, *value; - if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { - PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); + if (s->sort_keys) { + + items = PyDict_Items(dct); + if (items == NULL || PyList_Sort(items) < 0) goto bail; - } - key = PyTuple_GET_ITEM(item, 0); - if (PyUnicode_Check(key)) { - Py_INCREF(key); - kstr = key; - } - else if (PyFloat_Check(key)) { - kstr = encoder_encode_float(s, key); - if (kstr == NULL) - goto bail; - } - else if (key == Py_True || key == Py_False || key == Py_None) { - /* This must come before the PyLong_Check because - True and False are also 1 and 0.*/ - kstr = _encoded_const(key); - if (kstr == NULL) - goto bail; - } - else if (PyLong_Check(key)) { - kstr = PyLong_Type.tp_repr(key); - if (kstr == NULL) { + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(items); i++) { + PyObject *item = PyList_GET_ITEM(items, i); + + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { + PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); goto bail; } - } - else if (s->skipkeys) { - Py_DECREF(item); - continue; - } - else { - PyErr_Format(PyExc_TypeError, - "keys must be str, int, float, bool or None, " - "not %.100s", Py_TYPE(key)->tp_name); - goto bail; - } - if (idx) { - if (_PyUnicodeWriter_WriteStr(writer, s->item_separator)) + key = PyTuple_GET_ITEM(item, 0); + value = PyTuple_GET_ITEM(item, 1); + if (encoder_encode_key_value(s, writer, &first, key, value, indent_level) < 0) goto bail; } + Py_CLEAR(items); - encoded = encoder_encode_string(s, kstr); - Py_CLEAR(kstr); - if (encoded == NULL) - goto bail; - if (_PyUnicodeWriter_WriteStr(writer, encoded)) { - Py_DECREF(encoded); - goto bail; + } else { + Py_ssize_t pos = 0; + while (PyDict_Next(dct, &pos, &key, &value)) { + if (encoder_encode_key_value(s, writer, &first, key, value, indent_level) < 0) + goto bail; } - Py_DECREF(encoded); - if (_PyUnicodeWriter_WriteStr(writer, s->key_separator)) - goto bail; - - value = PyTuple_GET_ITEM(item, 1); - if (encoder_listencode_obj(s, writer, value, indent_level)) - goto bail; - idx += 1; - Py_DECREF(item); } - if (PyErr_Occurred()) - goto bail; - Py_CLEAR(it); if (ident != NULL) { if (PyDict_DelItem(s->markers, ident)) @@ -1630,14 +1643,11 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, return 0; bail: - Py_XDECREF(it); - Py_XDECREF(item); - Py_XDECREF(kstr); + Py_XDECREF(items); Py_XDECREF(ident); return -1; } - static int encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *seq, Py_ssize_t indent_level) From webhook-mailer at python.org Sat Aug 6 11:56:10 2022 From: webhook-mailer at python.org (ericvsmith) Date: Sat, 06 Aug 2022 15:56:10 -0000 Subject: [Python-checkins] Fix typo in test_dataclasses.py (gh-95735) Message-ID: <mailman.545.1659801371.3313.python-checkins@python.org> https://github.com/python/cpython/commit/59e09efe888affe549e9249f188797c1325edecc commit: 59e09efe888affe549e9249f188797c1325edecc branch: main author: da-woods <dw-git at d-woods.co.uk> committer: ericvsmith <ericvsmith at users.noreply.github.com> date: 2022-08-06T11:56:00-04:00 summary: Fix typo in test_dataclasses.py (gh-95735) `dataclass` was called as a function when it was almost certainly intended to be a decorator. files: M Lib/test/test_dataclasses.py diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index cfa82093dfb..e2eab695789 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2215,12 +2215,12 @@ class C(B): self.assertEqual(c.z, 100) def test_no_init(self): - dataclass(init=False) + @dataclass(init=False) class C: i: int = 0 self.assertEqual(C().i, 0) - dataclass(init=False) + @dataclass(init=False) class C: i: int = 2 def __init__(self): From webhook-mailer at python.org Sat Aug 6 12:16:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 06 Aug 2022 16:16:05 -0000 Subject: [Python-checkins] Fix typo in test_dataclasses.py (gh-95735) Message-ID: <mailman.546.1659802567.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9a23f582ee0c64954b930c9c03d1fd02ce8d4044 commit: 9a23f582ee0c64954b930c9c03d1fd02ce8d4044 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-06T09:16:01-07:00 summary: Fix typo in test_dataclasses.py (gh-95735) `dataclass` was called as a function when it was almost certainly intended to be a decorator. (cherry picked from commit 59e09efe888affe549e9249f188797c1325edecc) Co-authored-by: da-woods <dw-git at d-woods.co.uk> files: M Lib/test/test_dataclasses.py diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index f4f7ed5acab4..f72e81c31e61 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2129,12 +2129,12 @@ class C(B): self.assertEqual(c.z, 100) def test_no_init(self): - dataclass(init=False) + @dataclass(init=False) class C: i: int = 0 self.assertEqual(C().i, 0) - dataclass(init=False) + @dataclass(init=False) class C: i: int = 2 def __init__(self): From webhook-mailer at python.org Sat Aug 6 12:50:35 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 16:50:35 -0000 Subject: [Python-checkins] gh-95155: Update "Using Python on a Mac" documentation (GH-95284) Message-ID: <mailman.547.1659804636.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d25ff1f61387edd65a91b3930b12bcf4d734e8a1 commit: d25ff1f61387edd65a91b3930b12bcf4d734e8a1 branch: main author: Howie Zhao <howiezhaohr at hotmail.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T18:50:28+02:00 summary: gh-95155: Update "Using Python on a Mac" documentation (GH-95284) Co-authored-by: ?ukasz Langa <lukasz at langa.pl> files: M Doc/using/mac.rst diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index f85b5bd2e713..9ae0270eaee7 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -17,15 +17,16 @@ the IDE and the Package Manager that are worth pointing out. Getting and Installing MacPython ================================ -macOS since version 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you -are invited to install the most recent version of Python 3 from the Python +macOS used to come with Python 2.7 pre-installed between versions +10.8 and `12.3 <https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes#Python>`_. +You are invited to install the most recent version of Python 3 from the Python website (https://www.python.org). A current "universal binary" build of Python, which runs natively on the Mac's new Intel and legacy PPC CPU's, is available there. What you get after installing is a number of things: -* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here +* A :file:`Python 3.12` folder in your :file:`Applications` folder. In here you find IDLE, the development environment that is a standard part of official Python distributions; and PythonLauncher, which handles double-clicking Python scripts from the Finder. From webhook-mailer at python.org Sat Aug 6 12:52:57 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 16:52:57 -0000 Subject: [Python-checkins] gh-95395: Add argument type error test (GH-95412) Message-ID: <mailman.548.1659804778.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4703c158116bd157e20938bbf5356b79422470bb commit: 4703c158116bd157e20938bbf5356b79422470bb branch: main author: Sion Kang <31057849+Yaminyam at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T18:52:53+02:00 summary: gh-95395: Add argument type error test (GH-95412) files: M Lib/test/test_grp.py diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index c7ec03ec0e4..e52e17b8dc7 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -49,10 +49,12 @@ def test_values_extended(self): def test_errors(self): self.assertRaises(TypeError, grp.getgrgid) + self.assertRaises(TypeError, grp.getgrgid, 3.14) self.assertRaises(TypeError, grp.getgrnam) + self.assertRaises(TypeError, grp.getgrnam, 42) self.assertRaises(TypeError, grp.getgrall, 42) # embedded null character - self.assertRaises(ValueError, grp.getgrnam, 'a\x00b') + self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b') # try to get some errors bynames = {} From webhook-mailer at python.org Sat Aug 6 12:53:24 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 16:53:24 -0000 Subject: =?iso-8859-1?q?_=5BPython-checkins=5D_=08gh-95376=3A_Add_test_fo?= =?iso-8859-1?q?r_names_containing_null_=28=23GH-5394=29?= Message-ID: <mailman.549.1659804804.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a17cd47b614f8bc660788647a009a25e121221d7 commit: a17cd47b614f8bc660788647a009a25e121221d7 branch: main author: Sion Kang <31057849+Yaminyam at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T18:53:19+02:00 summary: gh-95376: Add test for names containing null (#GH-5394) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> files: M Lib/test/test_pwd.py diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index c789326425b..aa090b464a7 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -59,6 +59,8 @@ def test_errors(self): self.assertRaises(TypeError, pwd.getpwnam) self.assertRaises(TypeError, pwd.getpwnam, 42) self.assertRaises(TypeError, pwd.getpwall, 42) + # embedded null character + self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b') # try to get some errors bynames = {} From webhook-mailer at python.org Sat Aug 6 12:55:53 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 16:55:53 -0000 Subject: [Python-checkins] gh-95251: IDLE - Add What's New section to README (GH-95688) (GH-95726) Message-ID: <mailman.550.1659804954.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1f48913db3ad35a73ae85717f579e2f0e7a5cc38 commit: 1f48913db3ad35a73ae85717f579e2f0e7a5cc38 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T18:55:49+02:00 summary: gh-95251: IDLE - Add What's New section to README (GH-95688) (GH-95726) Document what I (TJR) currently do for 3.10/3.11. Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> (cherry picked from commit a302a274892f2dad4e1fa492c4886d55e4df0a80) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 67de2be26256..779b51c1b931 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -243,8 +243,8 @@ OTHER TOPICS Generally use PEP 8. -import ------- +import statements +----------------- Put imports at the top, unless there is a good reason otherwise. PEP 8 says to group stdlib, 3rd-party dependencies, and package imports. For idlelib, the groups are general stdlib, tkinter, and idlelib. @@ -259,3 +259,24 @@ htest function def or "if __name__ == '__main__'" clause. Within module imports like "from idlelib.mod import class" may cause circular imports to deadlock. Even without this, circular imports may require at least one of the imports to be delayed until a function call. + +What's New entries +------------------ + +Repository directory Doc/whatsnew/ has a file 3.n.rst for each 3.n +Python version. For the first entry in each file, add subsection +'IDLE and idlelib', in alphabetical position, to the 'Improved Modules' +section. For the rest of cpython, entries to 3.(n+1).rst begin with +the release of 3.n.0b1. For IDLE, entries for features backported from +'main' to '3.n' during its beta period do not got in 3.(n+1).rst. The +latter usually gets its first entry during the 3.n.0 candidate period +or after the 3.n.0 release. + +When, as per PEP 434, feature changes are backported, entries are placed +in the 3.n.rst file *in the main branch* for each Python version n that +gets the backport. (Note: the format of entries have varied between +versions.) Add a line "New in 3.n maintenance releases." before the +first back-ported feature after 3.n.0 is released. Since each older +version file gets a different number of backports, it is easiest to +make a separate PR for each file and label it with the backports +needed. From webhook-mailer at python.org Sat Aug 6 13:01:16 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:01:16 -0000 Subject: [Python-checkins] gh-89362: Doc IDLE menu and search (GH-95697) (GH-95718) Message-ID: <mailman.551.1659805278.3313.python-checkins@python.org> https://github.com/python/cpython/commit/11f7d41ccf369a6400fff9321955f17f5aa8d4ff commit: 11f7d41ccf369a6400fff9321955f17f5aa8d4ff branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:01:10+02:00 summary: gh-89362: Doc IDLE menu and search (GH-95697) (GH-95718) Update menu item position and capitalization. Add paragraph about search. For help.html, include save-as addition. (cherry picked from commit 834064c19a110dad425dc290c91c0545eaa24471) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/library/idle.rst M Lib/idlelib/help.html diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 2d52e5355749..f2ef72d682bd 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -61,17 +61,17 @@ New File Open... Open an existing file with an Open dialog. -Recent Files - Open a list of recent files. Click one to open it. - Open Module... Open an existing module (searches sys.path). +Recent Files + Open a list of recent files. Click one to open it. + .. index:: - single: Class browser + single: Module browser single: Path browser -Class Browser +Module Browser Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first. @@ -89,7 +89,7 @@ Save As... Save the current window with a Save As dialog. The file saved becomes the new associated file for the window. (If your file namager is set to hide extensions, the current extension will be omitted in the file name box. - If the new filename has no '.', '.py' and .'txt' will be added for Python + If the new filename has no '.', '.py' and '.txt' will be added for Python and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... @@ -117,6 +117,9 @@ Undo Redo Redo the last undone change to the current window. +Select All + Select the entire contents of the current window. + Cut Copy selection into the system-wide clipboard; then delete the selection. @@ -128,9 +131,6 @@ Paste The clipboard functions are also available in context menus. -Select All - Select the entire contents of the current window. - Find... Open a search dialog with many options @@ -159,12 +159,12 @@ Expand Word Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion. -Show call tip +Show Call Tip After an unclosed parenthesis for a function, open a small window with function parameter hints. See :ref:`Calltips <calltips>` in the Editing and navigation section below. -Show surrounding parens +Show Surrounding Parens Highlight the surrounding parenthesis. .. _format-menu: @@ -172,6 +172,11 @@ Show surrounding parens Format menu (Editor window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Format Paragraph + Reformat the current blank-line-delimited paragraph in comment block or + multiline string or selected line in a string. All lines in the + paragraph will be formatted to less than N columns, where N defaults to 72. + Indent Region Shift selected lines right by the indent width (default 4 spaces). @@ -198,12 +203,7 @@ New Indent Width Open a dialog to change indent width. The accepted default by the Python community is 4 spaces. -Format Paragraph - Reformat the current blank-line-delimited paragraph in comment block or - multiline string or selected line in a string. All lines in the - paragraph will be formatted to less than N columns, where N defaults to 72. - -Strip trailing whitespace +Strip Trailing Chitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, @@ -474,6 +474,14 @@ are restricted to four spaces due to Tcl/Tk limitations. See also the indent/dedent region commands on the :ref:`Format menu <format-menu>`. +Search and Replace +^^^^^^^^^^^^^^^^^^ + +Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If ``[x] Regular expresion`` is checked, the +target is interpreted according to the Python re module. + .. _completions: Completions diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index e8e7d2876097..ac386122cc71 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -91,6 +91,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#editor-windows">Editor windows</a></li> <li><a class="reference internal" href="#key-bindings">Key bindings</a></li> <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li> +<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li> <li><a class="reference internal" href="#completions">Completions</a></li> <li><a class="reference internal" href="#calltips">Calltips</a></li> <li><a class="reference internal" href="#code-context">Code Context</a></li> @@ -237,13 +238,13 @@ <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and </dd> <dt>Open?</dt><dd><p>Open an existing file with an Open dialog.</p> </dd> -<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p> -</dd> <dt>Open Module?</dt><dd><p>Open an existing module (searches sys.path).</p> </dd> +<dt>Recent Files</dt><dd><p>Open a list of recent files. Click one to open it.</p> +</dd> </dl> <dl class="simple" id="index-1"> -<dt>Class Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a +<dt>Module Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first.</p> </dd> <dt>Path Browser</dt><dd><p>Show sys.path directories, modules, functions, classes and methods in a @@ -255,10 +256,13 @@ <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and do Save As instead.</p> </dd> <dt>Save As?</dt><dd><p>Save the current window with a Save As dialog. The file saved becomes the -new associated file for the window.</p> +new associated file for the window. (If your file namager is set to hide +extensions, the current extension will be omitted in the file name box. +If the new filename has no ?.?, ?.py? and ?.txt? will be added for Python +and text files, except that on macOS Aqua,?.py? is added for all files.)</p> </dd> <dt>Save Copy As?</dt><dd><p>Save the current window to different file without changing the associated -file.</p> +file. (See Save As note above about filename extensions.)</p> </dd> <dt>Print Window</dt><dd><p>Print the current window to the default printer.</p> </dd> @@ -278,6 +282,8 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and </dd> <dt>Redo</dt><dd><p>Redo the last undone change to the current window.</p> </dd> +<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p> +</dd> <dt>Cut</dt><dd><p>Copy selection into the system-wide clipboard; then delete the selection.</p> </dd> <dt>Copy</dt><dd><p>Copy selection into the system-wide clipboard.</p> @@ -287,8 +293,6 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and </dl> <p>The clipboard functions are also available in context menus.</p> <dl class="simple"> -<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p> -</dd> <dt>Find?</dt><dd><p>Open a search dialog with many options</p> </dd> <dt>Find Again</dt><dd><p>Repeat the last search, if there is one.</p> @@ -309,17 +313,21 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and <dt>Expand Word</dt><dd><p>Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion.</p> </dd> -<dt>Show call tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with +<dt>Show Call Tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with function parameter hints. See <a class="reference internal" href="#calltips"><span class="std std-ref">Calltips</span></a> in the Editing and navigation section below.</p> </dd> -<dt>Show surrounding parens</dt><dd><p>Highlight the surrounding parenthesis.</p> +<dt>Show Surrounding Parens</dt><dd><p>Highlight the surrounding parenthesis.</p> </dd> </dl> </section> <section id="format-menu-editor-window-only"> <span id="format-menu"></span><h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this heading">?</a></h3> <dl class="simple"> +<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or +multiline string or selected line in a string. All lines in the +paragraph will be formatted to less than N columns, where N defaults to 72.</p> +</dd> <dt>Indent Region</dt><dd><p>Shift selected lines right by the indent width (default 4 spaces).</p> </dd> <dt>Dedent Region</dt><dd><p>Shift selected lines left by the indent width (default 4 spaces).</p> @@ -338,11 +346,7 @@ <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and <dt>New Indent Width</dt><dd><p>Open a dialog to change indent width. The accepted default by the Python community is 4 spaces.</p> </dd> -<dt>Format Paragraph</dt><dd><p>Reformat the current blank-line-delimited paragraph in comment block or -multiline string or selected line in a string. All lines in the -paragraph will be formatted to less than N columns, where N defaults to 72.</p> -</dd> -<dt>Strip trailing whitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last +<dt>Strip Trailing Chitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, remove extra newlines at the end of the file.</p> @@ -565,6 +569,13 @@ <h3>Automatic indentation<a class="headerlink" href="#automatic-indentation" tit <p>See also the indent/dedent region commands on the <a class="reference internal" href="#format-menu"><span class="std std-ref">Format menu</span></a>.</p> </section> +<section id="search-and-replace"> +<h3>Search and Replace<a class="headerlink" href="#search-and-replace" title="Permalink to this heading">?</a></h3> +<p>Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If <code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">Regular</span> <span class="pre">expresion</span></code> is checked, the +target is interpreted according to the Python re module.</p> +</section> <section id="completions"> <span id="id3"></span><h3>Completions<a class="headerlink" href="#completions" title="Permalink to this heading">?</a></h3> <p>Completions are supplied, when requested and available, for module @@ -1021,6 +1032,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#editor-windows">Editor windows</a></li> <li><a class="reference internal" href="#key-bindings">Key bindings</a></li> <li><a class="reference internal" href="#automatic-indentation">Automatic indentation</a></li> +<li><a class="reference internal" href="#search-and-replace">Search and Replace</a></li> <li><a class="reference internal" href="#completions">Completions</a></li> <li><a class="reference internal" href="#calltips">Calltips</a></li> <li><a class="reference internal" href="#code-context">Code Context</a></li> @@ -1141,7 +1153,7 @@ <h3>Navigation</h3> <br /> <br /> - Last updated on Jul 03, 2022. + Last updated on Aug 05, 2022. <a href="/bugs.html">Found a bug</a>? <br /> From webhook-mailer at python.org Sat Aug 6 13:15:37 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:15:37 -0000 Subject: [Python-checkins] gh-95155: Update "Using Python on a Mac" documentation (GH-95284) (GH-95743) Message-ID: <mailman.552.1659806137.3313.python-checkins@python.org> https://github.com/python/cpython/commit/32b71ffbdbf6223ec0ce4dedf9b99e26b9c9730c commit: 32b71ffbdbf6223ec0ce4dedf9b99e26b9c9730c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:15:32+02:00 summary: gh-95155: Update "Using Python on a Mac" documentation (GH-95284) (GH-95743) Co-authored-by: ?ukasz Langa <lukasz at langa.pl> (cherry picked from commit d25ff1f61387edd65a91b3930b12bcf4d734e8a1) Co-authored-by: Howie Zhao <howiezhaohr at hotmail.com> files: M Doc/using/mac.rst diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index f85b5bd2e713..9ae0270eaee7 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -17,15 +17,16 @@ the IDE and the Package Manager that are worth pointing out. Getting and Installing MacPython ================================ -macOS since version 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you -are invited to install the most recent version of Python 3 from the Python +macOS used to come with Python 2.7 pre-installed between versions +10.8 and `12.3 <https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes#Python>`_. +You are invited to install the most recent version of Python 3 from the Python website (https://www.python.org). A current "universal binary" build of Python, which runs natively on the Mac's new Intel and legacy PPC CPU's, is available there. What you get after installing is a number of things: -* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here +* A :file:`Python 3.12` folder in your :file:`Applications` folder. In here you find IDLE, the development environment that is a standard part of official Python distributions; and PythonLauncher, which handles double-clicking Python scripts from the Finder. From webhook-mailer at python.org Sat Aug 6 13:15:52 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:15:52 -0000 Subject: [Python-checkins] gh-95155: Update "Using Python on a Mac" documentation (GH-95284) (GH-95742) Message-ID: <mailman.553.1659806152.3313.python-checkins@python.org> https://github.com/python/cpython/commit/96c1f013b3ea142616979f0b02fee81a7b41eb70 commit: 96c1f013b3ea142616979f0b02fee81a7b41eb70 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:15:48+02:00 summary: gh-95155: Update "Using Python on a Mac" documentation (GH-95284) (GH-95742) Co-authored-by: ?ukasz Langa <lukasz at langa.pl> (cherry picked from commit d25ff1f61387edd65a91b3930b12bcf4d734e8a1) Co-authored-by: Howie Zhao <howiezhaohr at hotmail.com> files: M Doc/using/mac.rst diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index f85b5bd2e713..9ae0270eaee7 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -17,15 +17,16 @@ the IDE and the Package Manager that are worth pointing out. Getting and Installing MacPython ================================ -macOS since version 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you -are invited to install the most recent version of Python 3 from the Python +macOS used to come with Python 2.7 pre-installed between versions +10.8 and `12.3 <https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes#Python>`_. +You are invited to install the most recent version of Python 3 from the Python website (https://www.python.org). A current "universal binary" build of Python, which runs natively on the Mac's new Intel and legacy PPC CPU's, is available there. What you get after installing is a number of things: -* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here +* A :file:`Python 3.12` folder in your :file:`Applications` folder. In here you find IDLE, the development environment that is a standard part of official Python distributions; and PythonLauncher, which handles double-clicking Python scripts from the Finder. From webhook-mailer at python.org Sat Aug 6 13:30:33 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:30:33 -0000 Subject: [Python-checkins] gh-95395: Add argument type error test (GH-95412) (GH-95745) Message-ID: <mailman.554.1659807035.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9278fc4e27d7b4bad03cb0976fff80828b149ed2 commit: 9278fc4e27d7b4bad03cb0976fff80828b149ed2 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:30:29+02:00 summary: gh-95395: Add argument type error test (GH-95412) (GH-95745) (cherry picked from commit 4703c158116bd157e20938bbf5356b79422470bb) Co-authored-by: Sion Kang <31057849+Yaminyam at users.noreply.github.com> files: M Lib/test/test_grp.py diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index c7ec03ec0e4..e52e17b8dc7 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -49,10 +49,12 @@ def test_values_extended(self): def test_errors(self): self.assertRaises(TypeError, grp.getgrgid) + self.assertRaises(TypeError, grp.getgrgid, 3.14) self.assertRaises(TypeError, grp.getgrnam) + self.assertRaises(TypeError, grp.getgrnam, 42) self.assertRaises(TypeError, grp.getgrall, 42) # embedded null character - self.assertRaises(ValueError, grp.getgrnam, 'a\x00b') + self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b') # try to get some errors bynames = {} From webhook-mailer at python.org Sat Aug 6 13:30:50 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:30:50 -0000 Subject: [Python-checkins] gh-95395: Add argument type error test (GH-95412) (GH-95744) Message-ID: <mailman.555.1659807052.3313.python-checkins@python.org> https://github.com/python/cpython/commit/08510324db019ea8bd3c54de6860aed06cb47af1 commit: 08510324db019ea8bd3c54de6860aed06cb47af1 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:30:46+02:00 summary: gh-95395: Add argument type error test (GH-95412) (GH-95744) (cherry picked from commit 4703c158116bd157e20938bbf5356b79422470bb) Co-authored-by: Sion Kang <31057849+Yaminyam at users.noreply.github.com> files: M Lib/test/test_grp.py diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index c7ec03ec0e43..e52e17b8dc73 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -49,10 +49,12 @@ def test_values_extended(self): def test_errors(self): self.assertRaises(TypeError, grp.getgrgid) + self.assertRaises(TypeError, grp.getgrgid, 3.14) self.assertRaises(TypeError, grp.getgrnam) + self.assertRaises(TypeError, grp.getgrnam, 42) self.assertRaises(TypeError, grp.getgrall, 42) # embedded null character - self.assertRaises(ValueError, grp.getgrnam, 'a\x00b') + self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b') # try to get some errors bynames = {} From webhook-mailer at python.org Sat Aug 6 13:32:02 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:32:02 -0000 Subject: =?iso-8859-1?q?_=5BPython-checkins=5D_=08gh-95376=3A_Add_test_fo?= =?iso-8859-1?q?r_names_containing_null_=28GH-GH-5394=29_=28=23GH-5746=29?= Message-ID: <mailman.556.1659807122.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6dffb5f1cfe4b1ae30ce726907161b87f915c87d commit: 6dffb5f1cfe4b1ae30ce726907161b87f915c87d branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:31:58+02:00 summary: gh-95376: Add test for names containing null (GH-GH-5394) (#GH-5746) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> (cherry picked from commit a17cd47b614f8bc660788647a009a25e121221d7) Co-authored-by: Sion Kang <31057849+Yaminyam at users.noreply.github.com> files: M Lib/test/test_pwd.py diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index c789326425b..aa090b464a7 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -59,6 +59,8 @@ def test_errors(self): self.assertRaises(TypeError, pwd.getpwnam) self.assertRaises(TypeError, pwd.getpwnam, 42) self.assertRaises(TypeError, pwd.getpwall, 42) + # embedded null character + self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b') # try to get some errors bynames = {} From webhook-mailer at python.org Sat Aug 6 13:32:31 2022 From: webhook-mailer at python.org (ambv) Date: Sat, 06 Aug 2022 17:32:31 -0000 Subject: [Python-checkins] gh-95376: Add test for names containing null (GH-GH-5394) (GH-95747) Message-ID: <mailman.557.1659807152.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f05a0f48e82ba5759f2e405de58ce0d0028b0af6 commit: f05a0f48e82ba5759f2e405de58ce0d0028b0af6 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-06T19:32:27+02:00 summary: gh-95376: Add test for names containing null (GH-GH-5394) (GH-95747) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com> (cherry picked from commit a17cd47b614f8bc660788647a009a25e121221d7) Co-authored-by: Sion Kang <31057849+Yaminyam at users.noreply.github.com> files: M Lib/test/test_pwd.py diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index f8f12571ca9..d217e059808 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -59,6 +59,8 @@ def test_errors(self): self.assertRaises(TypeError, pwd.getpwnam) self.assertRaises(TypeError, pwd.getpwnam, 42) self.assertRaises(TypeError, pwd.getpwall, 42) + # embedded null character + self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b') # try to get some errors bynames = {} From webhook-mailer at python.org Sat Aug 6 17:30:55 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Sat, 06 Aug 2022 21:30:55 -0000 Subject: [Python-checkins] gh-94635: Fixup sqlite3 'Introduction' seealso note (#95751) Message-ID: <mailman.558.1659821456.3313.python-checkins@python.org> https://github.com/python/cpython/commit/56af5a200d60e86a8ac450264729d693053275e3 commit: 56af5a200d60e86a8ac450264729d693053275e3 branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-06T23:30:26+02:00 summary: gh-94635: Fixup sqlite3 'Introduction' seealso note (#95751) In gh-95269, the seealso note incorrectly ended up in the 'Tutorial' section. files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 140dccfea94b..83f29287120e 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -34,6 +34,18 @@ This document includes four main sections: * :ref:`sqlite3-explanation` provides in-depth background on transaction control. +.. seealso:: + + https://www.sqlite.org + The SQLite web page; the documentation describes the syntax and the + available data types for the supported SQL dialect. + + https://www.w3schools.com/sql/ + Tutorial, reference and examples for learning SQL syntax. + + :pep:`249` - Database API Specification 2.0 + PEP written by Marc-Andr? Lemburg. + .. _sqlite3-tutorial: @@ -114,18 +126,6 @@ You've now created an SQLite database using the :mod:`!sqlite3` module. .. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection -.. seealso:: - - https://www.sqlite.org - The SQLite web page; the documentation describes the syntax and the - available data types for the supported SQL dialect. - - https://www.w3schools.com/sql/ - Tutorial, reference and examples for learning SQL syntax. - - :pep:`249` - Database API Specification 2.0 - PEP written by Marc-Andr? Lemburg. - .. _sqlite3-reference: From webhook-mailer at python.org Sat Aug 6 17:38:28 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 06 Aug 2022 21:38:28 -0000 Subject: [Python-checkins] gh-94635: Fixup sqlite3 'Introduction' seealso note (GH-95751) Message-ID: <mailman.559.1659821910.3313.python-checkins@python.org> https://github.com/python/cpython/commit/255f7ded778206e79de6f901c0ccfa2405c64aa8 commit: 255f7ded778206e79de6f901c0ccfa2405c64aa8 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-06T14:38:18-07:00 summary: gh-94635: Fixup sqlite3 'Introduction' seealso note (GH-95751) In gh-95269, the seealso note incorrectly ended up in the 'Tutorial' section. (cherry picked from commit 56af5a200d60e86a8ac450264729d693053275e3) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 88cd5527b492..f711505d9229 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -34,6 +34,18 @@ This document includes four main sections: * :ref:`sqlite3-explanation` provides in-depth background on transaction control. +.. seealso:: + + https://www.sqlite.org + The SQLite web page; the documentation describes the syntax and the + available data types for the supported SQL dialect. + + https://www.w3schools.com/sql/ + Tutorial, reference and examples for learning SQL syntax. + + :pep:`249` - Database API Specification 2.0 + PEP written by Marc-Andr? Lemburg. + .. _sqlite3-tutorial: @@ -114,18 +126,6 @@ You've now created an SQLite database using the :mod:`!sqlite3` module. .. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection -.. seealso:: - - https://www.sqlite.org - The SQLite web page; the documentation describes the syntax and the - available data types for the supported SQL dialect. - - https://www.w3schools.com/sql/ - Tutorial, reference and examples for learning SQL syntax. - - :pep:`249` - Database API Specification 2.0 - PEP written by Marc-Andr? Lemburg. - .. _sqlite3-reference: From webhook-mailer at python.org Sat Aug 6 19:21:32 2022 From: webhook-mailer at python.org (gpshead) Date: Sat, 06 Aug 2022 23:21:32 -0000 Subject: [Python-checkins] gh-88339: enable fast seeking of uncompressed unencrypted zipfile.ZipExtFile (GH-27737) Message-ID: <mailman.560.1659828094.3313.python-checkins@python.org> https://github.com/python/cpython/commit/330f1d58282517bdf1f19577ab9317fa9810bf95 commit: 330f1d58282517bdf1f19577ab9317fa9810bf95 branch: main author: JuniorJPDJ <github.com at juniorjpdj.pl> committer: gpshead <greg at krypto.org> date: 2022-08-06T16:21:23-07:00 summary: gh-88339: enable fast seeking of uncompressed unencrypted zipfile.ZipExtFile (GH-27737) Avoid reading all of the intermediate data in uncompressed items in a zip file when the user seeks forward. Contributed by: @JuniorJPDJ files: A Misc/NEWS.d/next/Library/2021-08-27-18-07-35.bpo-44173.oW92Ev.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index fa0ca5aa742..21257785159 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2032,6 +2032,7 @@ def test_seek_tell(self): fp.seek(bloc, os.SEEK_CUR) self.assertEqual(fp.tell(), bloc) self.assertEqual(fp.read(5), txt[bloc:bloc+5]) + self.assertEqual(fp.tell(), bloc + 5) fp.seek(0, os.SEEK_END) self.assertEqual(fp.tell(), len(txt)) fp.seek(0, os.SEEK_SET) @@ -2049,6 +2050,7 @@ def test_seek_tell(self): fp.seek(bloc, os.SEEK_CUR) self.assertEqual(fp.tell(), bloc) self.assertEqual(fp.read(5), txt[bloc:bloc+5]) + self.assertEqual(fp.tell(), bloc + 5) fp.seek(0, os.SEEK_END) self.assertEqual(fp.tell(), len(txt)) fp.seek(0, os.SEEK_SET) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index e3b7a61a639..981560082ca 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -847,6 +847,7 @@ def __init__(self, fileobj, mode, zipinfo, pwd=None, self._orig_compress_size = zipinfo.compress_size self._orig_file_size = zipinfo.file_size self._orig_start_crc = self._running_crc + self._orig_crc = self._expected_crc self._seekable = True except AttributeError: pass @@ -1069,17 +1070,17 @@ def seekable(self): raise ValueError("I/O operation on closed file.") return self._seekable - def seek(self, offset, whence=0): + def seek(self, offset, whence=os.SEEK_SET): if self.closed: raise ValueError("seek on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") curr_pos = self.tell() - if whence == 0: # Seek from start of file + if whence == os.SEEK_SET: new_pos = offset - elif whence == 1: # Seek from current position + elif whence == os.SEEK_CUR: new_pos = curr_pos + offset - elif whence == 2: # Seek from EOF + elif whence == os.SEEK_END: new_pos = self._orig_file_size + offset else: raise ValueError("whence must be os.SEEK_SET (0), " @@ -1094,7 +1095,19 @@ def seek(self, offset, whence=0): read_offset = new_pos - curr_pos buff_offset = read_offset + self._offset - if buff_offset >= 0 and buff_offset < len(self._readbuffer): + # Fast seek uncompressed unencrypted file + if self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: + # disable CRC checking after first seeking - it would be invalid + self._expected_crc = None + # seek actual file taking already buffered data into account + read_offset -= len(self._readbuffer) - self._offset + self._fileobj.seek(read_offset, os.SEEK_CUR) + self._left -= read_offset + read_offset = 0 + # flush read buffer + self._readbuffer = b'' + self._offset = 0 + elif buff_offset >= 0 and buff_offset < len(self._readbuffer): # Just move the _offset index if the new position is in the _readbuffer self._offset = buff_offset read_offset = 0 @@ -1102,6 +1115,7 @@ def seek(self, offset, whence=0): # Position is before the current position. Reset the ZipExtFile self._fileobj.seek(self._orig_compress_start) self._running_crc = self._orig_start_crc + self._expected_crc = self._orig_crc self._compress_left = self._orig_compress_size self._left = self._orig_file_size self._readbuffer = b'' diff --git a/Misc/NEWS.d/next/Library/2021-08-27-18-07-35.bpo-44173.oW92Ev.rst b/Misc/NEWS.d/next/Library/2021-08-27-18-07-35.bpo-44173.oW92Ev.rst new file mode 100644 index 00000000000..abc98266afb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-08-27-18-07-35.bpo-44173.oW92Ev.rst @@ -0,0 +1 @@ +Enable fast seeking of uncompressed unencrypted :class:`zipfile.ZipExtFile` From webhook-mailer at python.org Mon Aug 8 02:49:56 2022 From: webhook-mailer at python.org (rhettinger) Date: Mon, 08 Aug 2022 06:49:56 -0000 Subject: [Python-checkins] Fix documentation typo for functools.cmp_to_key (GH-95766) Message-ID: <mailman.561.1659941398.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f83b0cabeb101599e6b55e6a1c972d5b8cae18b2 commit: f83b0cabeb101599e6b55e6a1c972d5b8cae18b2 branch: main author: Andrzej Bartosi?ski <6197476+Neob91 at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-08T01:49:48-05:00 summary: Fix documentation typo for functools.cmp_to_key (GH-95766) files: M Doc/library/functools.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index dd4d76ef670..00aca09bc7a 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -119,7 +119,7 @@ The :mod:`functools` module defines the following functions: tool for programs being converted from Python 2 which supported the use of comparison functions. - A comparison function is any callable that accept two arguments, compares them, + A comparison function is any callable that accepts two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one argument and returns another value to be used as the sort key. From webhook-mailer at python.org Mon Aug 8 04:03:13 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 08 Aug 2022 08:03:13 -0000 Subject: [Python-checkins] docs: Fix a few typos (#94899) Message-ID: <mailman.562.1659945795.3313.python-checkins@python.org> https://github.com/python/cpython/commit/32b49f613afefe351b38ce42466a856c1df07544 commit: 32b49f613afefe351b38ce42466a856c1df07544 branch: main author: Tim Gates <tim.gates at iress.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-08T10:02:45+02:00 summary: docs: Fix a few typos (#94899) - overriden => overridden - calcualation => calculation Signed-off-by: Tim Gates <tim.gates at iress.com> files: M Misc/NEWS.d/3.9.0a1.rst M Modules/getpath.py M Objects/typeobject.c diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst index 45f232f1948d..eace8755a0d1 100644 --- a/Misc/NEWS.d/3.9.0a1.rst +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -5769,4 +5769,4 @@ Convert posixmodule.c statically allocated types ``DirEntryType`` and .. section: C API Use singular/plural noun in error message when instantiating an abstract -class with non-overriden abstract method(s). +class with non-overridden abstract method(s). diff --git a/Modules/getpath.py b/Modules/getpath.py index dceeed7702c0..a50313aea78b 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -422,7 +422,7 @@ def search_up(prefix, *landmarks, test=isfile): # ****************************************************************************** # The contents of an optional ._pth file are used to totally override -# sys.path calcualation. Its presence also implies isolated mode and +# sys.path calculation. Its presence also implies isolated mode and # no-site (unless explicitly requested) pth = None pth_dir = None diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b2df9e7fad38..da02e86f94ed 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5460,7 +5460,7 @@ object_getstate(PyObject *obj, int required) PyCFunction_GET_SELF(getstate) == obj && PyCFunction_GET_FUNCTION(getstate) == object___getstate__) { - /* If __getstate__ is not overriden pass the required argument. */ + /* If __getstate__ is not overridden pass the required argument. */ state = object_getstate_default(obj, required); } else { From webhook-mailer at python.org Mon Aug 8 04:59:12 2022 From: webhook-mailer at python.org (encukou) Date: Mon, 08 Aug 2022 08:59:12 -0000 Subject: [Python-checkins] Fix downcast compiler warning in Modules/_testcapi/vectorcall.c (#95729) Message-ID: <mailman.563.1659949153.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0c14f07256ffc53e2bd0fe68e48db9dfc90dd5dc commit: 0c14f07256ffc53e2bd0fe68e48db9dfc90dd5dc branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-08T10:58:29+02:00 summary: Fix downcast compiler warning in Modules/_testcapi/vectorcall.c (#95729) files: M Modules/_testcapi/vectorcall.c diff --git a/Modules/_testcapi/vectorcall.c b/Modules/_testcapi/vectorcall.c index 21846f97ff81..626706eafab5 100644 --- a/Modules/_testcapi/vectorcall.c +++ b/Modules/_testcapi/vectorcall.c @@ -214,7 +214,7 @@ _testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base) VectorCallClass_members[0].offset = base->tp_basicsize; PyType_Spec spec = { .name = "_testcapi.VectorcallClass", - .basicsize = base->tp_basicsize + (int)sizeof(vectorcallfunc), + .basicsize = (int)(base->tp_basicsize + sizeof(vectorcallfunc)), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_BASETYPE, From webhook-mailer at python.org Mon Aug 8 06:16:43 2022 From: webhook-mailer at python.org (encukou) Date: Mon, 08 Aug 2022 10:16:43 -0000 Subject: [Python-checkins] gh-95388: Suppress deprecation warning in test_immutable_type_with_mutable_base (GH-95728) Message-ID: <mailman.564.1659953803.3313.python-checkins@python.org> https://github.com/python/cpython/commit/78a85a34ea2583b8489eeafba5b2018fa2048a4d commit: 78a85a34ea2583b8489eeafba5b2018fa2048a4d branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-08T12:15:57+02:00 summary: gh-95388: Suppress deprecation warning in test_immutable_type_with_mutable_base (GH-95728) When 3.14 kicks in, it'll be a RuntimeError; the test will correctly fail then. files: M Lib/test/test_capi.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index c7435578974..1ff14e7bc56 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -645,6 +645,7 @@ def test_pytype_fromspec_with_repeated_slots(self): with self.assertRaises(SystemError): _testcapi.create_type_from_repeated_slots(variant) + @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_immutable_type_with_mutable_base(self): # Add deprecation warning here so it's removed in 3.14 warnings._deprecated( From webhook-mailer at python.org Mon Aug 8 07:00:22 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 08 Aug 2022 11:00:22 -0000 Subject: [Python-checkins] gh-91838: Resolve more HTTP links which redirect to HTTPS (GH-95650) Message-ID: <mailman.565.1659956423.3313.python-checkins@python.org> https://github.com/python/cpython/commit/cc9160a29bc3356ced92348bcd8e6668c67167c9 commit: cc9160a29bc3356ced92348bcd8e6668c67167c9 branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-08T14:00:17+03:00 summary: gh-91838: Resolve more HTTP links which redirect to HTTPS (GH-95650) files: M Doc/whatsnew/2.5.rst M Lib/posixpath.py M Lib/test/test_descrtut.py M Tools/c-analyzer/c_parser/parser/__init__.py diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index ea785121db90..6c216826fee0 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -2019,7 +2019,7 @@ https://www.sqlite.org. .. seealso:: - http://www.pysqlite.org + https://www.pysqlite.org The pysqlite web page. https://www.sqlite.org diff --git a/Lib/posixpath.py b/Lib/posixpath.py index a7b2f2d64824..5e1ebe3293d8 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -364,7 +364,7 @@ def normpath(path): initial_slashes = path.startswith(sep) # POSIX allows one or two initial slashes, but treats three or more # as single slash. - # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) + # (see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) if (initial_slashes and path.startswith(sep*2) and not path.startswith(sep*3)): initial_slashes = 2 diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py index b4158eb23a56..7796031ed060 100644 --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -1,7 +1,7 @@ # This contains most of the executable examples from Guido's descr # tutorial, once at # -# http://www.python.org/2.2/descrintro.html +# https://www.python.org/download/releases/2.2.3/descrintro/ # # A few examples left implicit in the writeup were fleshed out, a few were # skipped due to lack of interest (e.g., faking super() by hand isn't diff --git a/Tools/c-analyzer/c_parser/parser/__init__.py b/Tools/c-analyzer/c_parser/parser/__init__.py index 0343c2d68aac..4227e938d7f8 100644 --- a/Tools/c-analyzer/c_parser/parser/__init__.py +++ b/Tools/c-analyzer/c_parser/parser/__init__.py @@ -12,7 +12,7 @@ * ... -(see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) +(see: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) We have taken advantage of the elements of the C grammar that are used only in a few limited contexts, mostly as delimiters. They allow us to From webhook-mailer at python.org Mon Aug 8 08:12:16 2022 From: webhook-mailer at python.org (encukou) Date: Mon, 08 Aug 2022 12:12:16 -0000 Subject: [Python-checkins] gh-93274: Expose receiving vectorcall in the Limited API (GH-95717) Message-ID: <mailman.566.1659960737.3313.python-checkins@python.org> https://github.com/python/cpython/commit/656dad702d3b25bf678ee9bd7109d98876946258 commit: 656dad702d3b25bf678ee9bd7109d98876946258 branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-08T14:12:05+02:00 summary: gh-93274: Expose receiving vectorcall in the Limited API (GH-95717) files: A Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst A Modules/_testcapi/vectorcall_limited.c M Doc/data/stable_abi.dat M Doc/whatsnew/3.12.rst M Include/abstract.h M Include/cpython/abstract.h M Include/cpython/object.h M Include/object.h M Lib/test/test_call.py M Lib/test/test_stable_abi_ctypes.py M Misc/stable_abi.toml M Modules/Setup.stdlib.in M Modules/_testcapi/parts.h M Modules/_testcapimodule.c M Objects/call.c M PC/python3dll.c M PCbuild/_testcapi.vcxproj M PCbuild/_testcapi.vcxproj.filters diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 82cd5796efd2..fde62eacd00a 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -783,6 +783,8 @@ function,PyUnicode_WriteChar,3.7,, type,PyVarObject,3.2,,members member,PyVarObject.ob_base,3.2,, member,PyVarObject.ob_size,3.2,, +function,PyVectorcall_Call,3.12,, +function,PyVectorcall_NARGS,3.12,, type,PyWeakReference,3.2,,opaque function,PyWeakref_GetObject,3.2,, function,PyWeakref_NewProxy,3.2,, @@ -883,4 +885,5 @@ type,symtable,3.2,,opaque type,ternaryfunc,3.2,, type,traverseproc,3.2,, type,unaryfunc,3.2,, +type,vectorcallfunc,3.12,, type,visitproc,3.2,, diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index ddf9e1f6a59b..f1696cc4584c 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -426,14 +426,22 @@ New Features an additional metaclass argument. (Contributed by Wenzel Jakob in :gh:`93012`.) -* (XXX: this should be combined with :gh:`93274` when that is done) +* API for creating objects that can be called using + :ref:`the vectorcall protocol <vectorcall>` was added to the + :ref:`Limited API <stable>`: + + * :const:`Py_TPFLAGS_HAVE_VECTORCALL` + * :c:func:`PyVectorcall_NARGS` + * :c:func:`PyVectorcall_Call` + * :c:type:`vectorcallfunc` + The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class when the class's :py:meth:`~object.__call__` method is reassigned. This makes vectorcall safe to use with mutable types (i.e. heap types without the :const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` flag). Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now - inherit the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. - (Contributed by Petr Viktorin in :gh:`93012`.) + inherit the ``Py_TPFLAGS_HAVE_VECTORCALL`` flag. + (Contributed by Petr Viktorin in :gh:`93274`.) Porting to Python 3.12 ---------------------- diff --git a/Include/abstract.h b/Include/abstract.h index 576024e09c41..784ff7e92867 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -228,6 +228,16 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( PyObject *name, ...); +/* Given a vectorcall nargsf argument, return the actual number of arguments. + * (For use outside the limited API, this is re-defined as a static inline + * function in cpython/abstract.h) + */ +PyAPI_FUNC(Py_ssize_t) PyVectorcall_NARGS(size_t nargsf); + +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); + /* Implemented elsewhere: diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 7038918f0188..6da29cde9f60 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -53,8 +53,12 @@ PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( #define PY_VECTORCALL_ARGUMENTS_OFFSET \ (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) +// PyVectorcall_NARGS() is exported as a function for the stable ABI. +// Here (when we are not using the stable ABI), the name is overridden to +// call a static inline function for best performance. +#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n) static inline Py_ssize_t -PyVectorcall_NARGS(size_t n) +_PyVectorcall_NARGS(size_t n) { return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; } @@ -84,10 +88,6 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( size_t nargsf, PyObject *kwargs); -/* Call "callable" (which must support vectorcall) with positional arguments - "tuple" and keyword arguments "dict". "dict" may also be NULL */ -PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); - // Same as PyObject_Vectorcall(), except without keyword arguments PyAPI_FUNC(PyObject *) _PyObject_FastCall( PyObject *func, diff --git a/Include/cpython/object.h b/Include/cpython/object.h index a26fc7f6aadf..c80fc1df0e0b 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -54,9 +54,6 @@ typedef struct _Py_Identifier { typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); typedef void (*releasebufferproc)(PyObject *, Py_buffer *); -typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - typedef struct { /* Number implementations must check *both* diff --git a/Include/object.h b/Include/object.h index c00b9eb58342..7d499d8b306e 100644 --- a/Include/object.h +++ b/Include/object.h @@ -228,6 +228,11 @@ typedef int (*initproc)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030c0000 // 3.12 +typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); +#endif + typedef struct{ int slot; /* slot id, see below */ void *pfunc; /* function pointer */ @@ -381,11 +386,13 @@ given type object has a specified feature. #define Py_TPFLAGS_BASETYPE (1UL << 10) /* Set if the type implements the vectorcall protocol (PEP 590) */ -#ifndef Py_LIMITED_API +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 #define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +#ifndef Py_LIMITED_API // Backwards compatibility alias for API that was provisional in Python 3.8 #define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL #endif +#endif /* Set if the type is 'ready' -- fully initialized */ #define Py_TPFLAGS_READY (1UL << 12) diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 6c81a154f65f..d3a254f15b62 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -759,6 +759,11 @@ def __call__(self, *args): self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) + def test_vectorcall_limited(self): + from _testcapi import pyobject_vectorcall + obj = _testcapi.LimitedVectorCallClass() + self.assertEqual(pyobject_vectorcall(obj, (), ()), "vectorcall called") + class A: def method_two_args(self, x, y): diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 53e93ab6b9b4..a803e3a50259 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -782,6 +782,8 @@ def test_windows_feature_macros(self): "PyUnicode_Translate", "PyUnicode_Type", "PyUnicode_WriteChar", + "PyVectorcall_Call", + "PyVectorcall_NARGS", "PyWeakref_GetObject", "PyWeakref_NewProxy", "PyWeakref_NewRef", diff --git a/Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst b/Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst new file mode 100644 index 000000000000..da6cce4a7b28 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-08-01-16-21-39.gh-issue-93274.QoDHEu.rst @@ -0,0 +1,3 @@ +API for implementing vectorcall (:c:data:`Py_TPFLAGS_HAVE_VECTORCALL`, +:c:func:`PyVectorcall_NARGS` and :c:func:`PyVectorcall_Call`) was added to +the limited API and stable ABI. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 84bec8270960..4da002a05862 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2275,5 +2275,14 @@ added = '3.11' [function.PyErr_SetHandledException] added = '3.11' + [function.PyType_FromMetaclass] added = '3.12' +[const.Py_TPFLAGS_HAVE_VECTORCALL] + added = '3.12' +[function.PyVectorcall_NARGS] + added = '3.12' +[function.PyVectorcall_Call] + added = '3.12' +[typedef.vectorcallfunc] + added = '3.12' diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index c5dc1e8eb453..908e6df97667 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -169,7 +169,7 @@ @MODULE__XXTESTFUZZ_TRUE at _xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE at _testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE at _testinternalcapi _testinternalcapi.c - at MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c + at MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c # Some testing modules MUST be built as shared libraries. *shared* diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index e6d2ed23cb18..4b672c9d05bd 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -1,4 +1,5 @@ #include "Python.h" int _PyTestCapi_Init_Vectorcall(PyObject *module); +int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_Heaptype(PyObject *module); diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c new file mode 100644 index 000000000000..63ea3b3101b2 --- /dev/null +++ b/Modules/_testcapi/vectorcall_limited.c @@ -0,0 +1,77 @@ +#define Py_LIMITED_API 0x030c0000 // 3.12 +#include "parts.h" +#include "structmember.h" // PyMemberDef + +/* Test Vectorcall in the limited API */ + +static PyObject * +LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { + return PyUnicode_FromString("tp_call called"); +} + +static PyObject * +LimitedVectorCallClass_vectorcall(PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames) { + return PyUnicode_FromString("vectorcall called"); +} + +static PyObject * +LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw) +{ + PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0); + if (!self) { + return NULL; + } + *(vectorcallfunc*)((char*)self + sizeof(PyObject)) = ( + LimitedVectorCallClass_vectorcall); + return self; +} + +static PyMemberDef LimitedVectorCallClass_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY}, + {NULL} +}; + +static PyType_Slot LimitedVectorallClass_slots[] = { + {Py_tp_new, LimitedVectorCallClass_new}, + {Py_tp_call, LimitedVectorCallClass_tpcall}, + {Py_tp_members, LimitedVectorCallClass_members}, + {0}, +}; + +static PyType_Spec LimitedVectorCallClass_spec = { + .name = "_testcapi.LimitedVectorCallClass", + .basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)), + .flags = Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_VECTORCALL + | Py_TPFLAGS_BASETYPE, + .slots = LimitedVectorallClass_slots, +}; + +static PyMethodDef TestMethods[] = { + /* Add module methods here. + * (Empty list left here as template/example, since using + * PyModule_AddFunctions isn't very common.) + */ + {NULL}, +}; + +int +_PyTestCapi_Init_VectorcallLimited(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec( + m, &LimitedVectorCallClass_spec, NULL); + if (!LimitedVectorCallClass) { + return -1; + } + if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 517591465b49..8004fa18bcc5 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6865,6 +6865,9 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Vectorcall(m) < 0) { return NULL; } + if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Heaptype(m) < 0) { return NULL; } diff --git a/Objects/call.c b/Objects/call.c index ed168c9c4796..c2509db2a9a2 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1047,3 +1047,11 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, PyMem_Free((PyObject **)stack - 1); Py_DECREF(kwnames); } + +// Export for the stable ABI +#undef PyVectorcall_NARGS +Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return _PyVectorcall_NARGS(n); +} diff --git a/PC/python3dll.c b/PC/python3dll.c index 024ec49d68d7..89bbd05932b8 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -723,6 +723,8 @@ EXPORT_FUNC(PyUnicodeTranslateError_GetStart) EXPORT_FUNC(PyUnicodeTranslateError_SetEnd) EXPORT_FUNC(PyUnicodeTranslateError_SetReason) EXPORT_FUNC(PyUnicodeTranslateError_SetStart) +EXPORT_FUNC(PyVectorcall_Call) +EXPORT_FUNC(PyVectorcall_NARGS) EXPORT_FUNC(PyWeakref_GetObject) EXPORT_FUNC(PyWeakref_NewProxy) EXPORT_FUNC(PyWeakref_NewRef) diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index a88540cab19f..0cb4e44cf734 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -95,6 +95,7 @@ <ItemGroup> <ClCompile Include="..\Modules\_testcapimodule.c" /> <ClCompile Include="..\Modules\_testcapi\vectorcall.c" /> + <ClCompile Include="..\Modules\_testcapi\vectorcall_limited.c" /> <ClCompile Include="..\Modules\_testcapi\heaptype.c" /> </ItemGroup> <ItemGroup> diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index a43ab5ea0ff9..4da972f279c8 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -15,6 +15,9 @@ <ClCompile Include="..\Modules\_testcapi\vectorcall.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\Modules\_testcapi\vectorcall_limited.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\Modules\_testcapi\heaptype.c"> <Filter>Source Files</Filter> </ClCompile> From webhook-mailer at python.org Mon Aug 8 09:09:19 2022 From: webhook-mailer at python.org (pablogsal) Date: Mon, 08 Aug 2022 13:09:19 -0000 Subject: [Python-checkins] Python 3.11.0rc1 Message-ID: <mailman.567.1659964161.3313.python-checkins@python.org> https://github.com/python/cpython/commit/41cb07120b7792eac6413b0c56256a25e9b14e5d commit: 41cb07120b7792eac6413b0c56256a25e9b14e5d branch: 3.11 author: Pablo Galindo <pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-05T15:45:18+01:00 summary: Python 3.11.0rc1 files: A Misc/NEWS.d/3.11.0rc1.rst D Misc/NEWS.d/next/Build/2022-07-21-09-17-01.gh-issue-95085.E9x2S_.rst D Misc/NEWS.d/next/Build/2022-07-23-21-39-09.gh-issue-95174.7cYMZR.rst D Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst D Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst D Misc/NEWS.d/next/Build/2022-07-26-18-13-34.gh-issue-94801.9fREfy.rst D Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst D Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-23-19-16-25.gh-issue-93351.0Jyvu-.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-24-00-27-47.gh-issue-95185.ghYTZx.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-05-07.gh-issue-95324.28Q5u7.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst D Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst D Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst D Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst D Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst D Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst D Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst D Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst D Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst D Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst D Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst D Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst D Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst D Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst D Misc/NEWS.d/next/Library/2022-07-21-22-59-22.gh-issue-95109.usxA9r.rst D Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst D Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst D Misc/NEWS.d/next/Library/2022-07-24-18-00-42.gh-issue-95097.lu5qNf.rst D Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst D Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst D Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst D Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst D Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst D Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst D Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst D Misc/NEWS.d/next/Windows/2022-07-26-20-33-12.gh-issue-95285.w6fa22.rst D Misc/NEWS.d/next/Windows/2022-07-28-20-21-38.gh-issue-95359.ywMrgu.rst D Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst D Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst D Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst D Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 4c657f738f36..e7176705acb4 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -19,11 +19,11 @@ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 11 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 5 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.11.0b5+" +#define PY_VERSION "3.11.0rc1" /*--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 535432725b2b..4a607bc3cdd7 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 Jul 25 23:19:30 2022 +# Autogenerated by Sphinx on Fri Aug 5 15:44:44 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' diff --git a/Misc/NEWS.d/3.11.0rc1.rst b/Misc/NEWS.d/3.11.0rc1.rst new file mode 100644 index 000000000000..51c5fd384d67 --- /dev/null +++ b/Misc/NEWS.d/3.11.0rc1.rst @@ -0,0 +1,436 @@ +.. date: 2022-07-31-13-23-12 +.. gh-issue: 95150 +.. nonce: 67FXVo +.. release date: 2022-08-05 +.. section: Core and Builtins + +Update code object hashing and equality to consider all debugging and +exception handling tables. This fixes an issue where certain non-identical +code objects could be "deduplicated" during compilation. + +.. + +.. date: 2022-07-28-08-33-31 +.. gh-issue: 95355 +.. nonce: yN4XVk +.. section: Core and Builtins + +``_PyPegen_Parser_New`` now properly detects token memory allocation errors. +Patch by Honglin Zhu. + +.. + +.. date: 2022-07-27-14-21-57 +.. gh-issue: 90081 +.. nonce: HVAS5x +.. section: Core and Builtins + +Run Python code in tracer/profiler function at full speed. Fixes slowdown in +earlier versions of 3.11. + +.. + +.. date: 2022-07-27-14-05-07 +.. gh-issue: 95324 +.. nonce: 28Q5u7 +.. section: Core and Builtins + +Emit a warning in debug mode if an object does not call +:c:func:`PyObject_GC_UnTrack` before deallocation. Patch by Pablo Galindo. + +.. + +.. date: 2022-07-24-00-27-47 +.. gh-issue: 95185 +.. nonce: ghYTZx +.. section: Core and Builtins + +Prevented crashes in the AST constructor when compiling some absurdly long +expressions like ``"+0"*1000000``. :exc:`RecursionError` is now raised +instead. Patch by Pablo Galindo + +.. + +.. date: 2022-07-23-19-16-25 +.. gh-issue: 93351 +.. nonce: 0Jyvu- +.. section: Core and Builtins + +:class:`ast.AST` node positions are now validated when provided to +:func:`compile` and other related functions. If invalid positions are +detected, a :exc:`ValueError` will be raised. + +.. + +.. date: 2022-07-19-09-41-55 +.. gh-issue: 94938 +.. nonce: xYBlM7 +.. section: Core and Builtins + +Fix error detection in some builtin functions when keyword argument name is +an instance of a str subclass with overloaded ``__eq__`` and ``__hash__``. +Previously it could cause SystemError or other undesired behavior. + +.. + +.. date: 2022-08-03-21-01-17 +.. gh-issue: 95609 +.. nonce: xxyjyX +.. section: Library + +Update bundled pip to 22.2.2. + +.. + +.. date: 2022-08-03-16-52-32 +.. gh-issue: 95289 +.. nonce: FMnHlV +.. section: Library + +Fix :class:`asyncio.TaskGroup` to propagate exception when +:exc:`asyncio.CancelledError` was replaced with another exception by a +context manger. Patch by Kumar Aditya and Guido van Rossum. + +.. + +.. date: 2022-07-27-19-43-07 +.. gh-issue: 95339 +.. nonce: NuVQ68 +.. section: Library + +Update bundled pip to 22.2.1. + +.. + +.. date: 2022-07-27-11-35-45 +.. gh-issue: 95045 +.. nonce: iysT-Q +.. section: Library + +Fix GC crash when deallocating ``_lsprof.Profiler`` by untracking it before +calling any callbacks. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-24-18-00-42 +.. gh-issue: 95097 +.. nonce: lu5qNf +.. section: Library + +Fix :func:`asyncio.run` for :class:`asyncio.Task` implementations without +:meth:`~asyncio.Task.uncancel` method. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-23-10-50-05 +.. gh-issue: 93899 +.. nonce: VT34A5 +.. section: Library + +Fix check for existence of :data:`os.EFD_CLOEXEC`, :data:`os.EFD_NONBLOCK` +and :data:`os.EFD_SEMAPHORE` flags on older kernel versions where these +flags are not present. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-23-10-42-05 +.. gh-issue: 95166 +.. nonce: xw6p3C +.. section: Library + +Fix :meth:`concurrent.futures.Executor.map` to cancel the currently waiting +on future on an error - e.g. TimeoutError or KeyboardInterrupt. + +.. + +.. date: 2022-07-21-22-59-22 +.. gh-issue: 95109 +.. nonce: usxA9r +.. section: Library + +Ensure that timeouts scheduled with :class:`asyncio.Timeout` that have +already expired are delivered promptly. + +.. + +.. date: 2022-06-02-08-40-58 +.. gh-issue: 91810 +.. nonce: Gtk44w +.. section: Library + +Suppress writing an XML declaration in open files in ``ElementTree.write()`` +with ``encoding='unicode'`` and ``xml_declaration=None``. + +.. + +.. date: 2022-04-12-18-05-40 +.. gh-issue: 91447 +.. nonce: N_Fs4H +.. section: Library + +Fix findtext in the xml module to only give an empty string when the text +attribute is set to None. + +.. + +.. date: 2022-08-03-13-35-08 +.. gh-issue: 91207 +.. nonce: eJ4pPf +.. section: Documentation + +Fix stylesheet not working in Windows CHM htmlhelp docs and add warning that +they are deprecated. Contributed by C.A.M. Gerlach. + +.. + +.. date: 2022-07-29-23-02-19 +.. gh-issue: 95451 +.. nonce: -tgB93 +.. section: Documentation + +Update library documentation with :ref:`availability information +<wasm-availability>` on WebAssembly platforms ``wasm32-emscripten`` and +``wasm32-wasi``. + +.. + +.. date: 2022-07-29-09-04-02 +.. gh-issue: 95415 +.. nonce: LKTyw6 +.. section: Documentation + +Use consistent syntax for platform availability. The directive now supports +a content body and emits a warning when it encounters an unknown platform. + +.. + +.. date: 2022-06-19-18-18-22 +.. gh-issue: 86128 +.. nonce: 39DDTD +.. section: Documentation + +Document a limitation in ThreadPoolExecutor where its exit handler is +executed before any handlers in atexit. + +.. + +.. date: 2022-08-05-09-57-43 +.. gh-issue: 95573 +.. nonce: edMdQB +.. section: Tests + +:source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug in the macOS +kernel where intense concurrent load on non-blocking sockets occasionally +causes :const:`errno.ENOBUFS` ("No buffer space available") to be emitted. +FB11063974 filed with Apple, in the mean time as a workaround buffer size +used in tests on macOS is decreased to avoid intermittent failures. Patch +by Fantix King. + +.. + +.. date: 2022-07-26-15-22-19 +.. gh-issue: 95280 +.. nonce: h8HvbP +.. section: Tests + +Fix problem with ``test_ssl`` ``test_get_ciphers`` on systems that require +perfect forward secrecy (PFS) ciphers. + +.. + +.. date: 2022-07-08-12-22-00 +.. gh-issue: 94675 +.. nonce: IiTs5f +.. section: Tests + +Add a regression test for :mod:`re` exponentional slowdown when using +rjsmin. + +.. + +.. date: 2022-07-26-18-13-34 +.. gh-issue: 94801 +.. nonce: 9fREfy +.. section: Build + +Fix a regression in ``configure`` script that caused some header checks to +ignore custom ``CPPFLAGS``. The regression was introduced in :gh:`94802`. + +.. + +.. date: 2022-07-25-09-48-43 +.. gh-issue: 95145 +.. nonce: ZNS3dj +.. section: Build + +wasm32-wasi builds no longer depend on WASIX's pthread stubs. Python now has +its own stubbed pthread API. + +.. + +.. date: 2022-07-25-08-59-35 +.. gh-issue: 95174 +.. nonce: g8woUW +.. section: Build + +Python now detects missing ``dup`` function in WASI and works around some +missing :mod:`errno`, :mod:`select`, and :mod:`socket` constants. + +.. + +.. date: 2022-07-23-21-39-09 +.. gh-issue: 95174 +.. nonce: 7cYMZR +.. section: Build + +Python now skips missing :mod:`socket` functions and methods on WASI. WASI +can only create sockets from existing fd / accept and has no netdb. + +.. + +.. date: 2022-07-21-09-17-01 +.. gh-issue: 95085 +.. nonce: E9x2S_ +.. section: Build + +Platforms ``wasm32-unknown-emscripten`` and ``wasm32-unknown-wasi`` have +been promoted to :pep:`11` tier 3 platform support. + +.. + +.. date: 2022-08-04-18-47-54 +.. gh-issue: 95656 +.. nonce: VJ1d13 +.. section: Windows + +Enable the :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` +API. + +.. + +.. date: 2022-08-04-01-12-27 +.. gh-issue: 95587 +.. nonce: Fvdv5q +.. section: Windows + +Fixes some issues where the Windows installer would incorrectly detect +certain features of an existing install when upgrading. + +.. + +.. date: 2022-08-03-00-49-46 +.. gh-issue: 94399 +.. nonce: KvxHc0 +.. section: Windows + +Restores the behaviour of :ref:`launcher` for ``/usr/bin/env`` shebang +lines, which will now search :envvar:`PATH` for an executable matching the +given command. If none is found, the usual search process is used. + +.. + +.. date: 2022-07-30-14-18-33 +.. gh-issue: 95445 +.. nonce: mjrTaq +.. section: Windows + +Fixes the unsuccessful removal of the HTML document directory when +uninstalling with Windows msi. + +.. + +.. date: 2022-07-28-20-21-38 +.. gh-issue: 95359 +.. nonce: ywMrgu +.. section: Windows + +Fix :ref:`launcher` handling of :file:`py.ini` commands (it was incorrectly +expecting a ``py_`` prefix on keys) and crashes when reading per-user +configuration file. + +.. + +.. date: 2022-07-26-20-33-12 +.. gh-issue: 95285 +.. nonce: w6fa22 +.. section: Windows + +Fix :ref:`launcher` handling of command lines where it is only passed a +short executable name. + +.. + +.. date: 2022-08-04-20-07-51 +.. gh-issue: 65802 +.. nonce: xnThWe +.. section: IDLE + +Document handling of extensions in Save As dialogs. + +.. + +.. date: 2022-08-01-23-31-48 +.. gh-issue: 95191 +.. nonce: U7vryB +.. section: IDLE + +Include prompts when saving Shell (interactive input and output). + +.. + +.. date: 2022-07-31-22-15-14 +.. gh-issue: 95511 +.. nonce: WX6PmB +.. section: IDLE + +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. + +.. + +.. date: 2022-07-30-15-10-39 +.. gh-issue: 95471 +.. nonce: z3scVG +.. section: IDLE + +In the Edit menu, move ``Select All`` and add a new separator. + +.. + +.. date: 2022-07-29-11-08-52 +.. gh-issue: 95411 +.. nonce: dazlqH +.. section: IDLE + +Enable using IDLE's module browser with .pyw files. + +.. + +.. date: 2022-07-28-18-56-57 +.. gh-issue: 89610 +.. nonce: hcosiM +.. section: IDLE + +Add .pyi as a recognized extension for IDLE on macOS. This allows opening +stub files by double clicking on them in the Finder. + +.. + +.. date: 2022-08-03-14-39-08 +.. gh-issue: 92678 +.. nonce: ozFTEx +.. section: C API + +Restore the 3.10 behavior for multiple inheritance of C extension classes +that store their dictionary at the end of the struct. + +.. + +.. date: 2022-07-19-22-37-40 +.. gh-issue: 94936 +.. nonce: LGlmKv +.. section: C API + +Added :c:func:`PyCode_GetVarnames`, :c:func:`PyCode_GetCellvars` and +:c:func:`PyCode_GetFreevars` for accessing ``co_varnames``, ``co_cellvars`` +and ``co_freevars`` respectively via the C API. diff --git a/Misc/NEWS.d/next/Build/2022-07-21-09-17-01.gh-issue-95085.E9x2S_.rst b/Misc/NEWS.d/next/Build/2022-07-21-09-17-01.gh-issue-95085.E9x2S_.rst deleted file mode 100644 index 02dbd2b8b311..000000000000 --- a/Misc/NEWS.d/next/Build/2022-07-21-09-17-01.gh-issue-95085.E9x2S_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Platforms ``wasm32-unknown-emscripten`` and ``wasm32-unknown-wasi`` have -been promoted to :pep:`11` tier 3 platform support. diff --git a/Misc/NEWS.d/next/Build/2022-07-23-21-39-09.gh-issue-95174.7cYMZR.rst b/Misc/NEWS.d/next/Build/2022-07-23-21-39-09.gh-issue-95174.7cYMZR.rst deleted file mode 100644 index 72ce183ac832..000000000000 --- a/Misc/NEWS.d/next/Build/2022-07-23-21-39-09.gh-issue-95174.7cYMZR.rst +++ /dev/null @@ -1 +0,0 @@ -Python now skips missing :mod:`socket` functions and methods on WASI. WASI can only create sockets from existing fd / accept and has no netdb. diff --git a/Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst b/Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst deleted file mode 100644 index 05f29955072c..000000000000 --- a/Misc/NEWS.d/next/Build/2022-07-25-08-59-35.gh-issue-95174.g8woUW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Python now detects missing ``dup`` function in WASI and works around some -missing :mod:`errno`, :mod:`select`, and :mod:`socket` constants. diff --git a/Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst b/Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst deleted file mode 100644 index c751b5e3adc4..000000000000 --- a/Misc/NEWS.d/next/Build/2022-07-25-09-48-43.gh-issue-95145.ZNS3dj.rst +++ /dev/null @@ -1,2 +0,0 @@ -wasm32-wasi builds no longer depend on WASIX's pthread stubs. Python now has -its own stubbed pthread API. diff --git a/Misc/NEWS.d/next/Build/2022-07-26-18-13-34.gh-issue-94801.9fREfy.rst b/Misc/NEWS.d/next/Build/2022-07-26-18-13-34.gh-issue-94801.9fREfy.rst deleted file mode 100644 index a58be30e81b0..000000000000 --- a/Misc/NEWS.d/next/Build/2022-07-26-18-13-34.gh-issue-94801.9fREfy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a regression in ``configure`` script that caused some header checks to -ignore custom ``CPPFLAGS``. The regression was introduced in :gh:`94802`. diff --git a/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst b/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst deleted file mode 100644 index abef9bb376c8..000000000000 --- a/Misc/NEWS.d/next/C API/2022-07-19-22-37-40.gh-issue-94936.LGlmKv.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added :c:func:`PyCode_GetVarnames`, :c:func:`PyCode_GetCellvars` and -:c:func:`PyCode_GetFreevars` for accessing ``co_varnames``, ``co_cellvars`` -and ``co_freevars`` respectively via the C API. diff --git a/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst b/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst deleted file mode 100644 index 6bf3d4b1abbf..000000000000 --- a/Misc/NEWS.d/next/C API/2022-08-03-14-39-08.gh-issue-92678.ozFTEx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restore the 3.10 behavior for multiple inheritance of C extension classes -that store their dictionary at the end of the struct. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst deleted file mode 100644 index cc4feae685f2..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-09-41-55.gh-issue-94938.xYBlM7.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix error detection in some builtin functions when keyword argument name is -an instance of a str subclass with overloaded ``__eq__`` and ``__hash__``. -Previously it could cause SystemError or other undesired behavior. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-23-19-16-25.gh-issue-93351.0Jyvu-.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-23-19-16-25.gh-issue-93351.0Jyvu-.rst deleted file mode 100644 index 97cf8055ac54..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-23-19-16-25.gh-issue-93351.0Jyvu-.rst +++ /dev/null @@ -1,3 +0,0 @@ -:class:`ast.AST` node positions are now validated when provided to -:func:`compile` and other related functions. If invalid positions are -detected, a :exc:`ValueError` will be raised. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-24-00-27-47.gh-issue-95185.ghYTZx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-24-00-27-47.gh-issue-95185.ghYTZx.rst deleted file mode 100644 index de156bab2f51..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-24-00-27-47.gh-issue-95185.ghYTZx.rst +++ /dev/null @@ -1,3 +0,0 @@ -Prevented crashes in the AST constructor when compiling some absurdly long -expressions like ``"+0"*1000000``. :exc:`RecursionError` is now raised -instead. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-05-07.gh-issue-95324.28Q5u7.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-05-07.gh-issue-95324.28Q5u7.rst deleted file mode 100644 index 250385270e94..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-05-07.gh-issue-95324.28Q5u7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Emit a warning in debug mode if an object does not call -:c:func:`PyObject_GC_UnTrack` before deallocation. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst deleted file mode 100644 index a3be34c175af..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst +++ /dev/null @@ -1,2 +0,0 @@ -Run Python code in tracer/profiler function at full speed. Fixes slowdown in -earlier versions of 3.11. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst deleted file mode 100644 index 6a289991e0d6..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-28-08-33-31.gh-issue-95355.yN4XVk.rst +++ /dev/null @@ -1 +0,0 @@ -``_PyPegen_Parser_New`` now properly detects token memory allocation errors. Patch by Honglin Zhu. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst deleted file mode 100644 index c3db4714188b..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-31-13-23-12.gh-issue-95150.67FXVo.rst +++ /dev/null @@ -1,3 +0,0 @@ -Update code object hashing and equality to consider all debugging and -exception handling tables. This fixes an issue where certain non-identical -code objects could be "deduplicated" during compilation. diff --git a/Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst b/Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst deleted file mode 100644 index bab006856dee..000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-06-19-18-18-22.gh-issue-86128.39DDTD.rst +++ /dev/null @@ -1 +0,0 @@ -Document a limitation in ThreadPoolExecutor where its exit handler is executed before any handlers in atexit. diff --git a/Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst b/Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst deleted file mode 100644 index ece36bc4d1ce..000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-07-29-09-04-02.gh-issue-95415.LKTyw6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use consistent syntax for platform availability. The directive now supports -a content body and emits a warning when it encounters an unknown platform. diff --git a/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst b/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst deleted file mode 100644 index 3a7b8a122b7a..000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-07-29-23-02-19.gh-issue-95451.-tgB93.rst +++ /dev/null @@ -1,3 +0,0 @@ -Update library documentation with -:ref:`availability information <wasm-availability>` -on WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``. diff --git a/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst b/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst deleted file mode 100644 index 8c7391f7edf7..000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-08-03-13-35-08.gh-issue-91207.eJ4pPf.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix stylesheet not working in Windows CHM htmlhelp docs -and add warning that they are deprecated. -Contributed by C.A.M. Gerlach. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst b/Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst deleted file mode 100644 index 0d283711e3e8..000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-28-18-56-57.gh-issue-89610.hcosiM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add .pyi as a recognized extension for IDLE on macOS. This allows opening -stub files by double clicking on them in the Finder. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst b/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst deleted file mode 100644 index 94ca8b2c2ea9..000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst +++ /dev/null @@ -1 +0,0 @@ -Enable using IDLE's module browser with .pyw files. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst b/Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst deleted file mode 100644 index 73a9d8058965..000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-30-15-10-39.gh-issue-95471.z3scVG.rst +++ /dev/null @@ -1 +0,0 @@ -In the Edit menu, move ``Select All`` and add a new separator. diff --git a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst b/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst deleted file mode 100644 index 803fa5f2a2ab..000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-07-31-22-15-14.gh-issue-95511.WX6PmB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the Shell context menu copy-with-prompts bug of copying an extra line -when one selects whole lines. diff --git a/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst b/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst deleted file mode 100644 index 94d3dbbd529f..000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-08-01-23-31-48.gh-issue-95191.U7vryB.rst +++ /dev/null @@ -1 +0,0 @@ -Include prompts when saving Shell (interactive input and output). diff --git a/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst b/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst deleted file mode 100644 index a62a784b6e69..000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-08-04-20-07-51.gh-issue-65802.xnThWe.rst +++ /dev/null @@ -1 +0,0 @@ -Document handling of extensions in Save As dialogs. diff --git a/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst b/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst deleted file mode 100644 index 6f9be2d3e9be..000000000000 --- a/Misc/NEWS.d/next/Library/2022-04-12-18-05-40.gh-issue-91447.N_Fs4H.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix findtext in the xml module to only give an empty string when the text -attribute is set to None. diff --git a/Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst b/Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst deleted file mode 100644 index e40005886afc..000000000000 --- a/Misc/NEWS.d/next/Library/2022-06-02-08-40-58.gh-issue-91810.Gtk44w.rst +++ /dev/null @@ -1,2 +0,0 @@ -Suppress writing an XML declaration in open files in ``ElementTree.write()`` -with ``encoding='unicode'`` and ``xml_declaration=None``. diff --git a/Misc/NEWS.d/next/Library/2022-07-21-22-59-22.gh-issue-95109.usxA9r.rst b/Misc/NEWS.d/next/Library/2022-07-21-22-59-22.gh-issue-95109.usxA9r.rst deleted file mode 100644 index 40196dd214a2..000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-21-22-59-22.gh-issue-95109.usxA9r.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure that timeouts scheduled with :class:`asyncio.Timeout` that have already expired are delivered promptly. diff --git a/Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst b/Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst deleted file mode 100644 index 34b017078436..000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-23-10-42-05.gh-issue-95166.xw6p3C.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :meth:`concurrent.futures.Executor.map` to cancel the currently waiting on future on an error - e.g. TimeoutError or KeyboardInterrupt. diff --git a/Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst b/Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst deleted file mode 100644 index e63475f8ba96..000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-23-10-50-05.gh-issue-93899.VT34A5.rst +++ /dev/null @@ -1 +0,0 @@ -Fix check for existence of :data:`os.EFD_CLOEXEC`, :data:`os.EFD_NONBLOCK` and :data:`os.EFD_SEMAPHORE` flags on older kernel versions where these flags are not present. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-07-24-18-00-42.gh-issue-95097.lu5qNf.rst b/Misc/NEWS.d/next/Library/2022-07-24-18-00-42.gh-issue-95097.lu5qNf.rst deleted file mode 100644 index 2840f057a9c1..000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-24-18-00-42.gh-issue-95097.lu5qNf.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :func:`asyncio.run` for :class:`asyncio.Task` implementations without :meth:`~asyncio.Task.uncancel` method. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst b/Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst deleted file mode 100644 index d4ab325e0365..000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-27-11-35-45.gh-issue-95045.iysT-Q.rst +++ /dev/null @@ -1 +0,0 @@ -Fix GC crash when deallocating ``_lsprof.Profiler`` by untracking it before calling any callbacks. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst b/Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst deleted file mode 100644 index 6674a4a26953..000000000000 --- a/Misc/NEWS.d/next/Library/2022-07-27-19-43-07.gh-issue-95339.NuVQ68.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled pip to 22.2.1. diff --git a/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst b/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst deleted file mode 100644 index d802f557217b..000000000000 --- a/Misc/NEWS.d/next/Library/2022-08-03-16-52-32.gh-issue-95289.FMnHlV.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :class:`asyncio.TaskGroup` to propagate exception when :exc:`asyncio.CancelledError` was replaced with another exception by a context manger. Patch by Kumar Aditya and Guido van Rossum. diff --git a/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst b/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst deleted file mode 100644 index 81c02ae900f7..000000000000 --- a/Misc/NEWS.d/next/Library/2022-08-03-21-01-17.gh-issue-95609.xxyjyX.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled pip to 22.2.2. diff --git a/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst b/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst deleted file mode 100644 index d0005d9f6014..000000000000 --- a/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst +++ /dev/null @@ -1 +0,0 @@ -Add a regression test for :mod:`re` exponentional slowdown when using rjsmin. diff --git a/Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst b/Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst deleted file mode 100644 index 523d9d5f2f8b..000000000000 --- a/Misc/NEWS.d/next/Tests/2022-07-26-15-22-19.gh-issue-95280.h8HvbP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix problem with ``test_ssl`` ``test_get_ciphers`` on systems that require -perfect forward secrecy (PFS) ciphers. diff --git a/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst b/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst deleted file mode 100644 index 8580556965e1..000000000000 --- a/Misc/NEWS.d/next/Tests/2022-08-05-09-57-43.gh-issue-95573.edMdQB.rst +++ /dev/null @@ -1,6 +0,0 @@ -:source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug in the macOS -kernel where intense concurrent load on non-blocking sockets occasionally -causes :const:`errno.ENOBUFS` ("No buffer space available") to be emitted. -FB11063974 filed with Apple, in the mean time as a workaround buffer size -used in tests on macOS is decreased to avoid intermittent failures. Patch -by Fantix King. diff --git a/Misc/NEWS.d/next/Windows/2022-07-26-20-33-12.gh-issue-95285.w6fa22.rst b/Misc/NEWS.d/next/Windows/2022-07-26-20-33-12.gh-issue-95285.w6fa22.rst deleted file mode 100644 index 76b38e7803cc..000000000000 --- a/Misc/NEWS.d/next/Windows/2022-07-26-20-33-12.gh-issue-95285.w6fa22.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :ref:`launcher` handling of command lines where it is only passed a -short executable name. diff --git a/Misc/NEWS.d/next/Windows/2022-07-28-20-21-38.gh-issue-95359.ywMrgu.rst b/Misc/NEWS.d/next/Windows/2022-07-28-20-21-38.gh-issue-95359.ywMrgu.rst deleted file mode 100644 index 513a2be28a9c..000000000000 --- a/Misc/NEWS.d/next/Windows/2022-07-28-20-21-38.gh-issue-95359.ywMrgu.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :ref:`launcher` handling of :file:`py.ini` commands (it was incorrectly -expecting a ``py_`` prefix on keys) and crashes when reading per-user -configuration file. diff --git a/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst b/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst deleted file mode 100644 index 565489ebf909..000000000000 --- a/Misc/NEWS.d/next/Windows/2022-07-30-14-18-33.gh-issue-95445.mjrTaq.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes the unsuccessful removal of the HTML document directory when uninstalling with Windows msi. diff --git a/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst b/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst deleted file mode 100644 index a49e99ca2665..000000000000 --- a/Misc/NEWS.d/next/Windows/2022-08-03-00-49-46.gh-issue-94399.KvxHc0.rst +++ /dev/null @@ -1,3 +0,0 @@ -Restores the behaviour of :ref:`launcher` for ``/usr/bin/env`` shebang -lines, which will now search :envvar:`PATH` for an executable matching the -given command. If none is found, the usual search process is used. diff --git a/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst b/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst deleted file mode 100644 index 1033e892876c..000000000000 --- a/Misc/NEWS.d/next/Windows/2022-08-04-01-12-27.gh-issue-95587.Fvdv5q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes some issues where the Windows installer would incorrectly detect -certain features of an existing install when upgrading. diff --git a/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst b/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst deleted file mode 100644 index 77fea4c33f7a..000000000000 --- a/Misc/NEWS.d/next/Windows/2022-08-04-18-47-54.gh-issue-95656.VJ1d13.rst +++ /dev/null @@ -1,2 +0,0 @@ -Enable the :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` -API. diff --git a/README.rst b/README.rst index 60eb20615f3c..f0b452e6f8fe 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.11.0 beta 5 -==================================== +This is Python version 3.11.0 release candidate 1 +================================================= .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg :alt: CPython build status on GitHub Actions From webhook-mailer at python.org Mon Aug 8 09:38:10 2022 From: webhook-mailer at python.org (terryjreedy) Date: Mon, 08 Aug 2022 13:38:10 -0000 Subject: [Python-checkins] gh-95491: Mention IDLE Issue project in Readme (#95750) Message-ID: <mailman.568.1659965891.3313.python-checkins@python.org> https://github.com/python/cpython/commit/63140b445e4a303df430b3d60c1cd4ef34f27c03 commit: 63140b445e4a303df430b3d60c1cd4ef34f27c03 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-08T09:37:43-04:00 summary: gh-95491: Mention IDLE Issue project in Readme (#95750) files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 779b51c1b931..76aec58912f0 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -280,3 +280,11 @@ first back-ported feature after 3.n.0 is released. Since each older version file gets a different number of backports, it is easiest to make a separate PR for each file and label it with the backports needed. + +Github repository and issues +---------------------------- + +The CPython repository is https://github.com/python/cpython. The +IDLE Issues listing is https://github.com/orgs/python/projects/31. +The main classification is by Topic, based on the IDLE menu. View the +topics list by clicking the [<]] button in the upper right. From webhook-mailer at python.org Mon Aug 8 10:03:32 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 08 Aug 2022 14:03:32 -0000 Subject: [Python-checkins] gh-95491: Mention IDLE Issue project in Readme (GH-95750) Message-ID: <mailman.569.1659967413.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6d1919009f64981943fa4218e69d0c09c7dbe740 commit: 6d1919009f64981943fa4218e69d0c09c7dbe740 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-08T07:03:23-07:00 summary: gh-95491: Mention IDLE Issue project in Readme (GH-95750) (cherry picked from commit 63140b445e4a303df430b3d60c1cd4ef34f27c03) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 779b51c1b931..76aec58912f0 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -280,3 +280,11 @@ first back-ported feature after 3.n.0 is released. Since each older version file gets a different number of backports, it is easiest to make a separate PR for each file and label it with the backports needed. + +Github repository and issues +---------------------------- + +The CPython repository is https://github.com/python/cpython. The +IDLE Issues listing is https://github.com/orgs/python/projects/31. +The main classification is by Topic, based on the IDLE menu. View the +topics list by clicking the [<]] button in the upper right. From webhook-mailer at python.org Mon Aug 8 11:09:20 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 08 Aug 2022 15:09:20 -0000 Subject: [Python-checkins] [3.10] gh-91838: Resolve more HTTP links which redirect to HTTPS (GH-95650). (GH-95786) Message-ID: <mailman.570.1659971361.3313.python-checkins@python.org> https://github.com/python/cpython/commit/da4aae29f829fdf288b42919671274d7d463fe04 commit: da4aae29f829fdf288b42919671274d7d463fe04 branch: 3.10 author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-08T18:09:06+03:00 summary: [3.10] gh-91838: Resolve more HTTP links which redirect to HTTPS (GH-95650). (GH-95786) (cherry picked from commit cc9160a29bc3356ced92348bcd8e6668c67167c9) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M Doc/whatsnew/2.5.rst M Lib/posixpath.py M Lib/test/test_descrtut.py M Tools/c-analyzer/c_parser/parser/__init__.py diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index ea785121db90..6c216826fee0 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -2019,7 +2019,7 @@ https://www.sqlite.org. .. seealso:: - http://www.pysqlite.org + https://www.pysqlite.org The pysqlite web page. https://www.sqlite.org diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 195374613a77..526f017acbd5 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -352,7 +352,7 @@ def normpath(path): initial_slashes = path.startswith(sep) # POSIX allows one or two initial slashes, but treats three or more # as single slash. - # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) + # (see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) if (initial_slashes and path.startswith(sep*2) and not path.startswith(sep*3)): initial_slashes = 2 diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py index 8e25f58d7aa2..c5fbcba2d6ae 100644 --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -1,7 +1,7 @@ # This contains most of the executable examples from Guido's descr # tutorial, once at # -# http://www.python.org/2.2/descrintro.html +# https://www.python.org/download/releases/2.2.3/descrintro/ # # A few examples left implicit in the writeup were fleshed out, a few were # skipped due to lack of interest (e.g., faking super() by hand isn't diff --git a/Tools/c-analyzer/c_parser/parser/__init__.py b/Tools/c-analyzer/c_parser/parser/__init__.py index df70aae66b77..8ec4b00165e6 100644 --- a/Tools/c-analyzer/c_parser/parser/__init__.py +++ b/Tools/c-analyzer/c_parser/parser/__init__.py @@ -12,7 +12,7 @@ * ... -(see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) +(see: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) We have taken advantage of the elements of the C grammar that are used only in a few limited contexts, mostly as delimiters. They allow us to From webhook-mailer at python.org Mon Aug 8 12:21:37 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 08 Aug 2022 16:21:37 -0000 Subject: [Python-checkins] gh-95781: More strict format string checking in PyUnicode_FromFormatV() (GH-95784) Message-ID: <mailman.571.1659975698.3313.python-checkins@python.org> https://github.com/python/cpython/commit/62f06508e76e023a81861caee6a45e1d639bf530 commit: 62f06508e76e023a81861caee6a45e1d639bf530 branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-08T19:21:07+03:00 summary: gh-95781: More strict format string checking in PyUnicode_FromFormatV() (GH-95784) An unrecognized format character in PyUnicode_FromFormat() and PyUnicode_FromFormatV() now sets a SystemError. In previous versions it caused all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. files: A Misc/NEWS.d/next/C API/2022-08-08-14-36-31.gh-issue-95781.W_G8YW.rst M Doc/c-api/unicode.rst M Doc/whatsnew/3.12.rst M Lib/test/test_unicode.py M Objects/unicodeobject.c diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 339ee35c7aa4..99afebd762a4 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -477,9 +477,6 @@ APIs: | | | :c:func:`PyObject_Repr`. | +-------------------+---------------------+----------------------------------+ - An unrecognized format character causes all the rest of the format string to be - copied as-is to the result string, and any extra arguments discarded. - .. note:: The width formatter unit is number of characters rather than bytes. The precision formatter unit is number of bytes for ``"%s"`` and @@ -500,6 +497,11 @@ APIs: Support width and precision formatter for ``"%s"``, ``"%A"``, ``"%U"``, ``"%V"``, ``"%S"``, ``"%R"`` added. + .. versionchanged:: 3.12 + An unrecognized format character now sets a :exc:`SystemError`. + In previous versions it caused all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + .. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index f1696cc4584c..6df122acba71 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -469,6 +469,12 @@ Porting to Python 3.12 :py:meth:`~class.__subclasses__` (using :c:func:`PyObject_CallMethod`, for example). +* An unrecognized format character in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV` now sets a :exc:`SystemError`. + In previous versions it caused all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + (Contributed by Serhiy Storchaka in :gh:`95781`.) + Deprecated ---------- diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 9765ed97a60a..63bccb72e046 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -2641,8 +2641,6 @@ def check_format(expected, format, *args): b'%c%c', c_int(0x10000), c_int(0x100000)) # test "%" - check_format('%', - b'%') check_format('%', b'%%') check_format('%s', @@ -2819,23 +2817,22 @@ def check_format(expected, format, *args): check_format('repr=abc\ufffd', b'repr=%V', None, b'abc\xff') - # not supported: copy the raw format string. these tests are just here - # to check for crashes and should not be considered as specifications - check_format('%s', - b'%1%s', b'abc') - check_format('%1abc', - b'%1abc') - check_format('%+i', - b'%+i', c_int(10)) - check_format('%.%s', - b'%.%s', b'abc') - # Issue #33817: empty strings check_format('', b'') check_format('', b'%s', b'') + # check for crashes + for fmt in (b'%', b'%0', b'%01', b'%.', b'%.1', + b'%0%s', b'%1%s', b'%.%s', b'%.1%s', b'%1abc', + b'%l', b'%ll', b'%z', b'%ls', b'%lls', b'%zs'): + with self.subTest(fmt=fmt): + self.assertRaisesRegex(SystemError, 'invalid format string', + PyUnicode_FromFormat, fmt, b'abc') + self.assertRaisesRegex(SystemError, 'invalid format string', + PyUnicode_FromFormat, b'%+i', c_int(10)) + # Test PyUnicode_AsWideChar() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') diff --git a/Misc/NEWS.d/next/C API/2022-08-08-14-36-31.gh-issue-95781.W_G8YW.rst b/Misc/NEWS.d/next/C API/2022-08-08-14-36-31.gh-issue-95781.W_G8YW.rst new file mode 100644 index 000000000000..eb2fd7e9da3d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-08-08-14-36-31.gh-issue-95781.W_G8YW.rst @@ -0,0 +1,4 @@ +An unrecognized format character in :c:func:`PyUnicode_FromFormat` and +:c:func:`PyUnicode_FromFormatV` now sets a :exc:`SystemError`. +In previous versions it caused all the rest of the format string to be +copied as-is to the result string, and any extra arguments discarded. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7ff79953257e..184a2bfd5dd8 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2355,6 +2355,13 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, p = f; f++; + if (*f == '%') { + if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) + return NULL; + f++; + return f; + } + zeropad = 0; if (*f == '0') { zeropad = 1; @@ -2392,14 +2399,6 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, f++; } } - if (*f == '%') { - /* "%.3%s" => f points to "3" */ - f--; - } - } - if (*f == '\0') { - /* bogus format "%.123" => go backward, f points to "3" */ - f--; } /* Handle %ld, %lu, %lld and %llu. */ @@ -2423,7 +2422,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, ++f; } - if (f[1] == '\0') + if (f[0] != '\0' && f[1] == '\0') writer->overallocate = 0; switch (*f) { @@ -2616,21 +2615,9 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case '%': - if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) - return NULL; - break; - default: - /* if we stumble upon an unknown formatting code, copy the rest - of the format string to the output string. (we cannot just - skip the code, since there's no way to know what's in the - argument list) */ - len = strlen(p); - if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1) - return NULL; - f = p+len; - return f; + PyErr_Format(PyExc_SystemError, "invalid format string: %s", p); + return NULL; } f++; From webhook-mailer at python.org Mon Aug 8 15:25:45 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 08 Aug 2022 19:25:45 -0000 Subject: [Python-checkins] gh-95273: Reorganize sqlite3 doc module level funcs and vars (#95626) Message-ID: <mailman.572.1659986746.3313.python-checkins@python.org> https://github.com/python/cpython/commit/41c939cb35cda395388a775156c367676efffebe commit: 41c939cb35cda395388a775156c367676efffebe branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-08T21:25:35+02:00 summary: gh-95273: Reorganize sqlite3 doc module level funcs and vars (#95626) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 83f29287120..06ed7af052f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -132,142 +132,18 @@ You've now created an SQLite database using the :mod:`!sqlite3` module. Reference --------- +.. We keep the old sqlite3-module-contents ref to prevent breaking links. .. _sqlite3-module-contents: -Module functions and constants -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _sqlite3-module-functions: +Module functions +^^^^^^^^^^^^^^^^ -.. data:: apilevel - - String constant stating the supported DB-API level. Required by the DB-API. - Hard-coded to ``"2.0"``. - -.. data:: paramstyle - - String constant stating the type of parameter marker formatting expected by - the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to - ``"qmark"``. - - .. note:: - - The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API - parameter styles, because that is what the underlying SQLite library - supports. However, the DB-API does not allow multiple values for - the ``paramstyle`` attribute. - -.. data:: version - - Version number of this module as a :class:`string <str>`. - This is not the version of the SQLite library. - - .. deprecated-removed:: 3.12 3.14 - This constant used to reflect the version number of the ``pysqlite`` - package, a third-party library which used to upstream changes to - :mod:`!sqlite3`. Today, it carries no meaning or practical value. - - -.. data:: version_info - - Version number of this module as a :class:`tuple` of :class:`integers <int>`. - This is not the version of the SQLite library. - - .. deprecated-removed:: 3.12 3.14 - This constant used to reflect the version number of the ``pysqlite`` - package, a third-party library which used to upstream changes to - :mod:`!sqlite3`. Today, it carries no meaning or practical value. - - -.. data:: sqlite_version - - Version number of the runtime SQLite library as a :class:`string <str>`. - - -.. data:: sqlite_version_info - - Version number of the runtime SQLite library as a :class:`tuple` of - :class:`integers <int>`. - - -.. data:: threadsafety - - Integer constant required by the DB-API 2.0, stating the level of thread - safety the :mod:`!sqlite3` module supports. This attribute is set based on - the default `threading mode <https://sqlite.org/threadsafe.html>`_ the - underlying SQLite library is compiled with. The SQLite threading modes are: - - 1. **Single-thread**: In this mode, all mutexes are disabled and SQLite is - unsafe to use in more than a single thread at once. - 2. **Multi-thread**: In this mode, SQLite can be safely used by multiple - threads provided that no single database connection is used - simultaneously in two or more threads. - 3. **Serialized**: In serialized mode, SQLite can be safely used by - multiple threads with no restriction. - - The mappings from SQLite threading modes to DB-API 2.0 threadsafety levels - are as follows: - - +------------------+-----------------+----------------------+-------------------------------+ - | SQLite threading | `threadsafety`_ | `SQLITE_THREADSAFE`_ | DB-API 2.0 meaning | - | mode | | | | - +==================+=================+======================+===============================+ - | single-thread | 0 | 0 | Threads may not share the | - | | | | module | - +------------------+-----------------+----------------------+-------------------------------+ - | multi-thread | 1 | 2 | Threads may share the module, | - | | | | but not connections | - +------------------+-----------------+----------------------+-------------------------------+ - | serialized | 3 | 1 | Threads may share the module, | - | | | | connections and cursors | - +------------------+-----------------+----------------------+-------------------------------+ - - .. _threadsafety: https://peps.python.org/pep-0249/#threadsafety - .. _SQLITE_THREADSAFE: https://sqlite.org/compile.html#threadsafe - - .. versionchanged:: 3.11 - Set *threadsafety* dynamically instead of hard-coding it to ``1``. - -.. data:: PARSE_DECLTYPES - - Pass this flag value to the *detect_types* parameter of - :func:`connect` to look up a converter function using - the declared types for each column. - The types are declared when the database table is created. - :mod:`!sqlite3` will look up a converter function using the first word of the - declared type as the converter dictionary key. - For example: - - - .. code-block:: sql - - CREATE TABLE test( - i integer primary key, ! will look up a converter named "integer" - p point, ! will look up a converter named "point" - n number(10) ! will look up a converter named "number" - ) - - This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` - (bitwise or) operator. - - -.. data:: PARSE_COLNAMES - - Pass this flag value to the *detect_types* parameter of - :func:`connect` to look up a converter function by - using the type name, parsed from the query column name, - as the converter dictionary key. - The type name must be wrapped in square brackets (``[]``). - - .. code-block:: sql - - SELECT p as "p [point]" FROM test; ! will look up converter "point" - - This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` - (bitwise or) operator. - - - -.. function:: connect(database, timeout=5.0, detect_types=0, isolation_level="DEFERRED", check_same_thread=True, factory=sqlite3.Connection, cached_statements=128, uri=False) +.. function:: connect(database, timeout=5.0, detect_types=0, \ + isolation_level="DEFERRED", check_same_thread=True, \ + factory=sqlite3.Connection, cached_statements=128, \ + uri=False) Open a connection to an SQLite database. @@ -344,30 +220,6 @@ Module functions and constants .. versionadded:: 3.10 The ``sqlite3.connect/handle`` auditing event. - -.. function:: register_converter(typename, converter, /) - - Register the *converter* callable to convert SQLite objects of type - *typename* into a Python object of a specific type. - The converter is invoked for all SQLite values of type *typename*; - it is passed a :class:`bytes` object and should return an object of the - desired Python type. - Consult the parameter *detect_types* of - :func:`connect` for information regarding how type detection works. - - Note: *typename* and the name of the type in your query are matched - case-insensitively. - - -.. function:: register_adapter(type, adapter, /) - - Register an *adapter* callable to adapt the Python type *type* into an - SQLite type. - The adapter is called with a Python object of type *type* as its sole - argument, and must return a value of a - :ref:`type that SQLite natively understands <sqlite3-types>`. - - .. function:: complete_statement(statement) Returns ``True`` if the string *statement* contains one or more complete SQL @@ -377,10 +229,8 @@ Module functions and constants This can be used to build a shell for SQLite, as in the following example: - .. literalinclude:: ../includes/sqlite3/complete_statement.py - .. function:: enable_callback_tracebacks(flag, /) Enable or disable callback tracebacks. @@ -408,6 +258,154 @@ Module functions and constants UnraisableHookArgs(exc_type=<class 'ZeroDivisionError'>, exc_value=ZeroDivisionError('division by zero'), exc_traceback=<traceback object at 0x10b559900>, err_msg=None, object=<function <lambda> at 0x10b4e3ee0>) <sqlite3.Cursor object at 0x10b1fe840> +.. function:: register_adapter(type, adapter, /) + + Register an *adapter* callable to adapt the Python type *type* into an + SQLite type. + The adapter is called with a Python object of type *type* as its sole + argument, and must return a value of a + :ref:`type that SQLite natively understands <sqlite3-types>`. + +.. function:: register_converter(typename, converter, /) + + Register the *converter* callable to convert SQLite objects of type + *typename* into a Python object of a specific type. + The converter is invoked for all SQLite values of type *typename*; + it is passed a :class:`bytes` object and should return an object of the + desired Python type. + Consult the parameter *detect_types* of + :func:`connect` for information regarding how type detection works. + + Note: *typename* and the name of the type in your query are matched + case-insensitively. + + +.. _sqlite3-module-constants: + +Module constants +^^^^^^^^^^^^^^^^ + +.. data:: PARSE_COLNAMES + + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function by + using the type name, parsed from the query column name, + as the converter dictionary key. + The type name must be wrapped in square brackets (``[]``). + + .. code-block:: sql + + SELECT p as "p [point]" FROM test; ! will look up converter "point" + + This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` + (bitwise or) operator. + +.. data:: PARSE_DECLTYPES + + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function using + the declared types for each column. + The types are declared when the database table is created. + :mod:`!sqlite3` will look up a converter function using the first word of the + declared type as the converter dictionary key. + For example: + + .. code-block:: sql + + CREATE TABLE test( + i integer primary key, ! will look up a converter named "integer" + p point, ! will look up a converter named "point" + n number(10) ! will look up a converter named "number" + ) + + This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` + (bitwise or) operator. + +.. data:: apilevel + + String constant stating the supported DB-API level. Required by the DB-API. + Hard-coded to ``"2.0"``. + +.. data:: paramstyle + + String constant stating the type of parameter marker formatting expected by + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to + ``"qmark"``. + + .. note:: + + The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API + parameter styles, because that is what the underlying SQLite library + supports. However, the DB-API does not allow multiple values for + the ``paramstyle`` attribute. + +.. data:: sqlite_version + + Version number of the runtime SQLite library as a :class:`string <str>`. + +.. data:: sqlite_version_info + + Version number of the runtime SQLite library as a :class:`tuple` of + :class:`integers <int>`. + +.. data:: threadsafety + + Integer constant required by the DB-API 2.0, stating the level of thread + safety the :mod:`!sqlite3` module supports. This attribute is set based on + the default `threading mode <https://sqlite.org/threadsafe.html>`_ the + underlying SQLite library is compiled with. The SQLite threading modes are: + + 1. **Single-thread**: In this mode, all mutexes are disabled and SQLite is + unsafe to use in more than a single thread at once. + 2. **Multi-thread**: In this mode, SQLite can be safely used by multiple + threads provided that no single database connection is used + simultaneously in two or more threads. + 3. **Serialized**: In serialized mode, SQLite can be safely used by + multiple threads with no restriction. + + The mappings from SQLite threading modes to DB-API 2.0 threadsafety levels + are as follows: + + +------------------+-----------------+----------------------+-------------------------------+ + | SQLite threading | `threadsafety`_ | `SQLITE_THREADSAFE`_ | DB-API 2.0 meaning | + | mode | | | | + +==================+=================+======================+===============================+ + | single-thread | 0 | 0 | Threads may not share the | + | | | | module | + +------------------+-----------------+----------------------+-------------------------------+ + | multi-thread | 1 | 2 | Threads may share the module, | + | | | | but not connections | + +------------------+-----------------+----------------------+-------------------------------+ + | serialized | 3 | 1 | Threads may share the module, | + | | | | connections and cursors | + +------------------+-----------------+----------------------+-------------------------------+ + + .. _threadsafety: https://peps.python.org/pep-0249/#threadsafety + .. _SQLITE_THREADSAFE: https://sqlite.org/compile.html#threadsafe + + .. versionchanged:: 3.11 + Set *threadsafety* dynamically instead of hard-coding it to ``1``. + +.. data:: version + + Version number of this module as a :class:`string <str>`. + This is not the version of the SQLite library. + + .. deprecated-removed:: 3.12 3.14 + This constant used to reflect the version number of the ``pysqlite`` + package, a third-party library which used to upstream changes to + :mod:`!sqlite3`. Today, it carries no meaning or practical value. + +.. data:: version_info + + Version number of this module as a :class:`tuple` of :class:`integers <int>`. + This is not the version of the SQLite library. + + .. deprecated-removed:: 3.12 3.14 + This constant used to reflect the version number of the ``pysqlite`` + package, a third-party library which used to upstream changes to + :mod:`!sqlite3`. Today, it carries no meaning or practical value. + .. _sqlite3-connection-objects: From webhook-mailer at python.org Mon Aug 8 16:08:48 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 08 Aug 2022 20:08:48 -0000 Subject: [Python-checkins] [3.10] gh-95273: Reorganize sqlite3 doc module level funcs and vars (GH-95626) (#95803) Message-ID: <mailman.573.1659989329.3313.python-checkins@python.org> https://github.com/python/cpython/commit/49e505c4bd11aa14f26209b1104f23d62337e1ad commit: 49e505c4bd11aa14f26209b1104f23d62337e1ad branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-08T22:08:43+02:00 summary: [3.10] gh-95273: Reorganize sqlite3 doc module level funcs and vars (GH-95626) (#95803) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM>. (cherry picked from commit 41c939cb35cda395388a775156c367676efffebe) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index f711505d922..219c41e2b19 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -132,114 +132,18 @@ You've now created an SQLite database using the :mod:`!sqlite3` module. Reference --------- +.. We keep the old sqlite3-module-contents ref to prevent breaking links. .. _sqlite3-module-contents: -Module functions and constants -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _sqlite3-module-functions: +Module functions +^^^^^^^^^^^^^^^^ -.. data:: apilevel - - String constant stating the supported DB-API level. Required by the DB-API. - Hard-coded to ``"2.0"``. - -.. data:: paramstyle - - String constant stating the type of parameter marker formatting expected by - the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to - ``"qmark"``. - - .. note:: - - The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API - parameter styles, because that is what the underlying SQLite library - supports. However, the DB-API does not allow multiple values for - the ``paramstyle`` attribute. - -.. data:: version - - Version number of this module as a :class:`string <str>`. - This is not the version of the SQLite library. - - -.. data:: version_info - - Version number of this module as a :class:`tuple` of :class:`integers <int>`. - This is not the version of the SQLite library. - - -.. data:: sqlite_version - - Version number of the runtime SQLite library as a :class:`string <str>`. - - -.. data:: sqlite_version_info - - Version number of the runtime SQLite library as a :class:`tuple` of - :class:`integers <int>`. - - -.. data:: threadsafety - - Integer constant required by the DB-API, stating the level of thread safety - the :mod:`!sqlite3` module supports. Currently hard-coded to ``1``, meaning - *"Threads may share the module, but not connections."* However, this may not - always be true. You can check the underlying SQLite library's compile-time - threaded mode using the following query:: - - import sqlite3 - con = sqlite3.connect(":memory:") - con.execute(""" - select * from pragma_compile_options - where compile_options like 'THREADSAFE=%' - """).fetchall() - - Note that the `SQLITE_THREADSAFE levels - <https://sqlite.org/compile.html#threadsafe>`_ do not match the DB-API 2.0 - ``threadsafety`` levels. - - -.. data:: PARSE_DECLTYPES - - Pass this flag value to the *detect_types* parameter of - :func:`connect` to look up a converter function using - the declared types for each column. - The types are declared when the database table is created. - :mod:`!sqlite3` will look up a converter function using the first word of the - declared type as the converter dictionary key. - For example: - - - .. code-block:: sql - - CREATE TABLE test( - i integer primary key, ! will look up a converter named "integer" - p point, ! will look up a converter named "point" - n number(10) ! will look up a converter named "number" - ) - - This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` - (bitwise or) operator. - - -.. data:: PARSE_COLNAMES - - Pass this flag value to the *detect_types* parameter of - :func:`connect` to look up a converter function by - using the type name, parsed from the query column name, - as the converter dictionary key. - The type name must be wrapped in square brackets (``[]``). - - .. code-block:: sql - - SELECT p as "p [point]" FROM test; ! will look up converter "point" - - This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` - (bitwise or) operator. - - - -.. function:: connect(database, timeout=5.0, detect_types=0, isolation_level="DEFERRED", check_same_thread=True, factory=sqlite3.Connection, cached_statements=128, uri=False) +.. function:: connect(database, timeout=5.0, detect_types=0, \ + isolation_level="DEFERRED", check_same_thread=True, \ + factory=sqlite3.Connection, cached_statements=128, \ + uri=False) Open a connection to an SQLite database. @@ -316,6 +220,33 @@ Module functions and constants .. versionadded:: 3.10 The ``sqlite3.connect/handle`` auditing event. +.. function:: complete_statement(statement) + + Returns ``True`` if the string *statement* contains one or more complete SQL + statements terminated by semicolons. It does not verify that the SQL is + syntactically correct, only that there are no unclosed string literals and the + statement is terminated by a semicolon. + + This can be used to build a shell for SQLite, as in the following example: + + .. literalinclude:: ../includes/sqlite3/complete_statement.py + +.. function:: enable_callback_tracebacks(flag, /) + + Enable or disable callback tracebacks. + By default you will not get any tracebacks in user-defined functions, + aggregates, converters, authorizer callbacks etc. If you want to debug them, + you can call this function with *flag* set to ``True``. Afterwards, you will + get tracebacks from callbacks on ``sys.stderr``. Use ``False`` to + disable the feature again. + +.. function:: register_adapter(type, adapter, /) + + Register an *adapter* callable to adapt the Python type *type* into an + SQLite type. + The adapter is called with a Python object of type *type* as its sole + argument, and must return a value of a + :ref:`type that SQLite natively understands <sqlite3-types>`. .. function:: register_converter(typename, converter, /) @@ -331,36 +262,102 @@ Module functions and constants case-insensitively. -.. function:: register_adapter(type, adapter, /) +.. _sqlite3-module-constants: - Register an *adapter* callable to adapt the Python type *type* into an - SQLite type. - The adapter is called with a Python object of type *type* as its sole - argument, and must return a value of a - :ref:`type that SQLite natively understands <sqlite3-types>`. +Module constants +^^^^^^^^^^^^^^^^ +.. data:: PARSE_COLNAMES -.. function:: complete_statement(statement) + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function by + using the type name, parsed from the query column name, + as the converter dictionary key. + The type name must be wrapped in square brackets (``[]``). - Returns ``True`` if the string *statement* contains one or more complete SQL - statements terminated by semicolons. It does not verify that the SQL is - syntactically correct, only that there are no unclosed string literals and the - statement is terminated by a semicolon. + .. code-block:: sql - This can be used to build a shell for SQLite, as in the following example: + SELECT p as "p [point]" FROM test; ! will look up converter "point" + This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` + (bitwise or) operator. - .. literalinclude:: ../includes/sqlite3/complete_statement.py +.. data:: PARSE_DECLTYPES + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function using + the declared types for each column. + The types are declared when the database table is created. + :mod:`!sqlite3` will look up a converter function using the first word of the + declared type as the converter dictionary key. + For example: -.. function:: enable_callback_tracebacks(flag, /) + .. code-block:: sql - Enable or disable callback tracebacks. - By default you will not get any tracebacks in user-defined functions, - aggregates, converters, authorizer callbacks etc. If you want to debug them, - you can call this function with *flag* set to ``True``. Afterwards, you will - get tracebacks from callbacks on ``sys.stderr``. Use ``False`` to - disable the feature again. + CREATE TABLE test( + i integer primary key, ! will look up a converter named "integer" + p point, ! will look up a converter named "point" + n number(10) ! will look up a converter named "number" + ) + + This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` + (bitwise or) operator. + +.. data:: apilevel + + String constant stating the supported DB-API level. Required by the DB-API. + Hard-coded to ``"2.0"``. + +.. data:: paramstyle + + String constant stating the type of parameter marker formatting expected by + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to + ``"qmark"``. + + .. note:: + + The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API + parameter styles, because that is what the underlying SQLite library + supports. However, the DB-API does not allow multiple values for + the ``paramstyle`` attribute. + +.. data:: sqlite_version + + Version number of the runtime SQLite library as a :class:`string <str>`. + +.. data:: sqlite_version_info + + Version number of the runtime SQLite library as a :class:`tuple` of + :class:`integers <int>`. + +.. data:: threadsafety + + Integer constant required by the DB-API, stating the level of thread safety + the :mod:`!sqlite3` module supports. Currently hard-coded to ``1``, meaning + *"Threads may share the module, but not connections."* However, this may not + always be true. You can check the underlying SQLite library's compile-time + threaded mode using the following query:: + + import sqlite3 + con = sqlite3.connect(":memory:") + con.execute(""" + select * from pragma_compile_options + where compile_options like 'THREADSAFE=%' + """).fetchall() + + Note that the `SQLITE_THREADSAFE levels + <https://sqlite.org/compile.html#threadsafe>`_ do not match the DB-API 2.0 + ``threadsafety`` levels. + +.. data:: version + + Version number of this module as a :class:`string <str>`. + This is not the version of the SQLite library. + +.. data:: version_info + + Version number of this module as a :class:`tuple` of :class:`integers <int>`. + This is not the version of the SQLite library. .. _sqlite3-connection-objects: From webhook-mailer at python.org Mon Aug 8 19:22:35 2022 From: webhook-mailer at python.org (rhettinger) Date: Mon, 08 Aug 2022 23:22:35 -0000 Subject: [Python-checkins] bpo-37000: Remove obsolete comment in _randbelow_with_getrandbits (#95775) Message-ID: <mailman.574.1660000955.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8a55e2f9200288c353937cd5a0b83f0a3e282092 commit: 8a55e2f9200288c353937cd5a0b83f0a3e282092 branch: main author: Matthias G?rgens <matthias.goergens at gmail.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-08T18:22:26-05:00 summary: bpo-37000: Remove obsolete comment in _randbelow_with_getrandbits (#95775) files: M Lib/random.py diff --git a/Lib/random.py b/Lib/random.py index 76627309e288..c70294ee0cbf 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -239,7 +239,7 @@ def _randbelow_with_getrandbits(self, n): "Return a random int in the range [0,n). Defined for n > 0." getrandbits = self.getrandbits - k = n.bit_length() # don't use (n-1) here because n can be 1 + k = n.bit_length() r = getrandbits(k) # 0 <= r < 2**k while r >= n: r = getrandbits(k) From webhook-mailer at python.org Tue Aug 9 02:32:24 2022 From: webhook-mailer at python.org (rhettinger) Date: Tue, 09 Aug 2022 06:32:24 -0000 Subject: [Python-checkins] Improvements to the bisect docs (GH-95807) Message-ID: <mailman.575.1660026745.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7c8626ab3db0b896052596066e1a2099b53ed135 commit: 7c8626ab3db0b896052596066e1a2099b53ed135 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-09T01:31:50-05:00 summary: Improvements to the bisect docs (GH-95807) files: M Doc/library/bisect.rst diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 513675d3685a..76045ea511a5 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -13,10 +13,16 @@ This module provides support for maintaining a list in sorted order without having to sort the list after each insertion. For long lists of items with -expensive comparison operations, this can be an improvement over the more common -approach. The module is called :mod:`bisect` because it uses a basic bisection -algorithm to do its work. The source code may be most useful as a working -example of the algorithm (the boundary conditions are already right!). +expensive comparison operations, this can be an improvement over +linear searches or frequent resorting. + +The module is called :mod:`bisect` because it uses a basic bisection +algorithm to do its work. Unlike other bisection tools that search for a +specific value, the functions in this module are designed to locate an +insertion point. Accordingly, the functions never call an :meth:`__eq__` +method to determine whether a value has been found. Instead, the +functions only call the :meth:`__lt__` method and will return an insertion +point between values in an array. The following functions are provided: @@ -30,16 +36,17 @@ The following functions are provided: any existing entries. The return value is suitable for use as the first parameter to ``list.insert()`` assuming that *a* is already sorted. - The returned insertion point *i* partitions the array *a* into two halves so - that ``all(val < x for val in a[lo : i])`` for the left side and - ``all(val >= x for val in a[i : hi])`` for the right side. + The returned insertion point *ip* partitions the array *a* into two + slices such that ``all(elem < x for elem in a[lo : ip])`` is true for the + left slice and ``all(elem >= x for elem in a[ip : hi])`` is true for the + right slice. *key* specifies a :term:`key function` of one argument that is used to extract a comparison key from each element in the array. To support searching complex records, the key function is not applied to the *x* value. - If *key* is ``None``, the elements are compared directly with no - intervening function call. + If *key* is ``None``, the elements are compared directly and + no key function is called. .. versionchanged:: 3.10 Added the *key* parameter. @@ -51,16 +58,9 @@ The following functions are provided: Similar to :func:`bisect_left`, but returns an insertion point which comes after (to the right of) any existing entries of *x* in *a*. - The returned insertion point *i* partitions the array *a* into two halves so - that ``all(val <= x for val in a[lo : i])`` for the left side and - ``all(val > x for val in a[i : hi])`` for the right side. - - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each element in the array. To support - searching complex records, the key function is not applied to the *x* value. - - If *key* is ``None``, the elements are compared directly with no - intervening function call. + The returned insertion point *ip* partitions the array *a* into two slices + such that ``all(elem <= x for elem in a[lo : ip])`` is true for the left slice and + ``all(elem > x for elem in a[ip : hi])`` is true for the right slice. .. versionchanged:: 3.10 Added the *key* parameter. From webhook-mailer at python.org Tue Aug 9 03:03:26 2022 From: webhook-mailer at python.org (encukou) Date: Tue, 09 Aug 2022 07:03:26 -0000 Subject: [Python-checkins] Disable Limited API tests with Py_TRACE_REFS (GH-95796) Message-ID: <mailman.576.1660028608.3313.python-checkins@python.org> https://github.com/python/cpython/commit/eb81c1aea16914347919745e843c982ed831a9fb commit: eb81c1aea16914347919745e843c982ed831a9fb branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-09T09:03:11+02:00 summary: Disable Limited API tests with Py_TRACE_REFS (GH-95796) files: M Lib/test/test_call.py M Modules/_testcapi/vectorcall_limited.c diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index d3a254f15b62..131b45e6caaa 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -9,6 +9,7 @@ import itertools import gc import contextlib +import sys class BadStr(str): @@ -759,6 +760,9 @@ def __call__(self, *args): self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) + @unittest.skipIf( + hasattr(sys, 'getobjects'), + "Limited API is not compatible with Py_TRACE_REFS") def test_vectorcall_limited(self): from _testcapi import pyobject_vectorcall obj = _testcapi.LimitedVectorCallClass() diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c index 63ea3b3101b2..c5184318e292 100644 --- a/Modules/_testcapi/vectorcall_limited.c +++ b/Modules/_testcapi/vectorcall_limited.c @@ -1,3 +1,16 @@ +#include "pyconfig.h" // Py_TRACE_REFS + +#ifdef Py_TRACE_REFS + +// Py_TRACE_REFS is incompatible with Limited API +#include "parts.h" +int +_PyTestCapi_Init_VectorcallLimited(PyObject *m) { + return 0; +} + +#else + #define Py_LIMITED_API 0x030c0000 // 3.12 #include "parts.h" #include "structmember.h" // PyMemberDef @@ -75,3 +88,5 @@ _PyTestCapi_Init_VectorcallLimited(PyObject *m) { return 0; } + +#endif // Py_TRACE_REFS From webhook-mailer at python.org Tue Aug 9 07:46:59 2022 From: webhook-mailer at python.org (ericvsmith) Date: Tue, 09 Aug 2022 11:46:59 -0000 Subject: [Python-checkins] Fix typo in test_dataclasses.py (gh-95735) (gh-95740) Message-ID: <mailman.577.1660045620.3313.python-checkins@python.org> https://github.com/python/cpython/commit/514ec820319138242589f9ca0aa2277de0a1c453 commit: 514ec820319138242589f9ca0aa2277de0a1c453 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ericvsmith <ericvsmith at users.noreply.github.com> date: 2022-08-09T07:46:20-04:00 summary: Fix typo in test_dataclasses.py (gh-95735) (gh-95740) `dataclass` was called as a function when it was almost certainly intended to be a decorator. (cherry picked from commit 59e09efe888affe549e9249f188797c1325edecc) Co-authored-by: da-woods <dw-git at d-woods.co.uk> Co-authored-by: da-woods <dw-git at d-woods.co.uk> files: M Lib/test/test_dataclasses.py diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 569f97902a39..63380ea0b680 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2215,12 +2215,12 @@ class C(B): self.assertEqual(c.z, 100) def test_no_init(self): - dataclass(init=False) + @dataclass(init=False) class C: i: int = 0 self.assertEqual(C().i, 0) - dataclass(init=False) + @dataclass(init=False) class C: i: int = 2 def __init__(self): From webhook-mailer at python.org Tue Aug 9 07:47:20 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 09 Aug 2022 11:47:20 -0000 Subject: [Python-checkins] [3.11] gh-95273: Reorganize sqlite3 doc module level funcs and vars (GH-95626) (#95801) Message-ID: <mailman.578.1660045640.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d7a6a97806ce8525e277ddbf5df639b85c59c09e commit: d7a6a97806ce8525e277ddbf5df639b85c59c09e branch: 3.11 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-09T13:47:15+02:00 summary: [3.11] gh-95273: Reorganize sqlite3 doc module level funcs and vars (GH-95626) (#95801) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM>. (cherry picked from commit 41c939cb35cda395388a775156c367676efffebe) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index b5af3091f731..e88207fa6401 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -132,132 +132,18 @@ You've now created an SQLite database using the :mod:`!sqlite3` module. Reference --------- +.. We keep the old sqlite3-module-contents ref to prevent breaking links. .. _sqlite3-module-contents: -Module functions and constants -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _sqlite3-module-functions: +Module functions +^^^^^^^^^^^^^^^^ -.. data:: apilevel - - String constant stating the supported DB-API level. Required by the DB-API. - Hard-coded to ``"2.0"``. - -.. data:: paramstyle - - String constant stating the type of parameter marker formatting expected by - the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to - ``"qmark"``. - - .. note:: - - The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API - parameter styles, because that is what the underlying SQLite library - supports. However, the DB-API does not allow multiple values for - the ``paramstyle`` attribute. - -.. data:: version - - Version number of this module as a :class:`string <str>`. - This is not the version of the SQLite library. - - -.. data:: version_info - - Version number of this module as a :class:`tuple` of :class:`integers <int>`. - This is not the version of the SQLite library. - - -.. data:: sqlite_version - - Version number of the runtime SQLite library as a :class:`string <str>`. - - -.. data:: sqlite_version_info - - Version number of the runtime SQLite library as a :class:`tuple` of - :class:`integers <int>`. - - -.. data:: threadsafety - - Integer constant required by the DB-API 2.0, stating the level of thread - safety the :mod:`!sqlite3` module supports. This attribute is set based on - the default `threading mode <https://sqlite.org/threadsafe.html>`_ the - underlying SQLite library is compiled with. The SQLite threading modes are: - - 1. **Single-thread**: In this mode, all mutexes are disabled and SQLite is - unsafe to use in more than a single thread at once. - 2. **Multi-thread**: In this mode, SQLite can be safely used by multiple - threads provided that no single database connection is used - simultaneously in two or more threads. - 3. **Serialized**: In serialized mode, SQLite can be safely used by - multiple threads with no restriction. - - The mappings from SQLite threading modes to DB-API 2.0 threadsafety levels - are as follows: - - +------------------+-----------------+----------------------+-------------------------------+ - | SQLite threading | `threadsafety`_ | `SQLITE_THREADSAFE`_ | DB-API 2.0 meaning | - | mode | | | | - +==================+=================+======================+===============================+ - | single-thread | 0 | 0 | Threads may not share the | - | | | | module | - +------------------+-----------------+----------------------+-------------------------------+ - | multi-thread | 1 | 2 | Threads may share the module, | - | | | | but not connections | - +------------------+-----------------+----------------------+-------------------------------+ - | serialized | 3 | 1 | Threads may share the module, | - | | | | connections and cursors | - +------------------+-----------------+----------------------+-------------------------------+ - - .. _threadsafety: https://peps.python.org/pep-0249/#threadsafety - .. _SQLITE_THREADSAFE: https://sqlite.org/compile.html#threadsafe - - .. versionchanged:: 3.11 - Set *threadsafety* dynamically instead of hard-coding it to ``1``. - -.. data:: PARSE_DECLTYPES - - Pass this flag value to the *detect_types* parameter of - :func:`connect` to look up a converter function using - the declared types for each column. - The types are declared when the database table is created. - :mod:`!sqlite3` will look up a converter function using the first word of the - declared type as the converter dictionary key. - For example: - - - .. code-block:: sql - - CREATE TABLE test( - i integer primary key, ! will look up a converter named "integer" - p point, ! will look up a converter named "point" - n number(10) ! will look up a converter named "number" - ) - - This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` - (bitwise or) operator. - - -.. data:: PARSE_COLNAMES - - Pass this flag value to the *detect_types* parameter of - :func:`connect` to look up a converter function by - using the type name, parsed from the query column name, - as the converter dictionary key. - The type name must be wrapped in square brackets (``[]``). - - .. code-block:: sql - - SELECT p as "p [point]" FROM test; ! will look up converter "point" - - This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` - (bitwise or) operator. - - - -.. function:: connect(database, timeout=5.0, detect_types=0, isolation_level="DEFERRED", check_same_thread=True, factory=sqlite3.Connection, cached_statements=128, uri=False) +.. function:: connect(database, timeout=5.0, detect_types=0, \ + isolation_level="DEFERRED", check_same_thread=True, \ + factory=sqlite3.Connection, cached_statements=128, \ + uri=False) Open a connection to an SQLite database. @@ -334,30 +220,6 @@ Module functions and constants .. versionadded:: 3.10 The ``sqlite3.connect/handle`` auditing event. - -.. function:: register_converter(typename, converter, /) - - Register the *converter* callable to convert SQLite objects of type - *typename* into a Python object of a specific type. - The converter is invoked for all SQLite values of type *typename*; - it is passed a :class:`bytes` object and should return an object of the - desired Python type. - Consult the parameter *detect_types* of - :func:`connect` for information regarding how type detection works. - - Note: *typename* and the name of the type in your query are matched - case-insensitively. - - -.. function:: register_adapter(type, adapter, /) - - Register an *adapter* callable to adapt the Python type *type* into an - SQLite type. - The adapter is called with a Python object of type *type* as its sole - argument, and must return a value of a - :ref:`type that SQLite natively understands <sqlite3-types>`. - - .. function:: complete_statement(statement) Returns ``True`` if the string *statement* contains one or more complete SQL @@ -367,10 +229,8 @@ Module functions and constants This can be used to build a shell for SQLite, as in the following example: - .. literalinclude:: ../includes/sqlite3/complete_statement.py - .. function:: enable_callback_tracebacks(flag, /) Enable or disable callback tracebacks. @@ -398,6 +258,144 @@ Module functions and constants UnraisableHookArgs(exc_type=<class 'ZeroDivisionError'>, exc_value=ZeroDivisionError('division by zero'), exc_traceback=<traceback object at 0x10b559900>, err_msg=None, object=<function <lambda> at 0x10b4e3ee0>) <sqlite3.Cursor object at 0x10b1fe840> +.. function:: register_adapter(type, adapter, /) + + Register an *adapter* callable to adapt the Python type *type* into an + SQLite type. + The adapter is called with a Python object of type *type* as its sole + argument, and must return a value of a + :ref:`type that SQLite natively understands <sqlite3-types>`. + +.. function:: register_converter(typename, converter, /) + + Register the *converter* callable to convert SQLite objects of type + *typename* into a Python object of a specific type. + The converter is invoked for all SQLite values of type *typename*; + it is passed a :class:`bytes` object and should return an object of the + desired Python type. + Consult the parameter *detect_types* of + :func:`connect` for information regarding how type detection works. + + Note: *typename* and the name of the type in your query are matched + case-insensitively. + + +.. _sqlite3-module-constants: + +Module constants +^^^^^^^^^^^^^^^^ + +.. data:: PARSE_COLNAMES + + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function by + using the type name, parsed from the query column name, + as the converter dictionary key. + The type name must be wrapped in square brackets (``[]``). + + .. code-block:: sql + + SELECT p as "p [point]" FROM test; ! will look up converter "point" + + This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` + (bitwise or) operator. + +.. data:: PARSE_DECLTYPES + + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function using + the declared types for each column. + The types are declared when the database table is created. + :mod:`!sqlite3` will look up a converter function using the first word of the + declared type as the converter dictionary key. + For example: + + .. code-block:: sql + + CREATE TABLE test( + i integer primary key, ! will look up a converter named "integer" + p point, ! will look up a converter named "point" + n number(10) ! will look up a converter named "number" + ) + + This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` + (bitwise or) operator. + +.. data:: apilevel + + String constant stating the supported DB-API level. Required by the DB-API. + Hard-coded to ``"2.0"``. + +.. data:: paramstyle + + String constant stating the type of parameter marker formatting expected by + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to + ``"qmark"``. + + .. note:: + + The :mod:`!sqlite3` module supports both ``qmark`` and ``numeric`` DB-API + parameter styles, because that is what the underlying SQLite library + supports. However, the DB-API does not allow multiple values for + the ``paramstyle`` attribute. + +.. data:: sqlite_version + + Version number of the runtime SQLite library as a :class:`string <str>`. + +.. data:: sqlite_version_info + + Version number of the runtime SQLite library as a :class:`tuple` of + :class:`integers <int>`. + +.. data:: threadsafety + + Integer constant required by the DB-API 2.0, stating the level of thread + safety the :mod:`!sqlite3` module supports. This attribute is set based on + the default `threading mode <https://sqlite.org/threadsafe.html>`_ the + underlying SQLite library is compiled with. The SQLite threading modes are: + + 1. **Single-thread**: In this mode, all mutexes are disabled and SQLite is + unsafe to use in more than a single thread at once. + 2. **Multi-thread**: In this mode, SQLite can be safely used by multiple + threads provided that no single database connection is used + simultaneously in two or more threads. + 3. **Serialized**: In serialized mode, SQLite can be safely used by + multiple threads with no restriction. + + The mappings from SQLite threading modes to DB-API 2.0 threadsafety levels + are as follows: + + +------------------+-----------------+----------------------+-------------------------------+ + | SQLite threading | `threadsafety`_ | `SQLITE_THREADSAFE`_ | DB-API 2.0 meaning | + | mode | | | | + +==================+=================+======================+===============================+ + | single-thread | 0 | 0 | Threads may not share the | + | | | | module | + +------------------+-----------------+----------------------+-------------------------------+ + | multi-thread | 1 | 2 | Threads may share the module, | + | | | | but not connections | + +------------------+-----------------+----------------------+-------------------------------+ + | serialized | 3 | 1 | Threads may share the module, | + | | | | connections and cursors | + +------------------+-----------------+----------------------+-------------------------------+ + + .. _threadsafety: https://peps.python.org/pep-0249/#threadsafety + .. _SQLITE_THREADSAFE: https://sqlite.org/compile.html#threadsafe + + .. versionchanged:: 3.11 + Set *threadsafety* dynamically instead of hard-coding it to ``1``. + +.. data:: version + + Version number of this module as a :class:`string <str>`. + This is not the version of the SQLite library. + +.. data:: version_info + + Version number of this module as a :class:`tuple` of :class:`integers <int>`. + This is not the version of the SQLite library. + .. _sqlite3-connection-objects: From webhook-mailer at python.org Tue Aug 9 07:48:12 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 09 Aug 2022 11:48:12 -0000 Subject: [Python-checkins] gh-94635: Fixup sqlite3 'Introduction' seealso note (GH-95751) (#95752) Message-ID: <mailman.579.1660045693.3313.python-checkins@python.org> https://github.com/python/cpython/commit/88cae1c9c69f1f48e88956344f1983f32389f3e3 commit: 88cae1c9c69f1f48e88956344f1983f32389f3e3 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-09T13:48:08+02:00 summary: gh-94635: Fixup sqlite3 'Introduction' seealso note (GH-95751) (#95752) In gh-95269, the seealso note incorrectly ended up in the 'Tutorial' section. (cherry picked from commit 56af5a200d60e86a8ac450264729d693053275e3) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e88207fa640..1afb8c87b38 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -34,6 +34,18 @@ This document includes four main sections: * :ref:`sqlite3-explanation` provides in-depth background on transaction control. +.. seealso:: + + https://www.sqlite.org + The SQLite web page; the documentation describes the syntax and the + available data types for the supported SQL dialect. + + https://www.w3schools.com/sql/ + Tutorial, reference and examples for learning SQL syntax. + + :pep:`249` - Database API Specification 2.0 + PEP written by Marc-Andr? Lemburg. + .. _sqlite3-tutorial: @@ -114,18 +126,6 @@ You've now created an SQLite database using the :mod:`!sqlite3` module. .. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection -.. seealso:: - - https://www.sqlite.org - The SQLite web page; the documentation describes the syntax and the - available data types for the supported SQL dialect. - - https://www.w3schools.com/sql/ - Tutorial, reference and examples for learning SQL syntax. - - :pep:`249` - Database API Specification 2.0 - PEP written by Marc-Andr? Lemburg. - .. _sqlite3-reference: From webhook-mailer at python.org Tue Aug 9 09:27:00 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 09 Aug 2022 13:27:00 -0000 Subject: [Python-checkins] GH-92678: Document that you shouldn't be doing your own dictionary offset calculations. (GH-95598) Message-ID: <mailman.580.1660051621.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8d37c62c2a2579ae7839ecaf8351e862f2ecc9bb commit: 8d37c62c2a2579ae7839ecaf8351e862f2ecc9bb branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-09T14:26:37+01:00 summary: GH-92678: Document that you shouldn't be doing your own dictionary offset calculations. (GH-95598) Co-authored-by: Petr Viktorin <encukou at gmail.com> Co-authored-by: Stanley <46876382+slateny at users.noreply.github.com> files: M Doc/c-api/object.rst M Doc/c-api/typeobj.rst M Doc/whatsnew/3.11.rst M Objects/object.c diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 07a625bac02f..fb03366056b0 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -126,6 +126,14 @@ Object Protocol A generic implementation for the getter of a ``__dict__`` descriptor. It creates the dictionary if necessary. + This function may also be called to get the :py:attr:`~object.__dict__` + of the object *o*. Pass ``NULL`` for *context* when calling it. + Since this function may need to allocate memory for the + dictionary, it may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. + + On failure, returns ``NULL`` with an exception set. + .. versionadded:: 3.3 @@ -137,6 +145,16 @@ Object Protocol .. versionadded:: 3.3 +.. c:function:: PyObject** _PyObject_GetDictPtr(PyObject *obj) + + Return a pointer to :py:attr:`~object.__dict__` of the object *obj*. + If there is no ``__dict__``, return ``NULL`` without setting an exception. + + This function may need to allocate memory for the + dictionary, so it may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. + + .. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) Compare the values of *o1* and *o2* using the operation specified by *opid*, diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 3af48f408ea3..b8baa7c7dc39 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1715,18 +1715,11 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:member:`~PyTypeObject.tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is at the very end of the structure. - The real dictionary offset in an instance can be computed from a negative - :c:member:`~PyTypeObject.tp_dictoffset` as follows:: - - dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset - if dictoffset is not aligned on sizeof(void*): - round up to sizeof(void*) - - where :c:member:`~PyTypeObject.tp_basicsize`, :c:member:`~PyTypeObject.tp_itemsize` and :c:member:`~PyTypeObject.tp_dictoffset` are - taken from the type object, and :attr:`ob_size` is taken from the instance. The - absolute value is taken because ints use the sign of :attr:`ob_size` to - store the sign of the number. (There's never a need to do this calculation - yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.) + The :c:member:`~PyTypeObject.tp_dictoffset` should be regarded as write-only. + To get the pointer to the dictionary call :c:func:`PyObject_GenericGetDict`. + Calling :c:func:`PyObject_GenericGetDict` may need to allocate memory for the + dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. **Inheritance:** diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 88f62bc2d91b..39f1dab590a9 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1544,6 +1544,10 @@ Changes in the Python API :func:`compile` and other related functions. If invalid positions are detected, a :exc:`ValueError` will be raised. (Contributed by Pablo Galindo in :gh:`93351`) +* :c:member:`~PyTypeObject.tp_dictoffset` should be treated as write-only. + It can be set to describe C extension clases to the VM, but should be regarded + as meaningless when read. To get the pointer to the object's dictionary call + :c:func:`PyObject_GenericGetDict` instead. Build Changes ============= diff --git a/Objects/object.c b/Objects/object.c index f0c0434fab3d..a90c6faf99db 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1079,7 +1079,11 @@ _PyObject_ComputedDictPointer(PyObject *obj) /* Helper to get a pointer to an object's __dict__ slot, if any. * Creates the dict from inline attributes if necessary. - * Does not set an exception. */ + * Does not set an exception. + * + * Note that the tp_dictoffset docs used to recommend this function, + * so it should be treated as part of the public API. + */ PyObject ** _PyObject_GetDictPtr(PyObject *obj) { From webhook-mailer at python.org Tue Aug 9 09:59:45 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 09 Aug 2022 13:59:45 -0000 Subject: [Python-checkins] gh-95767: Fix grammatical error in asyncio loop.create_task docs (#95768) Message-ID: <mailman.581.1660053587.3313.python-checkins@python.org> https://github.com/python/cpython/commit/141f2517fc36cc7a0caf177f270edb6d39cf3d23 commit: 141f2517fc36cc7a0caf177f270edb6d39cf3d23 branch: main author: Andrzej Bartosi?ski <6197476+Neob91 at users.noreply.github.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-09T15:59:27+02:00 summary: gh-95767: Fix grammatical error in asyncio loop.create_task docs (#95768) files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 4f0f8c06fee..555a0f5cb2a 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -332,7 +332,7 @@ Creating Futures and Tasks .. method:: loop.create_task(coro, *, name=None, context=None) - Schedule the execution of a :ref:`coroutine`. + Schedule the execution of :ref:`coroutine <coroutine>` *coro*. Return a :class:`Task` object. Third-party event loops can use their own subclass of :class:`Task` From webhook-mailer at python.org Tue Aug 9 10:07:41 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 09 Aug 2022 14:07:41 -0000 Subject: [Python-checkins] gh-95767: Fix grammatical error in asyncio loop.create_task docs (GH-95768) Message-ID: <mailman.582.1660054062.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d57d86a59177aef3d66c42f969a0ed3fbf061c8c commit: d57d86a59177aef3d66c42f969a0ed3fbf061c8c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-09T07:07:21-07:00 summary: gh-95767: Fix grammatical error in asyncio loop.create_task docs (GH-95768) (cherry picked from commit 141f2517fc36cc7a0caf177f270edb6d39cf3d23) Co-authored-by: Andrzej Bartosi?ski <6197476+Neob91 at users.noreply.github.com> files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 300092d71b1..0e66b3e7a6c 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -332,7 +332,7 @@ Creating Futures and Tasks .. method:: loop.create_task(coro, *, name=None) - Schedule the execution of a :ref:`coroutine`. + Schedule the execution of :ref:`coroutine <coroutine>` *coro*. Return a :class:`Task` object. Third-party event loops can use their own subclass of :class:`Task` From webhook-mailer at python.org Tue Aug 9 10:09:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 09 Aug 2022 14:09:54 -0000 Subject: [Python-checkins] gh-95767: Fix grammatical error in asyncio loop.create_task docs (GH-95768) Message-ID: <mailman.583.1660054195.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2d36d5e2d7d2165f37c189187d985bc0794e5dba commit: 2d36d5e2d7d2165f37c189187d985bc0794e5dba branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-09T07:09:49-07:00 summary: gh-95767: Fix grammatical error in asyncio loop.create_task docs (GH-95768) (cherry picked from commit 141f2517fc36cc7a0caf177f270edb6d39cf3d23) Co-authored-by: Andrzej Bartosi?ski <6197476+Neob91 at users.noreply.github.com> files: M Doc/library/asyncio-eventloop.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 4f0f8c06fee..555a0f5cb2a 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -332,7 +332,7 @@ Creating Futures and Tasks .. method:: loop.create_task(coro, *, name=None, context=None) - Schedule the execution of a :ref:`coroutine`. + Schedule the execution of :ref:`coroutine <coroutine>` *coro*. Return a :class:`Task` object. Third-party event loops can use their own subclass of :class:`Task` From webhook-mailer at python.org Tue Aug 9 11:23:05 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 09 Aug 2022 15:23:05 -0000 Subject: [Python-checkins] GH-92678: Document that you shouldn't be doing your own dictionary offset calculations. (GH-95598) (GH-95821) Message-ID: <mailman.584.1660058587.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c96b26cb0639583731c78b7202ea2b8507ff1127 commit: c96b26cb0639583731c78b7202ea2b8507ff1127 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: markshannon <mark at hotpy.org> date: 2022-08-09T16:22:54+01:00 summary: GH-92678: Document that you shouldn't be doing your own dictionary offset calculations. (GH-95598) (GH-95821) Co-authored-by: Petr Viktorin <encukou at gmail.com> Co-authored-by: Stanley <46876382+slateny at users.noreply.github.com> Co-authored-by: Mark Shannon <mark at hotpy.org> files: M Doc/c-api/object.rst M Doc/c-api/typeobj.rst M Doc/whatsnew/3.11.rst M Objects/object.c diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 07a625bac02f..fb03366056b0 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -126,6 +126,14 @@ Object Protocol A generic implementation for the getter of a ``__dict__`` descriptor. It creates the dictionary if necessary. + This function may also be called to get the :py:attr:`~object.__dict__` + of the object *o*. Pass ``NULL`` for *context* when calling it. + Since this function may need to allocate memory for the + dictionary, it may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. + + On failure, returns ``NULL`` with an exception set. + .. versionadded:: 3.3 @@ -137,6 +145,16 @@ Object Protocol .. versionadded:: 3.3 +.. c:function:: PyObject** _PyObject_GetDictPtr(PyObject *obj) + + Return a pointer to :py:attr:`~object.__dict__` of the object *obj*. + If there is no ``__dict__``, return ``NULL`` without setting an exception. + + This function may need to allocate memory for the + dictionary, so it may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. + + .. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) Compare the values of *o1* and *o2* using the operation specified by *opid*, diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index e6df34e7db95..47e1c8602197 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1709,18 +1709,11 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:member:`~PyTypeObject.tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is at the very end of the structure. - The real dictionary offset in an instance can be computed from a negative - :c:member:`~PyTypeObject.tp_dictoffset` as follows:: - - dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset - if dictoffset is not aligned on sizeof(void*): - round up to sizeof(void*) - - where :c:member:`~PyTypeObject.tp_basicsize`, :c:member:`~PyTypeObject.tp_itemsize` and :c:member:`~PyTypeObject.tp_dictoffset` are - taken from the type object, and :attr:`ob_size` is taken from the instance. The - absolute value is taken because ints use the sign of :attr:`ob_size` to - store the sign of the number. (There's never a need to do this calculation - yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.) + The :c:member:`~PyTypeObject.tp_dictoffset` should be regarded as write-only. + To get the pointer to the dictionary call :c:func:`PyObject_GenericGetDict`. + Calling :c:func:`PyObject_GenericGetDict` may need to allocate memory for the + dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. **Inheritance:** diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 3ea3fa63d408..a36564a8ab19 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1549,6 +1549,10 @@ Changes in the Python API :func:`compile` and other related functions. If invalid positions are detected, a :exc:`ValueError` will be raised. (Contributed by Pablo Galindo in :gh:`93351`) +* :c:member:`~PyTypeObject.tp_dictoffset` should be treated as write-only. + It can be set to describe C extension clases to the VM, but should be regarded + as meaningless when read. To get the pointer to the object's dictionary call + :c:func:`PyObject_GenericGetDict` instead. Build Changes ============= diff --git a/Objects/object.c b/Objects/object.c index d9fa779462a9..cb7853ca8cfd 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1086,7 +1086,11 @@ _PyObject_DictPointer(PyObject *obj) /* Helper to get a pointer to an object's __dict__ slot, if any. * Creates the dict from inline attributes if necessary. - * Does not set an exception. */ + * Does not set an exception. + * + * Note that the tp_dictoffset docs used to recommend this function, + * so it should be treated as part of the public API. + */ PyObject ** _PyObject_GetDictPtr(PyObject *obj) { From webhook-mailer at python.org Tue Aug 9 13:38:46 2022 From: webhook-mailer at python.org (terryjreedy) Date: Tue, 09 Aug 2022 17:38:46 -0000 Subject: [Python-checkins] gh-95491: Mention IDLE Issue project in Readme (GH-95750) (#95791) Message-ID: <mailman.585.1660066727.3313.python-checkins@python.org> https://github.com/python/cpython/commit/77fccc29dfab51e924848dda6ee14db24d789064 commit: 77fccc29dfab51e924848dda6ee14db24d789064 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-09T13:38:36-04:00 summary: gh-95491: Mention IDLE Issue project in Readme (GH-95750) (#95791) (cherry picked from commit 63140b445e4a303df430b3d60c1cd4ef34f27c03) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/README.txt diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index 779b51c1b931..76aec58912f0 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -280,3 +280,11 @@ first back-ported feature after 3.n.0 is released. Since each older version file gets a different number of backports, it is easiest to make a separate PR for each file and label it with the backports needed. + +Github repository and issues +---------------------------- + +The CPython repository is https://github.com/python/cpython. The +IDLE Issues listing is https://github.com/orgs/python/projects/31. +The main classification is by Topic, based on the IDLE menu. View the +topics list by clicking the [<]] button in the upper right. From webhook-mailer at python.org Tue Aug 9 13:42:20 2022 From: webhook-mailer at python.org (terryjreedy) Date: Tue, 09 Aug 2022 17:42:20 -0000 Subject: [Python-checkins] [3.11] gh-88878: IDLE - replace type('') with str (#95792) Message-ID: <mailman.586.1660066941.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1a22ec5d69c2cbe51afdaff2cc3bc25a9514dd4f commit: 1a22ec5d69c2cbe51afdaff2cc3bc25a9514dd4f branch: 3.11 author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-09T13:42:16-04:00 summary: [3.11] gh-88878: IDLE - replace type('') with str (#95792) Change in idlelib.browser, line 54 cherrypicked from 3680ebed7f3e529d01996dd0318601f9f0d02b4b files: M Lib/idlelib/browser.py diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py index 10d9a7261113..4fe64dced60a 100644 --- a/Lib/idlelib/browser.py +++ b/Lib/idlelib/browser.py @@ -52,7 +52,7 @@ def transform_children(child_dict, modname=None): # If obj.name != key, it has already been suffixed. supers = [] for sup in obj.super: - if type(sup) is type(''): + if isinstance(sup, str): sname = sup else: sname = sup.name From webhook-mailer at python.org Tue Aug 9 14:10:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 09 Aug 2022 18:10:16 -0000 Subject: [Python-checkins] [3.11] gh-88878: IDLE - replace type('') with str (GH-95792) Message-ID: <mailman.587.1660068617.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a9c25cdd0dccdd617f1fd3edcb2b89db6f283e25 commit: a9c25cdd0dccdd617f1fd3edcb2b89db6f283e25 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-09T11:10:00-07:00 summary: [3.11] gh-88878: IDLE - replace type('') with str (GH-95792) Change in idlelib.browser, line 54 cherrypicked from 3680ebed7f3e529d01996dd0318601f9f0d02b4b (cherry picked from commit 1a22ec5d69c2cbe51afdaff2cc3bc25a9514dd4f) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/browser.py diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py index 10d9a7261113..4fe64dced60a 100644 --- a/Lib/idlelib/browser.py +++ b/Lib/idlelib/browser.py @@ -52,7 +52,7 @@ def transform_children(child_dict, modname=None): # If obj.name != key, it has already been suffixed. supers = [] for sup in obj.super: - if type(sup) is type(''): + if isinstance(sup, str): sname = sup else: sname = sup.name From webhook-mailer at python.org Tue Aug 9 14:34:59 2022 From: webhook-mailer at python.org (terryjreedy) Date: Tue, 09 Aug 2022 18:34:59 -0000 Subject: [Python-checkins] gh-75500: Add idlelib section to IDLE doc (#95832) Message-ID: <mailman.588.1660070101.3313.python-checkins@python.org> https://github.com/python/cpython/commit/70fc9641b56144854777aef29c145cd10789e3df commit: 70fc9641b56144854777aef29c145cd10789e3df branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-09T14:34:42-04:00 summary: gh-75500: Add idlelib section to IDLE doc (#95832) This enables accessing IDLE as 'idlelib' in the Doc Module listing. files: M Doc/library/idle.rst M Lib/idlelib/help.html diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index f2ef72d682bd..81e0182e10be 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -983,3 +983,20 @@ changed with the Extensions tab of the preferences dialog. See the beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + +idlelib +^^^^^^^ + +.. module:: idlelib + :synopsis: Implementation package for the IDLE shell/editor. + +**Source code:** :source:`Lib/idlelib` + +The Lib/idlelib package implements the IDLE application. See the top +of this file or content listing on the left for how to use IDLE. + +The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under 'Startup', the idlelib code is 'private' in +sense that feature changes can be backported (see :pep:`434`). diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index ac386122cc71..af5cbd5a5ba4 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -113,6 +113,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li> <li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li> <li><a class="reference internal" href="#extensions">Extensions</a></li> +<li><a class="reference internal" href="#module-idlelib">idlelib</a></li> </ul> </li> </ul> @@ -1001,6 +1002,17 @@ <h3>Extensions<a class="headerlink" href="#extensions" title="Permalink to this information. The only current default extension is zzdummy, an example also used for testing.</p> </section> +<section id="module-idlelib"> +<span id="idlelib"></span><h3>idlelib<a class="headerlink" href="#module-idlelib" title="Permalink to this heading">?</a></h3> +<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/main/Lib/idlelib">Lib/idlelib</a></p> +<p>The Lib/idlelib package implements the IDLE application. See the top +of this file or content listing on the left for how to use IDLE.</p> +<p>The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under ?Startup?, the idlelib code is ?private? in +sense that feature changes can be backported (see <span class="target" id="index-7"></span><a class="pep reference external" href="https://peps.python.org/pep-0434/"><strong>PEP 434</strong></a>).</p> +</section> </section> </section> @@ -1054,6 +1066,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li> <li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li> <li><a class="reference internal" href="#extensions">Extensions</a></li> +<li><a class="reference internal" href="#module-idlelib">idlelib</a></li> </ul> </li> </ul> @@ -1153,7 +1166,7 @@ <h3>Navigation</h3> <br /> <br /> - Last updated on Aug 05, 2022. + Last updated on Aug 07, 2022. <a href="/bugs.html">Found a bug</a>? <br /> From webhook-mailer at python.org Tue Aug 9 15:33:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 09 Aug 2022 19:33:36 -0000 Subject: [Python-checkins] gh-75500: Add idlelib section to IDLE doc (GH-95832) Message-ID: <mailman.589.1660073616.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c6aa68fdf57940305cb0371f1c22dfebe1497c24 commit: c6aa68fdf57940305cb0371f1c22dfebe1497c24 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-09T12:33:23-07:00 summary: gh-75500: Add idlelib section to IDLE doc (GH-95832) This enables accessing IDLE as 'idlelib' in the Doc Module listing. (cherry picked from commit 70fc9641b56144854777aef29c145cd10789e3df) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/library/idle.rst M Lib/idlelib/help.html diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index f2ef72d682bd..81e0182e10be 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -983,3 +983,20 @@ changed with the Extensions tab of the preferences dialog. See the beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + +idlelib +^^^^^^^ + +.. module:: idlelib + :synopsis: Implementation package for the IDLE shell/editor. + +**Source code:** :source:`Lib/idlelib` + +The Lib/idlelib package implements the IDLE application. See the top +of this file or content listing on the left for how to use IDLE. + +The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under 'Startup', the idlelib code is 'private' in +sense that feature changes can be backported (see :pep:`434`). diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index ac386122cc71..af5cbd5a5ba4 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -113,6 +113,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li> <li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li> <li><a class="reference internal" href="#extensions">Extensions</a></li> +<li><a class="reference internal" href="#module-idlelib">idlelib</a></li> </ul> </li> </ul> @@ -1001,6 +1002,17 @@ <h3>Extensions<a class="headerlink" href="#extensions" title="Permalink to this information. The only current default extension is zzdummy, an example also used for testing.</p> </section> +<section id="module-idlelib"> +<span id="idlelib"></span><h3>idlelib<a class="headerlink" href="#module-idlelib" title="Permalink to this heading">?</a></h3> +<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/main/Lib/idlelib">Lib/idlelib</a></p> +<p>The Lib/idlelib package implements the IDLE application. See the top +of this file or content listing on the left for how to use IDLE.</p> +<p>The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under ?Startup?, the idlelib code is ?private? in +sense that feature changes can be backported (see <span class="target" id="index-7"></span><a class="pep reference external" href="https://peps.python.org/pep-0434/"><strong>PEP 434</strong></a>).</p> +</section> </section> </section> @@ -1054,6 +1066,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li> <li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li> <li><a class="reference internal" href="#extensions">Extensions</a></li> +<li><a class="reference internal" href="#module-idlelib">idlelib</a></li> </ul> </li> </ul> @@ -1153,7 +1166,7 @@ <h3>Navigation</h3> <br /> <br /> - Last updated on Aug 05, 2022. + Last updated on Aug 07, 2022. <a href="/bugs.html">Found a bug</a>? <br /> From webhook-mailer at python.org Tue Aug 9 15:33:42 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 09 Aug 2022 19:33:42 -0000 Subject: [Python-checkins] gh-75500: Add idlelib section to IDLE doc (GH-95832) Message-ID: <mailman.590.1660073623.3313.python-checkins@python.org> https://github.com/python/cpython/commit/64abb733549df3851b6060a5341700acd5efc62b commit: 64abb733549df3851b6060a5341700acd5efc62b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-09T12:33:37-07:00 summary: gh-75500: Add idlelib section to IDLE doc (GH-95832) This enables accessing IDLE as 'idlelib' in the Doc Module listing. (cherry picked from commit 70fc9641b56144854777aef29c145cd10789e3df) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/library/idle.rst M Lib/idlelib/help.html diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index f2ef72d682b..81e0182e10b 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -983,3 +983,20 @@ changed with the Extensions tab of the preferences dialog. See the beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + +idlelib +^^^^^^^ + +.. module:: idlelib + :synopsis: Implementation package for the IDLE shell/editor. + +**Source code:** :source:`Lib/idlelib` + +The Lib/idlelib package implements the IDLE application. See the top +of this file or content listing on the left for how to use IDLE. + +The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under 'Startup', the idlelib code is 'private' in +sense that feature changes can be backported (see :pep:`434`). diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index ac386122cc7..af5cbd5a5ba 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -113,6 +113,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li> <li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li> <li><a class="reference internal" href="#extensions">Extensions</a></li> +<li><a class="reference internal" href="#module-idlelib">idlelib</a></li> </ul> </li> </ul> @@ -1001,6 +1002,17 @@ <h3>Extensions<a class="headerlink" href="#extensions" title="Permalink to this information. The only current default extension is zzdummy, an example also used for testing.</p> </section> +<section id="module-idlelib"> +<span id="idlelib"></span><h3>idlelib<a class="headerlink" href="#module-idlelib" title="Permalink to this heading">?</a></h3> +<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/main/Lib/idlelib">Lib/idlelib</a></p> +<p>The Lib/idlelib package implements the IDLE application. See the top +of this file or content listing on the left for how to use IDLE.</p> +<p>The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under ?Startup?, the idlelib code is ?private? in +sense that feature changes can be backported (see <span class="target" id="index-7"></span><a class="pep reference external" href="https://peps.python.org/pep-0434/"><strong>PEP 434</strong></a>).</p> +</section> </section> </section> @@ -1054,6 +1066,7 @@ <h3><a href="../contents.html">Table of Contents</a></h3> <li><a class="reference internal" href="#setting-preferences">Setting preferences</a></li> <li><a class="reference internal" href="#idle-on-macos">IDLE on macOS</a></li> <li><a class="reference internal" href="#extensions">Extensions</a></li> +<li><a class="reference internal" href="#module-idlelib">idlelib</a></li> </ul> </li> </ul> @@ -1153,7 +1166,7 @@ <h3>Navigation</h3> <br /> <br /> - Last updated on Aug 05, 2022. + Last updated on Aug 07, 2022. <a href="/bugs.html">Found a bug</a>? <br /> From webhook-mailer at python.org Tue Aug 9 19:04:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 09 Aug 2022 23:04:21 -0000 Subject: [Python-checkins] gh-95349: Hide a Distutils Warning Filter for test_check_c_globals (GH-95837) Message-ID: <mailman.591.1660086261.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3ff6d9affb351292ad8530802e7c06f651520706 commit: 3ff6d9affb351292ad8530802e7c06f651520706 branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-09T16:04:05-07:00 summary: gh-95349: Hide a Distutils Warning Filter for test_check_c_globals (GH-95837) Under certain build conditions, test_check_c_globals fails. This fix takes the same approach as we took for gh-84236 (via gh-20095). We'll be removing use of distutils in the c-analyzer at some point. Until then we'll hide the warning filter. files: M Lib/test/test_check_c_globals.py diff --git a/Lib/test/test_check_c_globals.py b/Lib/test/test_check_c_globals.py index 030debc452e4..898807a5e692 100644 --- a/Lib/test/test_check_c_globals.py +++ b/Lib/test/test_check_c_globals.py @@ -1,9 +1,14 @@ import unittest import test.test_tools +from test.support.warnings_helper import save_restore_warnings_filters test.test_tools.skip_if_missing('c-analyzer') with test.test_tools.imports_under_tool('c-analyzer'): - from cpython.__main__ import main + # gh-95349: Save/restore warnings filters to leave them unchanged. + # Importing the c-analyzer imports docutils which imports pkg_resources + # which adds a warnings filter. + with save_restore_warnings_filters(): + from cpython.__main__ import main class ActualChecks(unittest.TestCase): From webhook-mailer at python.org Wed Aug 10 01:40:35 2022 From: webhook-mailer at python.org (rhettinger) Date: Wed, 10 Aug 2022 05:40:35 -0000 Subject: [Python-checkins] Fix documentation typo for functools.cmp_to_key (GH-95766) (#95777) Message-ID: <mailman.592.1660110036.3313.python-checkins@python.org> https://github.com/python/cpython/commit/346aa78af4145135465d68a3b647d55e7366d0b2 commit: 346aa78af4145135465d68a3b647d55e7366d0b2 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-10T00:40:15-05:00 summary: Fix documentation typo for functools.cmp_to_key (GH-95766) (#95777) files: M Doc/library/functools.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index c78818bfab1..188443c2964 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -119,7 +119,7 @@ The :mod:`functools` module defines the following functions: tool for programs being converted from Python 2 which supported the use of comparison functions. - A comparison function is any callable that accept two arguments, compares them, + A comparison function is any callable that accepts two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one argument and returns another value to be used as the sort key. From webhook-mailer at python.org Wed Aug 10 03:10:46 2022 From: webhook-mailer at python.org (encukou) Date: Wed, 10 Aug 2022 07:10:46 -0000 Subject: [Python-checkins] gh-93649: Split unicode tests from _testcapimodule.c & add some more (GH-95819) Message-ID: <mailman.593.1660115447.3313.python-checkins@python.org> https://github.com/python/cpython/commit/325ae93b6b7113cd4a4c2ce441615ae7def779e2 commit: 325ae93b6b7113cd4a4c2ce441615ae7def779e2 branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-10T09:10:25+02:00 summary: gh-93649: Split unicode tests from _testcapimodule.c & add some more (GH-95819) - Move PyUnicode tests to a separate file - Add some more tests for PyUnicode_FromFormat Co-authored-by: philg314 <110174000+philg314 at users.noreply.github.com> files: A Modules/_testcapi/unicode.c M Misc/ACKS M Modules/Setup.stdlib.in M Modules/_testcapi/parts.h M Modules/_testcapimodule.c M PCbuild/_testcapi.vcxproj M PCbuild/_testcapi.vcxproj.filters diff --git a/Misc/ACKS b/Misc/ACKS index b18fabe09ef4..7065267379de 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -609,6 +609,7 @@ Jan-Philip Gehrcke Thomas Gellekum Gabriel Genellina Christos Georgiou +Philip Georgi Elazar (?????) Gershuni Ben Gertzfield Nadim Ghaznavi diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 908e6df97667..ac8959ebea5b 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -169,7 +169,7 @@ @MODULE__XXTESTFUZZ_TRUE at _xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE at _testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE at _testinternalcapi _testinternalcapi.c - at MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c + at MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c # Some testing modules MUST be built as shared libraries. *shared* diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index 4b672c9d05bd..c0e0f3aa1cc2 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -3,3 +3,4 @@ int _PyTestCapi_Init_Vectorcall(PyObject *module); int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_Heaptype(PyObject *module); +int _PyTestCapi_Init_Unicode(PyObject *module); diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c new file mode 100644 index 000000000000..58214249e225 --- /dev/null +++ b/Modules/_testcapi/unicode.c @@ -0,0 +1,653 @@ +#include "parts.h" + +static struct PyModuleDef *_testcapimodule = NULL; // set at initialization + +static PyObject * +codec_incrementalencoder(PyObject *self, PyObject *args) +{ + const char *encoding, *errors = NULL; + if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", + &encoding, &errors)) + return NULL; + return PyCodec_IncrementalEncoder(encoding, errors); +} + +static PyObject * +codec_incrementaldecoder(PyObject *self, PyObject *args) +{ + const char *encoding, *errors = NULL; + if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", + &encoding, &errors)) + return NULL; + return PyCodec_IncrementalDecoder(encoding, errors); +} + +static PyObject * +test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { + PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); + int result; + if (py_s == NULL) + return NULL; + result = PyUnicode_CompareWithASCIIString(py_s, "str"); + Py_DECREF(py_s); + if (!result) { + PyErr_SetString(PyExc_AssertionError, "Python string ending in NULL " + "should not compare equal to c string."); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ +#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) + const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; + size_t wtextlen = 1; + const wchar_t invalid[1] = {(wchar_t)0x110000u}; +#else + const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; + size_t wtextlen = 2; +#endif + PyObject *wide, *utf8; + + wide = PyUnicode_FromWideChar(wtext, wtextlen); + if (wide == NULL) + return NULL; + + utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); + if (utf8 == NULL) { + Py_DECREF(wide); + return NULL; + } + + if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { + Py_DECREF(wide); + Py_DECREF(utf8); + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "wide string and utf8 string " + "have different length"); + return NULL; + } + if (PyUnicode_Compare(wide, utf8)) { + Py_DECREF(wide); + Py_DECREF(utf8); + if (PyErr_Occurred()) + return NULL; + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "wide string and utf8 string " + "are different"); + return NULL; + } + + Py_DECREF(wide); + Py_DECREF(utf8); + +#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) + wide = PyUnicode_FromWideChar(invalid, 1); + if (wide == NULL) + PyErr_Clear(); + else { + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); + return NULL; + } +#endif + Py_RETURN_NONE; +} + +static PyObject * +unicode_aswidechar(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t buflen, size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) + return NULL; + buffer = PyMem_New(wchar_t, buflen); + if (buffer == NULL) + return PyErr_NoMemory(); + + size = PyUnicode_AsWideChar(unicode, buffer, buflen); + if (size == -1) { + PyMem_Free(buffer); + return NULL; + } + + if (size < buflen) + buflen = size + 1; + else + buflen = size; + result = PyUnicode_FromWideChar(buffer, buflen); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + + return Py_BuildValue("(Nn)", result, size); +} + +static PyObject * +unicode_aswidecharstring(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "U", &unicode)) + return NULL; + + buffer = PyUnicode_AsWideCharString(unicode, &size); + if (buffer == NULL) + return NULL; + + result = PyUnicode_FromWideChar(buffer, size + 1); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + return Py_BuildValue("(Nn)", result, size); +} + +static PyObject * +unicode_asucs4(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_UCS4 *buffer; + int copy_null; + Py_ssize_t str_len, buf_len; + + if (!PyArg_ParseTuple(args, "Unp:unicode_asucs4", &unicode, &str_len, ©_null)) { + return NULL; + } + + buf_len = str_len + 1; + buffer = PyMem_NEW(Py_UCS4, buf_len); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + memset(buffer, 0, sizeof(Py_UCS4)*buf_len); + buffer[str_len] = 0xffffU; + + if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { + PyMem_Free(buffer); + return NULL; + } + + result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); + PyMem_Free(buffer); + return result; +} + +static PyObject * +unicode_asutf8(PyObject *self, PyObject *args) +{ + PyObject *unicode; + const char *buffer; + + if (!PyArg_ParseTuple(args, "U", &unicode)) { + return NULL; + } + + buffer = PyUnicode_AsUTF8(unicode); + if (buffer == NULL) { + return NULL; + } + + return PyBytes_FromString(buffer); +} + +static PyObject * +unicode_asutf8andsize(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + const char *buffer; + Py_ssize_t utf8_len; + + if(!PyArg_ParseTuple(args, "U", &unicode)) { + return NULL; + } + + buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); + if (buffer == NULL) { + return NULL; + } + + result = PyBytes_FromString(buffer); + if (result == NULL) { + return NULL; + } + + return Py_BuildValue("(Nn)", result, utf8_len); +} + +static PyObject * +unicode_findchar(PyObject *self, PyObject *args) +{ + PyObject *str; + int direction; + unsigned int ch; + Py_ssize_t result; + Py_ssize_t start, end; + + if (!PyArg_ParseTuple(args, "UInni:unicode_findchar", &str, &ch, + &start, &end, &direction)) { + return NULL; + } + + result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); + if (result == -2) + return NULL; + else + return PyLong_FromSsize_t(result); +} + +static PyObject * +unicode_copycharacters(PyObject *self, PyObject *args) +{ + PyObject *from, *to, *to_copy; + Py_ssize_t from_start, to_start, how_many, copied; + + if (!PyArg_ParseTuple(args, "UnOnn:unicode_copycharacters", &to, &to_start, + &from, &from_start, &how_many)) { + return NULL; + } + + if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), + PyUnicode_MAX_CHAR_VALUE(to)))) { + return NULL; + } + if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { + Py_DECREF(to_copy); + return NULL; + } + + if ((copied = PyUnicode_CopyCharacters(to_copy, to_start, from, + from_start, how_many)) < 0) { + Py_DECREF(to_copy); + return NULL; + } + + return Py_BuildValue("(Nn)", to_copy, copied); +} + +static int +check_raised_systemerror(PyObject *result, char* msg) +{ + if (result) { + // no exception + PyErr_Format(PyExc_AssertionError, + "SystemError not raised: %s", + msg); + return 0; + } + if (PyErr_ExceptionMatches(PyExc_SystemError)) { + // expected exception + PyErr_Clear(); + return 1; + } + // unexpected exception + return 0; +} + +static PyObject * +test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *result; + PyObject *unicode = PyUnicode_FromString("None"); + +#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2) \ + result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2); \ + if (EXPECTED == NULL) { \ + if (!check_raised_systemerror(result, FORMAT)) { \ + goto Fail; \ + } \ + } \ + else if (result == NULL) \ + return NULL; \ + else if (!_PyUnicode_EqualToASCIIString(result, EXPECTED)) { \ + PyErr_Format(PyExc_AssertionError, \ + "test_string_from_format: failed at \"%s\" " \ + "expected \"%s\" got \"%s\"", \ + FORMAT, EXPECTED, PyUnicode_AsUTF8(result)); \ + goto Fail; \ + } \ + Py_XDECREF(result) + +#define CHECK_FORMAT_1(FORMAT, EXPECTED, ARG) \ + CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0) + +#define CHECK_FORMAT_0(FORMAT, EXPECTED) \ + CHECK_FORMAT_2(FORMAT, EXPECTED, 0, 0) + + // Unrecognized + CHECK_FORMAT_2("%u %? %u", NULL, 1, 2); + + // "%%" (options are rejected) + CHECK_FORMAT_0( "%%", "%"); + CHECK_FORMAT_0( "%0%", NULL); + CHECK_FORMAT_0("%00%", NULL); + CHECK_FORMAT_0( "%2%", NULL); + CHECK_FORMAT_0("%02%", NULL); + CHECK_FORMAT_0("%.0%", NULL); + CHECK_FORMAT_0("%.2%", NULL); + + // "%c" + CHECK_FORMAT_1( "%c", "c", 'c'); + CHECK_FORMAT_1( "%0c", "c", 'c'); + CHECK_FORMAT_1("%00c", "c", 'c'); + CHECK_FORMAT_1( "%2c", "c", 'c'); + CHECK_FORMAT_1("%02c", "c", 'c'); + CHECK_FORMAT_1("%.0c", "c", 'c'); + CHECK_FORMAT_1("%.2c", "c", 'c'); + + // Integers + CHECK_FORMAT_1("%d", "123", (int)123); + CHECK_FORMAT_1("%i", "123", (int)123); + CHECK_FORMAT_1("%u", "123", (unsigned int)123); + CHECK_FORMAT_1("%ld", "123", (long)123); + CHECK_FORMAT_1("%li", "123", (long)123); + CHECK_FORMAT_1("%lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%lld", "123", (long long)123); + CHECK_FORMAT_1("%lli", "123", (long long)123); + CHECK_FORMAT_1("%llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%zu", "123", (size_t)123); + CHECK_FORMAT_1("%x", "7b", (int)123); + + CHECK_FORMAT_1("%d", "-123", (int)-123); + CHECK_FORMAT_1("%i", "-123", (int)-123); + CHECK_FORMAT_1("%ld", "-123", (long)-123); + CHECK_FORMAT_1("%li", "-123", (long)-123); + CHECK_FORMAT_1("%lld", "-123", (long long)-123); + CHECK_FORMAT_1("%lli", "-123", (long long)-123); + CHECK_FORMAT_1("%zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%x", "ffffff85", (int)-123); + + // Integers: width < length + CHECK_FORMAT_1("%1d", "123", (int)123); + CHECK_FORMAT_1("%1i", "123", (int)123); + CHECK_FORMAT_1("%1u", "123", (unsigned int)123); + CHECK_FORMAT_1("%1ld", "123", (long)123); + CHECK_FORMAT_1("%1li", "123", (long)123); + CHECK_FORMAT_1("%1lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%1lld", "123", (long long)123); + CHECK_FORMAT_1("%1lli", "123", (long long)123); + CHECK_FORMAT_1("%1llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%1zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%1zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%1zu", "123", (size_t)123); + CHECK_FORMAT_1("%1x", "7b", (int)123); + + CHECK_FORMAT_1("%1d", "-123", (int)-123); + CHECK_FORMAT_1("%1i", "-123", (int)-123); + CHECK_FORMAT_1("%1ld", "-123", (long)-123); + CHECK_FORMAT_1("%1li", "-123", (long)-123); + CHECK_FORMAT_1("%1lld", "-123", (long long)-123); + CHECK_FORMAT_1("%1lli", "-123", (long long)-123); + CHECK_FORMAT_1("%1zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%1zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%1x", "ffffff85", (int)-123); + + // Integers: width > length + CHECK_FORMAT_1("%5d", " 123", (int)123); + CHECK_FORMAT_1("%5i", " 123", (int)123); + CHECK_FORMAT_1("%5u", " 123", (unsigned int)123); + CHECK_FORMAT_1("%5ld", " 123", (long)123); + CHECK_FORMAT_1("%5li", " 123", (long)123); + CHECK_FORMAT_1("%5lu", " 123", (unsigned long)123); + CHECK_FORMAT_1("%5lld", " 123", (long long)123); + CHECK_FORMAT_1("%5lli", " 123", (long long)123); + CHECK_FORMAT_1("%5llu", " 123", (unsigned long long)123); + CHECK_FORMAT_1("%5zd", " 123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5zi", " 123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5zu", " 123", (size_t)123); + CHECK_FORMAT_1("%5x", " 7b", (int)123); + + CHECK_FORMAT_1("%5d", " -123", (int)-123); + CHECK_FORMAT_1("%5i", " -123", (int)-123); + CHECK_FORMAT_1("%5ld", " -123", (long)-123); + CHECK_FORMAT_1("%5li", " -123", (long)-123); + CHECK_FORMAT_1("%5lld", " -123", (long long)-123); + CHECK_FORMAT_1("%5lli", " -123", (long long)-123); + CHECK_FORMAT_1("%5zd", " -123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%5zi", " -123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%9x", " ffffff85", (int)-123); + + // Integers: width > length, 0-flag + CHECK_FORMAT_1("%05d", "00123", (int)123); + CHECK_FORMAT_1("%05i", "00123", (int)123); + CHECK_FORMAT_1("%05u", "00123", (unsigned int)123); + CHECK_FORMAT_1("%05ld", "00123", (long)123); + CHECK_FORMAT_1("%05li", "00123", (long)123); + CHECK_FORMAT_1("%05lu", "00123", (unsigned long)123); + CHECK_FORMAT_1("%05lld", "00123", (long long)123); + CHECK_FORMAT_1("%05lli", "00123", (long long)123); + CHECK_FORMAT_1("%05llu", "00123", (unsigned long long)123); + CHECK_FORMAT_1("%05zd", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05zi", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05zu", "00123", (size_t)123); + CHECK_FORMAT_1("%05x", "0007b", (int)123); + + // Integers: precision < length + CHECK_FORMAT_1("%.1d", "123", (int)123); + CHECK_FORMAT_1("%.1i", "123", (int)123); + CHECK_FORMAT_1("%.1u", "123", (unsigned int)123); + CHECK_FORMAT_1("%.1ld", "123", (long)123); + CHECK_FORMAT_1("%.1li", "123", (long)123); + CHECK_FORMAT_1("%.1lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%.1lld", "123", (long long)123); + CHECK_FORMAT_1("%.1lli", "123", (long long)123); + CHECK_FORMAT_1("%.1llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%.1zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.1zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.1zu", "123", (size_t)123); + CHECK_FORMAT_1("%.1x", "7b", (int)123); + + CHECK_FORMAT_1("%.1d", "-123", (int)-123); + CHECK_FORMAT_1("%.1i", "-123", (int)-123); + CHECK_FORMAT_1("%.1ld", "-123", (long)-123); + CHECK_FORMAT_1("%.1li", "-123", (long)-123); + CHECK_FORMAT_1("%.1lld", "-123", (long long)-123); + CHECK_FORMAT_1("%.1lli", "-123", (long long)-123); + CHECK_FORMAT_1("%.1zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.1zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.1x", "ffffff85", (int)-123); + + // Integers: precision > length + CHECK_FORMAT_1("%.5d", "00123", (int)123); + CHECK_FORMAT_1("%.5i", "00123", (int)123); + CHECK_FORMAT_1("%.5u", "00123", (unsigned int)123); + CHECK_FORMAT_1("%.5ld", "00123", (long)123); + CHECK_FORMAT_1("%.5li", "00123", (long)123); + CHECK_FORMAT_1("%.5lu", "00123", (unsigned long)123); + CHECK_FORMAT_1("%.5lld", "00123", (long long)123); + CHECK_FORMAT_1("%.5lli", "00123", (long long)123); + CHECK_FORMAT_1("%.5llu", "00123", (unsigned long long)123); + CHECK_FORMAT_1("%.5zd", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.5zi", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.5zu", "00123", (size_t)123); + CHECK_FORMAT_1("%.5x", "0007b", (int)123); + + // Integers: width > precision > length + CHECK_FORMAT_1("%7.5d", " 00123", (int)123); + CHECK_FORMAT_1("%7.5i", " 00123", (int)123); + CHECK_FORMAT_1("%7.5u", " 00123", (unsigned int)123); + CHECK_FORMAT_1("%7.5ld", " 00123", (long)123); + CHECK_FORMAT_1("%7.5li", " 00123", (long)123); + CHECK_FORMAT_1("%7.5lu", " 00123", (unsigned long)123); + CHECK_FORMAT_1("%7.5lld", " 00123", (long long)123); + CHECK_FORMAT_1("%7.5lli", " 00123", (long long)123); + CHECK_FORMAT_1("%7.5llu", " 00123", (unsigned long long)123); + CHECK_FORMAT_1("%7.5zd", " 00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%7.5zi", " 00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%7.5zu", " 00123", (size_t)123); + CHECK_FORMAT_1("%7.5x", " 0007b", (int)123); + + // Integers: width > precision > length, 0-flag + CHECK_FORMAT_1("%07.5d", "0000123", (int)123); + CHECK_FORMAT_1("%07.5i", "0000123", (int)123); + CHECK_FORMAT_1("%07.5u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%07.5ld", "0000123", (long)123); + CHECK_FORMAT_1("%07.5li", "0000123", (long)123); + CHECK_FORMAT_1("%07.5lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%07.5lld", "0000123", (long long)123); + CHECK_FORMAT_1("%07.5lli", "0000123", (long long)123); + CHECK_FORMAT_1("%07.5llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%07.5zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%07.5zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%07.5zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%07.5x", "000007b", (int)123); + + // Integers: precision > width > length + CHECK_FORMAT_1("%5.7d", "0000123", (int)123); + CHECK_FORMAT_1("%5.7i", "0000123", (int)123); + CHECK_FORMAT_1("%5.7u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%5.7ld", "0000123", (long)123); + CHECK_FORMAT_1("%5.7li", "0000123", (long)123); + CHECK_FORMAT_1("%5.7lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%5.7lld", "0000123", (long long)123); + CHECK_FORMAT_1("%5.7lli", "0000123", (long long)123); + CHECK_FORMAT_1("%5.7llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%5.7zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5.7zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5.7zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%5.7x", "000007b", (int)123); + + // Integers: precision > width > length, 0-flag + CHECK_FORMAT_1("%05.7d", "0000123", (int)123); + CHECK_FORMAT_1("%05.7i", "0000123", (int)123); + CHECK_FORMAT_1("%05.7u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%05.7ld", "0000123", (long)123); + CHECK_FORMAT_1("%05.7li", "0000123", (long)123); + CHECK_FORMAT_1("%05.7lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%05.7lld", "0000123", (long long)123); + CHECK_FORMAT_1("%05.7lli", "0000123", (long long)123); + CHECK_FORMAT_1("%05.7llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%05.7zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05.7zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05.7zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%05.7x", "000007b", (int)123); + + // Integers: precision = 0, arg = 0 (empty string in C) + CHECK_FORMAT_1("%.0d", "0", (int)0); + CHECK_FORMAT_1("%.0i", "0", (int)0); + CHECK_FORMAT_1("%.0u", "0", (unsigned int)0); + CHECK_FORMAT_1("%.0ld", "0", (long)0); + CHECK_FORMAT_1("%.0li", "0", (long)0); + CHECK_FORMAT_1("%.0lu", "0", (unsigned long)0); + CHECK_FORMAT_1("%.0lld", "0", (long long)0); + CHECK_FORMAT_1("%.0lli", "0", (long long)0); + CHECK_FORMAT_1("%.0llu", "0", (unsigned long long)0); + CHECK_FORMAT_1("%.0zd", "0", (Py_ssize_t)0); + CHECK_FORMAT_1("%.0zi", "0", (Py_ssize_t)0); + CHECK_FORMAT_1("%.0zu", "0", (size_t)0); + CHECK_FORMAT_1("%.0x", "0", (int)0); + + // Strings + CHECK_FORMAT_1("%s", "None", "None"); + CHECK_FORMAT_1("%U", "None", unicode); + CHECK_FORMAT_1("%A", "None", Py_None); + CHECK_FORMAT_1("%S", "None", Py_None); + CHECK_FORMAT_1("%R", "None", Py_None); + CHECK_FORMAT_2("%V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%V", "None", NULL, "None"); + + // Strings: width < length + CHECK_FORMAT_1("%1s", "None", "None"); + CHECK_FORMAT_1("%1U", "None", unicode); + CHECK_FORMAT_1("%1A", "None", Py_None); + CHECK_FORMAT_1("%1S", "None", Py_None); + CHECK_FORMAT_1("%1R", "None", Py_None); + CHECK_FORMAT_2("%1V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%1V", "None", NULL, "None"); + + // Strings: width > length + CHECK_FORMAT_1("%5s", " None", "None"); + CHECK_FORMAT_1("%5U", " None", unicode); + CHECK_FORMAT_1("%5A", " None", Py_None); + CHECK_FORMAT_1("%5S", " None", Py_None); + CHECK_FORMAT_1("%5R", " None", Py_None); + CHECK_FORMAT_2("%5V", " None", unicode, "ignored"); + CHECK_FORMAT_2("%5V", " None", NULL, "None"); + + // Strings: precision < length + CHECK_FORMAT_1("%.1s", "N", "None"); + CHECK_FORMAT_1("%.1U", "N", unicode); + CHECK_FORMAT_1("%.1A", "N", Py_None); + CHECK_FORMAT_1("%.1S", "N", Py_None); + CHECK_FORMAT_1("%.1R", "N", Py_None); + CHECK_FORMAT_2("%.1V", "N", unicode, "ignored"); + CHECK_FORMAT_2("%.1V", "N", NULL, "None"); + + // Strings: precision > length + CHECK_FORMAT_1("%.5s", "None", "None"); + CHECK_FORMAT_1("%.5U", "None", unicode); + CHECK_FORMAT_1("%.5A", "None", Py_None); + CHECK_FORMAT_1("%.5S", "None", Py_None); + CHECK_FORMAT_1("%.5R", "None", Py_None); + CHECK_FORMAT_2("%.5V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%.5V", "None", NULL, "None"); + + // Strings: precision < length, width > length + CHECK_FORMAT_1("%5.1s", " N", "None"); + CHECK_FORMAT_1("%5.1U", " N", unicode); + CHECK_FORMAT_1("%5.1A", " N", Py_None); + CHECK_FORMAT_1("%5.1S", " N", Py_None); + CHECK_FORMAT_1("%5.1R", " N", Py_None); + CHECK_FORMAT_2("%5.1V", " N", unicode, "ignored"); + CHECK_FORMAT_2("%5.1V", " N", NULL, "None"); + + // Strings: width < length, precision > length + CHECK_FORMAT_1("%1.5s", "None", "None"); + CHECK_FORMAT_1("%1.5U", "None", unicode); + CHECK_FORMAT_1("%1.5A", "None", Py_None); + CHECK_FORMAT_1("%1.5S", "None", Py_None); + CHECK_FORMAT_1("%1.5R", "None", Py_None); + CHECK_FORMAT_2("%1.5V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%1.5V", "None", NULL, "None"); + + Py_XDECREF(unicode); + Py_RETURN_NONE; + + Fail: + Py_XDECREF(result); + Py_XDECREF(unicode); + return NULL; + +#undef CHECK_FORMAT_2 +#undef CHECK_FORMAT_1 +#undef CHECK_FORMAT_0 +} + +static PyMethodDef TestMethods[] = { + {"codec_incrementalencoder", codec_incrementalencoder, METH_VARARGS}, + {"codec_incrementaldecoder", codec_incrementaldecoder, METH_VARARGS}, + {"test_unicode_compare_with_ascii", + test_unicode_compare_with_ascii, METH_NOARGS}, + {"test_string_from_format", test_string_from_format, METH_NOARGS}, + {"test_widechar", test_widechar, METH_NOARGS}, + {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, + {"unicode_aswidecharstring", unicode_aswidecharstring, METH_VARARGS}, + {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, + {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, + {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, + {"unicode_findchar", unicode_findchar, METH_VARARGS}, + {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Unicode(PyObject *m) { + _testcapimodule = PyModule_GetDef(m); + + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8004fa18bcc5..91bdeb8b6464 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1886,234 +1886,6 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) return return_value; } -static PyObject * -test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ -#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) - const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; - size_t wtextlen = 1; - const wchar_t invalid[1] = {(wchar_t)0x110000u}; -#else - const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; - size_t wtextlen = 2; -#endif - PyObject *wide, *utf8; - - wide = PyUnicode_FromWideChar(wtext, wtextlen); - if (wide == NULL) - return NULL; - - utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); - if (utf8 == NULL) { - Py_DECREF(wide); - return NULL; - } - - if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { - Py_DECREF(wide); - Py_DECREF(utf8); - return raiseTestError("test_widechar", - "wide string and utf8 string " - "have different length"); - } - if (PyUnicode_Compare(wide, utf8)) { - Py_DECREF(wide); - Py_DECREF(utf8); - if (PyErr_Occurred()) - return NULL; - return raiseTestError("test_widechar", - "wide string and utf8 string " - "are different"); - } - - Py_DECREF(wide); - Py_DECREF(utf8); - -#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) - wide = PyUnicode_FromWideChar(invalid, 1); - if (wide == NULL) - PyErr_Clear(); - else - return raiseTestError("test_widechar", - "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); -#endif - Py_RETURN_NONE; -} - -static PyObject * -unicode_aswidechar(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - Py_ssize_t buflen, size; - wchar_t *buffer; - - if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) - return NULL; - buffer = PyMem_New(wchar_t, buflen); - if (buffer == NULL) - return PyErr_NoMemory(); - - size = PyUnicode_AsWideChar(unicode, buffer, buflen); - if (size == -1) { - PyMem_Free(buffer); - return NULL; - } - - if (size < buflen) - buflen = size + 1; - else - buflen = size; - result = PyUnicode_FromWideChar(buffer, buflen); - PyMem_Free(buffer); - if (result == NULL) - return NULL; - - return Py_BuildValue("(Nn)", result, size); -} - -static PyObject * -unicode_aswidecharstring(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - Py_ssize_t size; - wchar_t *buffer; - - if (!PyArg_ParseTuple(args, "U", &unicode)) - return NULL; - - buffer = PyUnicode_AsWideCharString(unicode, &size); - if (buffer == NULL) - return NULL; - - result = PyUnicode_FromWideChar(buffer, size + 1); - PyMem_Free(buffer); - if (result == NULL) - return NULL; - return Py_BuildValue("(Nn)", result, size); -} - -static PyObject * -unicode_asucs4(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - Py_UCS4 *buffer; - int copy_null; - Py_ssize_t str_len, buf_len; - - if (!PyArg_ParseTuple(args, "Unp:unicode_asucs4", &unicode, &str_len, ©_null)) { - return NULL; - } - - buf_len = str_len + 1; - buffer = PyMem_NEW(Py_UCS4, buf_len); - if (buffer == NULL) { - return PyErr_NoMemory(); - } - memset(buffer, 0, sizeof(Py_UCS4)*buf_len); - buffer[str_len] = 0xffffU; - - if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { - PyMem_Free(buffer); - return NULL; - } - - result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); - PyMem_Free(buffer); - return result; -} - -static PyObject * -unicode_asutf8(PyObject *self, PyObject *args) -{ - PyObject *unicode; - const char *buffer; - - if (!PyArg_ParseTuple(args, "U", &unicode)) { - return NULL; - } - - buffer = PyUnicode_AsUTF8(unicode); - if (buffer == NULL) { - return NULL; - } - - return PyBytes_FromString(buffer); -} - -static PyObject * -unicode_asutf8andsize(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - const char *buffer; - Py_ssize_t utf8_len; - - if(!PyArg_ParseTuple(args, "U", &unicode)) { - return NULL; - } - - buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); - if (buffer == NULL) { - return NULL; - } - - result = PyBytes_FromString(buffer); - if (result == NULL) { - return NULL; - } - - return Py_BuildValue("(Nn)", result, utf8_len); -} - -static PyObject * -unicode_findchar(PyObject *self, PyObject *args) -{ - PyObject *str; - int direction; - unsigned int ch; - Py_ssize_t result; - Py_ssize_t start, end; - - if (!PyArg_ParseTuple(args, "UInni:unicode_findchar", &str, &ch, - &start, &end, &direction)) { - return NULL; - } - - result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); - if (result == -2) - return NULL; - else - return PyLong_FromSsize_t(result); -} - -static PyObject * -unicode_copycharacters(PyObject *self, PyObject *args) -{ - PyObject *from, *to, *to_copy; - Py_ssize_t from_start, to_start, how_many, copied; - - if (!PyArg_ParseTuple(args, "UnOnn:unicode_copycharacters", &to, &to_start, - &from, &from_start, &how_many)) { - return NULL; - } - - if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), - PyUnicode_MAX_CHAR_VALUE(to)))) { - return NULL; - } - if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { - Py_DECREF(to_copy); - return NULL; - } - - if ((copied = PyUnicode_CopyCharacters(to_copy, to_start, from, - from_start, how_many)) < 0) { - Py_DECREF(to_copy); - return NULL; - } - - return Py_BuildValue("(Nn)", to_copy, copied); -} - static PyObject * getargs_w_star(PyObject *self, PyObject *args) { @@ -2164,27 +1936,6 @@ test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) } } -static PyObject * -codec_incrementalencoder(PyObject *self, PyObject *args) -{ - const char *encoding, *errors = NULL; - if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", - &encoding, &errors)) - return NULL; - return PyCodec_IncrementalEncoder(encoding, errors); -} - -static PyObject * -codec_incrementaldecoder(PyObject *self, PyObject *args) -{ - const char *encoding, *errors = NULL; - if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", - &encoding, &errors)) - return NULL; - return PyCodec_IncrementalDecoder(encoding, errors); -} - - /* Simple test of _PyLong_NumBits and _PyLong_Sign. */ static PyObject * test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) @@ -2847,63 +2598,6 @@ pending_threadfunc(PyObject *self, PyObject *arg) Py_RETURN_TRUE; } -/* Some tests of PyUnicode_FromFormat(). This needs more tests. */ -static PyObject * -test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *result; - char *msg; - -#define CHECK_1_FORMAT(FORMAT, TYPE) \ - result = PyUnicode_FromFormat(FORMAT, (TYPE)1); \ - if (result == NULL) \ - return NULL; \ - if (!_PyUnicode_EqualToASCIIString(result, "1")) { \ - msg = FORMAT " failed at 1"; \ - goto Fail; \ - } \ - Py_DECREF(result) - - CHECK_1_FORMAT("%d", int); - CHECK_1_FORMAT("%ld", long); - /* The z width modifier was added in Python 2.5. */ - CHECK_1_FORMAT("%zd", Py_ssize_t); - - /* The u type code was added in Python 2.5. */ - CHECK_1_FORMAT("%u", unsigned int); - CHECK_1_FORMAT("%lu", unsigned long); - CHECK_1_FORMAT("%zu", size_t); - - /* "%lld" and "%llu" support added in Python 2.7. */ - CHECK_1_FORMAT("%llu", unsigned long long); - CHECK_1_FORMAT("%lld", long long); - - Py_RETURN_NONE; - - Fail: - Py_XDECREF(result); - return raiseTestError("test_string_from_format", msg); - -#undef CHECK_1_FORMAT -} - - -static PyObject * -test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); - int result; - if (py_s == NULL) - return NULL; - result = PyUnicode_CompareWithASCIIString(py_s, "str"); - Py_DECREF(py_s); - if (!result) { - PyErr_SetString(TestError, "Python string ending in NULL " - "should not compare equal to c string."); - return NULL; - } - Py_RETURN_NONE; -} - /* This is here to provide a docstring for test_descr. */ static PyObject * test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) @@ -5823,12 +5517,9 @@ static PyMethodDef TestMethods[] = { {"pyobject_repr_from_null", pyobject_repr_from_null, METH_NOARGS}, {"pyobject_str_from_null", pyobject_str_from_null, METH_NOARGS}, {"pyobject_bytes_from_null", pyobject_bytes_from_null, METH_NOARGS}, - {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, {"test_with_docstring", test_with_docstring, METH_NOARGS, PyDoc_STR("This is a pretty normal docstring.")}, {"test_string_to_double", test_string_to_double, METH_NOARGS}, - {"test_unicode_compare_with_ascii", test_unicode_compare_with_ascii, - METH_NOARGS}, {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) @@ -5897,19 +5588,7 @@ static PyMethodDef TestMethods[] = { {"getargs_et", getargs_et, METH_VARARGS}, {"getargs_es_hash", getargs_es_hash, METH_VARARGS}, {"getargs_et_hash", getargs_et_hash, METH_VARARGS}, - {"codec_incrementalencoder", - (PyCFunction)codec_incrementalencoder, METH_VARARGS}, - {"codec_incrementaldecoder", - (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, {"test_s_code", test_s_code, METH_NOARGS}, - {"test_widechar", test_widechar, METH_NOARGS}, - {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, - {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, - {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, - {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, - {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, - {"unicode_findchar", unicode_findchar, METH_VARARGS}, - {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, {"_test_thread_state", test_thread_state, METH_VARARGS}, {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, #ifdef HAVE_GETTIMEOFDAY @@ -6871,6 +6550,9 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Heaptype(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Unicode(m) < 0) { + return NULL; + } PyState_AddModule(m, &_testcapimodule); return m; diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index 0cb4e44cf734..23bb5ec85274 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -97,6 +97,7 @@ <ClCompile Include="..\Modules\_testcapi\vectorcall.c" /> <ClCompile Include="..\Modules\_testcapi\vectorcall_limited.c" /> <ClCompile Include="..\Modules\_testcapi\heaptype.c" /> + <ClCompile Include="..\Modules\_testcapi\unicode.c" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\PC\python_nt.rc" /> diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index 4da972f279c8..fc2c4345fe14 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -21,6 +21,9 @@ <ClCompile Include="..\Modules\_testcapi\heaptype.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\Modules\_testcapi\unicode.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\PC\python_nt.rc"> From webhook-mailer at python.org Wed Aug 10 05:53:52 2022 From: webhook-mailer at python.org (encukou) Date: Wed, 10 Aug 2022 09:53:52 -0000 Subject: [Python-checkins] gh-93649: Undefine NDEBUG in Modules/_testcapi/* to enable assert() (GH-95793) Message-ID: <mailman.594.1660125234.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5a97a93be086c19343df4352672bfda32f6cbd0c commit: 5a97a93be086c19343df4352672bfda32f6cbd0c branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-10T11:53:10+02:00 summary: gh-93649: Undefine NDEBUG in Modules/_testcapi/* to enable assert() (GH-95793) files: M Modules/_testcapi/parts.h diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index c0e0f3aa1cc..a76ddd93c0e 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -1,5 +1,8 @@ #include "Python.h" +/* Always enable assertions */ +#undef NDEBUG + int _PyTestCapi_Init_Vectorcall(PyObject *module); int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_Heaptype(PyObject *module); From webhook-mailer at python.org Wed Aug 10 06:50:32 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 10 Aug 2022 10:50:32 -0000 Subject: [Python-checkins] [docs] Mention RESUME opcode in whatsnew/3.11.rst (#95595) Message-ID: <mailman.595.1660128633.3313.python-checkins@python.org> https://github.com/python/cpython/commit/cf28540fd361eaca7b457e3fa43d62fd97a94d17 commit: cf28540fd361eaca7b457e3fa43d62fd97a94d17 branch: main author: esc <esc at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-10T12:50:21+02:00 summary: [docs] Mention RESUME opcode in whatsnew/3.11.rst (#95595) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 39f1dab590a9..7e1130e8ea30 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1208,6 +1208,8 @@ CPython bytecode changes * :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP` are now relative rather than absolute. +* :opcode:`RESUME` has been added. It is a no-op. Performs internal tracing, + debugging and optimization checks. Deprecated ========== From webhook-mailer at python.org Wed Aug 10 06:55:08 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 10 Aug 2022 10:55:08 -0000 Subject: [Python-checkins] [docs] Fix typo for functools.cmp_to_key (GH-95766) Message-ID: <mailman.596.1660128909.3313.python-checkins@python.org> https://github.com/python/cpython/commit/25d0a81e620538ecad5f67a0b71f7961b45c0ad8 commit: 25d0a81e620538ecad5f67a0b71f7961b45c0ad8 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-10T12:54:57+02:00 summary: [docs] Fix typo for functools.cmp_to_key (GH-95766) (cherry picked from commit f83b0cabeb101599e6b55e6a1c972d5b8cae18b2) Co-authored-by: Andrzej Bartosi?ski <6197476+Neob91 at users.noreply.github.com> files: M Doc/library/functools.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index dd4d76ef670..00aca09bc7a 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -119,7 +119,7 @@ The :mod:`functools` module defines the following functions: tool for programs being converted from Python 2 which supported the use of comparison functions. - A comparison function is any callable that accept two arguments, compares them, + A comparison function is any callable that accepts two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one argument and returns another value to be used as the sort key. From webhook-mailer at python.org Wed Aug 10 06:55:54 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 10 Aug 2022 10:55:54 -0000 Subject: [Python-checkins] gh-91838: Resolve more HTTP links which redirect to HTTPS (GH-95650) (GH-95780) Message-ID: <mailman.597.1660128956.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a42215c7e1e5a209b1bfb4cd02b52c7c1999f5cf commit: a42215c7e1e5a209b1bfb4cd02b52c7c1999f5cf branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-10T12:55:50+02:00 summary: gh-91838: Resolve more HTTP links which redirect to HTTPS (GH-95650) (GH-95780) (cherry picked from commit cc9160a29bc3356ced92348bcd8e6668c67167c9) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M Doc/whatsnew/2.5.rst M Lib/posixpath.py M Lib/test/test_descrtut.py M Tools/c-analyzer/c_parser/parser/__init__.py diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index ea785121db90..6c216826fee0 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -2019,7 +2019,7 @@ https://www.sqlite.org. .. seealso:: - http://www.pysqlite.org + https://www.pysqlite.org The pysqlite web page. https://www.sqlite.org diff --git a/Lib/posixpath.py b/Lib/posixpath.py index a7b2f2d64824..5e1ebe3293d8 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -364,7 +364,7 @@ def normpath(path): initial_slashes = path.startswith(sep) # POSIX allows one or two initial slashes, but treats three or more # as single slash. - # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) + # (see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) if (initial_slashes and path.startswith(sep*2) and not path.startswith(sep*3)): initial_slashes = 2 diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py index e01a31a74695..9aefda3d521b 100644 --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -1,7 +1,7 @@ # This contains most of the executable examples from Guido's descr # tutorial, once at # -# http://www.python.org/2.2/descrintro.html +# https://www.python.org/download/releases/2.2.3/descrintro/ # # A few examples left implicit in the writeup were fleshed out, a few were # skipped due to lack of interest (e.g., faking super() by hand isn't diff --git a/Tools/c-analyzer/c_parser/parser/__init__.py b/Tools/c-analyzer/c_parser/parser/__init__.py index b5eae2ed92d0..4c121adb5168 100644 --- a/Tools/c-analyzer/c_parser/parser/__init__.py +++ b/Tools/c-analyzer/c_parser/parser/__init__.py @@ -12,7 +12,7 @@ * ... -(see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) +(see: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) We have taken advantage of the elements of the C grammar that are used only in a few limited contexts, mostly as delimiters. They allow us to From webhook-mailer at python.org Wed Aug 10 06:57:37 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 10 Aug 2022 10:57:37 -0000 Subject: [Python-checkins] gh-95349: Hide a Distutils Warning Filter for test_check_c_globals (GH-95837) (GH-95843) Message-ID: <mailman.598.1660129059.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2c4bd21630b6de45a211e3a8c0aea38abe4c58f2 commit: 2c4bd21630b6de45a211e3a8c0aea38abe4c58f2 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-10T12:57:32+02:00 summary: gh-95349: Hide a Distutils Warning Filter for test_check_c_globals (GH-95837) (GH-95843) Under certain build conditions, test_check_c_globals fails. This fix takes the same approach as we took for gh-84236 (via gh-20095). We'll be removing use of distutils in the c-analyzer at some point. Until then we'll hide the warning filter. (cherry picked from commit 3ff6d9affb351292ad8530802e7c06f651520706) Co-authored-by: Eric Snow <ericsnowcurrently at gmail.com> files: M Lib/test/test_check_c_globals.py diff --git a/Lib/test/test_check_c_globals.py b/Lib/test/test_check_c_globals.py index 030debc452e..898807a5e69 100644 --- a/Lib/test/test_check_c_globals.py +++ b/Lib/test/test_check_c_globals.py @@ -1,9 +1,14 @@ import unittest import test.test_tools +from test.support.warnings_helper import save_restore_warnings_filters test.test_tools.skip_if_missing('c-analyzer') with test.test_tools.imports_under_tool('c-analyzer'): - from cpython.__main__ import main + # gh-95349: Save/restore warnings filters to leave them unchanged. + # Importing the c-analyzer imports docutils which imports pkg_resources + # which adds a warnings filter. + with save_restore_warnings_filters(): + from cpython.__main__ import main class ActualChecks(unittest.TestCase): From webhook-mailer at python.org Wed Aug 10 07:01:33 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 10 Aug 2022 11:01:33 -0000 Subject: [Python-checkins] [docs] Mention RESUME opcode in whatsnew/3.11.rst (GH-95595) (GH-95851) Message-ID: <mailman.599.1660129295.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5c829436d201fc166683d5afa9669f1bdee609dd commit: 5c829436d201fc166683d5afa9669f1bdee609dd branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-10T13:01:19+02:00 summary: [docs] Mention RESUME opcode in whatsnew/3.11.rst (GH-95595) (GH-95851) (cherry picked from commit cf28540fd361eaca7b457e3fa43d62fd97a94d17) Co-authored-by: esc <esc at users.noreply.github.com> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index a36564a8ab1..f25bc549bf5 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1208,6 +1208,8 @@ CPython bytecode changes * :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP` are now relative rather than absolute. +* :opcode:`RESUME` has been added. It is a no-op. Performs internal tracing, + debugging and optimization checks. Deprecated ========== From webhook-mailer at python.org Wed Aug 10 07:13:12 2022 From: webhook-mailer at python.org (encukou) Date: Wed, 10 Aug 2022 11:13:12 -0000 Subject: [Python-checkins] gh-95504: Fix negative numbers in PyUnicode_FromFormat (GH-95848) Message-ID: <mailman.600.1660129992.3313.python-checkins@python.org> https://github.com/python/cpython/commit/71c3d649b5a0324c6eb01f9ad025c1e102b82bba commit: 71c3d649b5a0324c6eb01f9ad025c1e102b82bba branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-10T13:12:40+02:00 summary: gh-95504: Fix negative numbers in PyUnicode_FromFormat (GH-95848) Co-authored-by: philg314 <110174000+philg314 at users.noreply.github.com> files: A Misc/NEWS.d/next/C API/2022-07-31-21-58-27.gh-issue-95504.wy7B1F.rst M Doc/whatsnew/3.12.rst M Misc/ACKS M Modules/_testcapi/unicode.c M Objects/unicodeobject.c diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 6df122acba71..acf59616b2fe 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -475,6 +475,9 @@ Porting to Python 3.12 copied as-is to the result string, and any extra arguments discarded. (Contributed by Serhiy Storchaka in :gh:`95781`.) +* Fixed wrong sign placement in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV`. + (Contributed by Philip Georgi in :gh:`95504`.) Deprecated ---------- diff --git a/Misc/ACKS b/Misc/ACKS index 7065267379de..28b4ce42e907 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -608,8 +608,8 @@ Marius Gedminas Jan-Philip Gehrcke Thomas Gellekum Gabriel Genellina -Christos Georgiou Philip Georgi +Christos Georgiou Elazar (?????) Gershuni Ben Gertzfield Nadim Ghaznavi diff --git a/Misc/NEWS.d/next/C API/2022-07-31-21-58-27.gh-issue-95504.wy7B1F.rst b/Misc/NEWS.d/next/C API/2022-07-31-21-58-27.gh-issue-95504.wy7B1F.rst new file mode 100644 index 000000000000..955bdd4c7494 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-07-31-21-58-27.gh-issue-95504.wy7B1F.rst @@ -0,0 +1,3 @@ +Fix sign placement when specifying width or precision in +:c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. +Patch by Philip Georgi. diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c index 58214249e225..d0f1e2abdc82 100644 --- a/Modules/_testcapi/unicode.c +++ b/Modules/_testcapi/unicode.c @@ -433,6 +433,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) CHECK_FORMAT_1("%05zu", "00123", (size_t)123); CHECK_FORMAT_1("%05x", "0007b", (int)123); + CHECK_FORMAT_1("%05d", "-0123", (int)-123); + CHECK_FORMAT_1("%05i", "-0123", (int)-123); + CHECK_FORMAT_1("%05ld", "-0123", (long)-123); + CHECK_FORMAT_1("%05li", "-0123", (long)-123); + CHECK_FORMAT_1("%05lld", "-0123", (long long)-123); + CHECK_FORMAT_1("%05lli", "-0123", (long long)-123); + CHECK_FORMAT_1("%05zd", "-0123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%05zi", "-0123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%09x", "0ffffff85", (int)-123); + // Integers: precision < length CHECK_FORMAT_1("%.1d", "123", (int)123); CHECK_FORMAT_1("%.1i", "123", (int)123); @@ -473,6 +483,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) CHECK_FORMAT_1("%.5zu", "00123", (size_t)123); CHECK_FORMAT_1("%.5x", "0007b", (int)123); + CHECK_FORMAT_1("%.5d", "-00123", (int)-123); + CHECK_FORMAT_1("%.5i", "-00123", (int)-123); + CHECK_FORMAT_1("%.5ld", "-00123", (long)-123); + CHECK_FORMAT_1("%.5li", "-00123", (long)-123); + CHECK_FORMAT_1("%.5lld", "-00123", (long long)-123); + CHECK_FORMAT_1("%.5lli", "-00123", (long long)-123); + CHECK_FORMAT_1("%.5zd", "-00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.5zi", "-00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.9x", "0ffffff85", (int)-123); + // Integers: width > precision > length CHECK_FORMAT_1("%7.5d", " 00123", (int)123); CHECK_FORMAT_1("%7.5i", " 00123", (int)123); @@ -488,6 +508,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) CHECK_FORMAT_1("%7.5zu", " 00123", (size_t)123); CHECK_FORMAT_1("%7.5x", " 0007b", (int)123); + CHECK_FORMAT_1("%7.5d", " -00123", (int)-123); + CHECK_FORMAT_1("%7.5i", " -00123", (int)-123); + CHECK_FORMAT_1("%7.5ld", " -00123", (long)-123); + CHECK_FORMAT_1("%7.5li", " -00123", (long)-123); + CHECK_FORMAT_1("%7.5lld", " -00123", (long long)-123); + CHECK_FORMAT_1("%7.5lli", " -00123", (long long)-123); + CHECK_FORMAT_1("%7.5zd", " -00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%7.5zi", " -00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%10.9x", " 0ffffff85", (int)-123); + // Integers: width > precision > length, 0-flag CHECK_FORMAT_1("%07.5d", "0000123", (int)123); CHECK_FORMAT_1("%07.5i", "0000123", (int)123); @@ -503,6 +533,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) CHECK_FORMAT_1("%07.5zu", "0000123", (size_t)123); CHECK_FORMAT_1("%07.5x", "000007b", (int)123); + CHECK_FORMAT_1("%07.5d", "-000123", (int)-123); + CHECK_FORMAT_1("%07.5i", "-000123", (int)-123); + CHECK_FORMAT_1("%07.5ld", "-000123", (long)-123); + CHECK_FORMAT_1("%07.5li", "-000123", (long)-123); + CHECK_FORMAT_1("%07.5lld", "-000123", (long long)-123); + CHECK_FORMAT_1("%07.5lli", "-000123", (long long)-123); + CHECK_FORMAT_1("%07.5zd", "-000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%07.5zi", "-000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%010.9x", "00ffffff85", (int)-123); + // Integers: precision > width > length CHECK_FORMAT_1("%5.7d", "0000123", (int)123); CHECK_FORMAT_1("%5.7i", "0000123", (int)123); @@ -518,6 +558,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) CHECK_FORMAT_1("%5.7zu", "0000123", (size_t)123); CHECK_FORMAT_1("%5.7x", "000007b", (int)123); + CHECK_FORMAT_1("%5.7d", "-0000123", (int)-123); + CHECK_FORMAT_1("%5.7i", "-0000123", (int)-123); + CHECK_FORMAT_1("%5.7ld", "-0000123", (long)-123); + CHECK_FORMAT_1("%5.7li", "-0000123", (long)-123); + CHECK_FORMAT_1("%5.7lld", "-0000123", (long long)-123); + CHECK_FORMAT_1("%5.7lli", "-0000123", (long long)-123); + CHECK_FORMAT_1("%5.7zd", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%5.7zi", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%9.10x", "00ffffff85", (int)-123); + // Integers: precision > width > length, 0-flag CHECK_FORMAT_1("%05.7d", "0000123", (int)123); CHECK_FORMAT_1("%05.7i", "0000123", (int)123); @@ -533,6 +583,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) CHECK_FORMAT_1("%05.7zu", "0000123", (size_t)123); CHECK_FORMAT_1("%05.7x", "000007b", (int)123); + CHECK_FORMAT_1("%05.7d", "-0000123", (int)-123); + CHECK_FORMAT_1("%05.7i", "-0000123", (int)-123); + CHECK_FORMAT_1("%05.7ld", "-0000123", (long)-123); + CHECK_FORMAT_1("%05.7li", "-0000123", (long)-123); + CHECK_FORMAT_1("%05.7lld", "-0000123", (long long)-123); + CHECK_FORMAT_1("%05.7lli", "-0000123", (long long)-123); + CHECK_FORMAT_1("%05.7zd", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%05.7zi", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%09.10x", "00ffffff85", (int)-123); + // Integers: precision = 0, arg = 0 (empty string in C) CHECK_FORMAT_1("%.0d", "0", (int)0); CHECK_FORMAT_1("%.0i", "0", (int)0); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 184a2bfd5dd8..b1d14a32f70f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2481,21 +2481,34 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, } assert(len >= 0); - if (precision < len) - precision = len; + int negative = (buffer[0] == '-'); + len -= negative; + + precision = Py_MAX(precision, len); + width = Py_MAX(width, precision + negative); arglen = Py_MAX(precision, width); if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1) return NULL; if (width > precision) { - Py_UCS4 fillchar; - fill = width - precision; - fillchar = zeropad?'0':' '; + if (negative && zeropad) { + if (_PyUnicodeWriter_WriteChar(writer, '-') == -1) + return NULL; + } + + Py_UCS4 fillchar = zeropad?'0':' '; + fill = width - precision - negative; if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1) return NULL; writer->pos += fill; + + if (negative && !zeropad) { + if (_PyUnicodeWriter_WriteChar(writer, '-') == -1) + return NULL; + } } + if (precision > len) { fill = precision - len; if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1) @@ -2503,7 +2516,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, writer->pos += fill; } - if (_PyUnicodeWriter_WriteASCIIString(writer, buffer, len) < 0) + if (_PyUnicodeWriter_WriteASCIIString(writer, &buffer[negative], len) < 0) return NULL; break; } From webhook-mailer at python.org Wed Aug 10 13:09:14 2022 From: webhook-mailer at python.org (vsajip) Date: Wed, 10 Aug 2022 17:09:14 -0000 Subject: [Python-checkins] gh-95804: Respect MemoryHandler.flushOnClose in logging shutdown. (GH-95857) Message-ID: <mailman.601.1660151355.3313.python-checkins@python.org> https://github.com/python/cpython/commit/37c0f9ccc06750a7e22f5c176df39373f7aca526 commit: 37c0f9ccc06750a7e22f5c176df39373f7aca526 branch: main author: David Bonner <dbonner at gmail.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-10T18:08:55+01:00 summary: gh-95804: Respect MemoryHandler.flushOnClose in logging shutdown. (GH-95857) files: A Misc/NEWS.d/next/Library/2022-08-10-11-54-04.gh-issue-95804.i5FCFK.rst M Lib/logging/__init__.py M Lib/test/test_logging.py M Misc/ACKS diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index dc28702f5004..afb5234a0772 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -2245,7 +2245,11 @@ def shutdown(handlerList=_handlerList): if h: try: h.acquire() - h.flush() + # MemoryHandlers might not want to be flushed on close, + # but circular imports prevent us scoping this to just + # those handlers. hence the default to True. + if getattr(h, 'flushOnClose', True): + h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index a505e8000daa..99ea2f687551 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1225,6 +1225,35 @@ def test_flush_on_close(self): # assert that no new lines have been added self.assert_log_lines(lines) # no change + def test_shutdown_flush_on_close(self): + """ + Test that the flush-on-close configuration is respected by the + shutdown method. + """ + self.mem_logger.debug(self.next_message()) + self.assert_log_lines([]) + self.mem_logger.info(self.next_message()) + self.assert_log_lines([]) + # Default behaviour is to flush on close. Check that it happens. + logging.shutdown(handlerList=[logging.weakref.ref(self.mem_hdlr)]) + lines = [ + ('DEBUG', '1'), + ('INFO', '2'), + ] + self.assert_log_lines(lines) + # Now configure for flushing not to be done on close. + self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING, + self.root_hdlr, + False) + self.mem_logger.addHandler(self.mem_hdlr) + self.mem_logger.debug(self.next_message()) + self.assert_log_lines(lines) # no change + self.mem_logger.info(self.next_message()) + self.assert_log_lines(lines) # no change + # assert that no new lines have been added after shutdown + logging.shutdown(handlerList=[logging.weakref.ref(self.mem_hdlr)]) + self.assert_log_lines(lines) # no change + @threading_helper.requires_working_threading() def test_race_between_set_target_and_flush(self): class MockRaceConditionHandler: diff --git a/Misc/ACKS b/Misc/ACKS index 28b4ce42e907..c1f570acaaf8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -198,6 +198,7 @@ Gawain Bolton Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond +David Bonner Angelin Booz M?d?ric Boquien Matias Bordese diff --git a/Misc/NEWS.d/next/Library/2022-08-10-11-54-04.gh-issue-95804.i5FCFK.rst b/Misc/NEWS.d/next/Library/2022-08-10-11-54-04.gh-issue-95804.i5FCFK.rst new file mode 100644 index 000000000000..46434cb46604 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-10-11-54-04.gh-issue-95804.i5FCFK.rst @@ -0,0 +1,2 @@ +Fix ``logging`` shutdown handler so it respects +``MemoryHandler.flushOnClose``. From webhook-mailer at python.org Wed Aug 10 14:26:02 2022 From: webhook-mailer at python.org (mdickinson) Date: Wed, 10 Aug 2022 18:26:02 -0000 Subject: [Python-checkins] gh-95605: Fix `float(s)` error message when `s` contains only whitespace (GH-95665) Message-ID: <mailman.602.1660155963.3313.python-checkins@python.org> https://github.com/python/cpython/commit/97e9cfa75a80b54a0630b7371f35e368a12749d1 commit: 97e9cfa75a80b54a0630b7371f35e368a12749d1 branch: main author: Mark Dickinson <dickinsm at gmail.com> committer: mdickinson <dickinsm at gmail.com> date: 2022-08-10T19:25:39+01:00 summary: gh-95605: Fix `float(s)` error message when `s` contains only whitespace (GH-95665) This PR fixes the error message from float(s) in the case where s contains only whitespace. files: A Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst M Lib/test/test_float.py M Objects/floatobject.c diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index b5e271abc86a..f8350c1e4caa 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -137,6 +137,10 @@ def check(s): check('123\xbd') check(' 123 456 ') check(b' 123 456 ') + # all whitespace (cf. https://github.com/python/cpython/issues/95605) + check('') + check(' ') + check('\t \n') # non-ascii digits (error came from non-digit '!') check('\u0663\u0661\u0664!') diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst new file mode 100644 index 000000000000..49441c6b3118 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst @@ -0,0 +1,2 @@ +Fix misleading contents of error message when converting an all-whitespace +string to :class:`float`. diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 4b1b24f2e702..c4353572d32d 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -162,11 +162,18 @@ float_from_string_inner(const char *s, Py_ssize_t len, void *obj) double x; const char *end; const char *last = s + len; - /* strip space */ + /* strip leading whitespace */ while (s < last && Py_ISSPACE(*s)) { s++; } + if (s == last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", obj); + return NULL; + } + /* strip trailing whitespace */ while (s < last - 1 && Py_ISSPACE(last[-1])) { last--; } From webhook-mailer at python.org Wed Aug 10 14:58:06 2022 From: webhook-mailer at python.org (mdickinson) Date: Wed, 10 Aug 2022 18:58:06 -0000 Subject: [Python-checkins] gh-95605: Fix `float(s)` error message when `s` contains only whitespace (GH-95665) (GH-95859) Message-ID: <mailman.603.1660157887.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b4f968e0947c0c090c5cf7d8b9ed614f9050a0f4 commit: b4f968e0947c0c090c5cf7d8b9ed614f9050a0f4 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: mdickinson <dickinsm at gmail.com> date: 2022-08-10T19:57:55+01:00 summary: gh-95605: Fix `float(s)` error message when `s` contains only whitespace (GH-95665) (GH-95859) This PR fixes the error message from float(s) in the case where s contains only whitespace. (cherry picked from commit 97e9cfa75a80b54a0630b7371f35e368a12749d1) Co-authored-by: Mark Dickinson <dickinsm at gmail.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst M Lib/test/test_float.py M Objects/floatobject.c diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 29f775644dd4..4c4a8f9ba921 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -135,6 +135,10 @@ def check(s): check('123\xbd') check(' 123 456 ') check(b' 123 456 ') + # all whitespace (cf. https://github.com/python/cpython/issues/95605) + check('') + check(' ') + check('\t \n') # non-ascii digits (error came from non-digit '!') check('\u0663\u0661\u0664!') diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst new file mode 100644 index 000000000000..49441c6b3118 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst @@ -0,0 +1,2 @@ +Fix misleading contents of error message when converting an all-whitespace +string to :class:`float`. diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 5af267877311..064ba2ec29db 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -150,11 +150,18 @@ float_from_string_inner(const char *s, Py_ssize_t len, void *obj) double x; const char *end; const char *last = s + len; - /* strip space */ + /* strip leading whitespace */ while (s < last && Py_ISSPACE(*s)) { s++; } + if (s == last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", obj); + return NULL; + } + /* strip trailing whitespace */ while (s < last - 1 && Py_ISSPACE(last[-1])) { last--; } From webhook-mailer at python.org Wed Aug 10 19:48:09 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 10 Aug 2022 23:48:09 -0000 Subject: [Python-checkins] gh-95733: Allow installing Store package on older Windows versions (GH-95862) Message-ID: <mailman.604.1660175290.3313.python-checkins@python.org> https://github.com/python/cpython/commit/73d8ffefe95791fa1f036b029cf51f907a89ee42 commit: 73d8ffefe95791fa1f036b029cf51f907a89ee42 branch: main author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-11T00:47:58+01:00 summary: gh-95733: Allow installing Store package on older Windows versions (GH-95862) files: A Misc/NEWS.d/next/Windows/2022-08-10-22-46-48.gh-issue-95733.2_urOp.rst M PC/layout/support/appxmanifest.py diff --git a/Misc/NEWS.d/next/Windows/2022-08-10-22-46-48.gh-issue-95733.2_urOp.rst b/Misc/NEWS.d/next/Windows/2022-08-10-22-46-48.gh-issue-95733.2_urOp.rst new file mode 100644 index 000000000000..996209211690 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-08-10-22-46-48.gh-issue-95733.2_urOp.rst @@ -0,0 +1,2 @@ +Make certain requirements of the Windows Store package optional to allow +installing on earlier updates of Windows. diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index 4850fad9b56d..1fb03380278f 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -86,7 +86,8 @@ } APPXMANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?> -<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" +<Package IgnorableNamespaces="desktop4 desktop6" + xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:rescap4="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/4" From webhook-mailer at python.org Wed Aug 10 20:15:57 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 00:15:57 -0000 Subject: [Python-checkins] gh-95349: Hide a Distutils Warning Filter for test_check_c_globals (GH-95837) Message-ID: <mailman.605.1660176959.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b11895e3e7cbe13f5be0f6321f2690af664a247f commit: b11895e3e7cbe13f5be0f6321f2690af664a247f branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-10T17:15:53-07:00 summary: gh-95349: Hide a Distutils Warning Filter for test_check_c_globals (GH-95837) Under certain build conditions, test_check_c_globals fails. This fix takes the same approach as we took for gh-84236 (via gh-20095). We'll be removing use of distutils in the c-analyzer at some point. Until then we'll hide the warning filter. (cherry picked from commit 3ff6d9affb351292ad8530802e7c06f651520706) Co-authored-by: Eric Snow <ericsnowcurrently at gmail.com> files: M Lib/test/test_check_c_globals.py diff --git a/Lib/test/test_check_c_globals.py b/Lib/test/test_check_c_globals.py index 030debc452e..898807a5e69 100644 --- a/Lib/test/test_check_c_globals.py +++ b/Lib/test/test_check_c_globals.py @@ -1,9 +1,14 @@ import unittest import test.test_tools +from test.support.warnings_helper import save_restore_warnings_filters test.test_tools.skip_if_missing('c-analyzer') with test.test_tools.imports_under_tool('c-analyzer'): - from cpython.__main__ import main + # gh-95349: Save/restore warnings filters to leave them unchanged. + # Importing the c-analyzer imports docutils which imports pkg_resources + # which adds a warnings filter. + with save_restore_warnings_filters(): + from cpython.__main__ import main class ActualChecks(unittest.TestCase): From webhook-mailer at python.org Wed Aug 10 22:05:09 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 11 Aug 2022 02:05:09 -0000 Subject: [Python-checkins] gh-84910: Tweak IDLE Glossary entry (#95866) Message-ID: <mailman.606.1660183511.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3646f6cd880f8f91e189a2fe44a687798aa1fef1 commit: 3646f6cd880f8f91e189a2fe44a687798aa1fef1 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-10T22:04:36-04:00 summary: gh-84910: Tweak IDLE Glossary entry (#95866) Link "IDLE" to its doc and add 'and Learning' to its expansion, as in the doc. files: M Doc/glossary.rst diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 7950ec4e206..e0dd4fc9676 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -566,9 +566,9 @@ Glossary from their :func:`id`. IDLE - An Integrated Development Environment for Python. IDLE is a basic editor - and interpreter environment which ships with the standard distribution of - Python. + An Integrated Development and Learning Environment for Python. + :ref:`idle` is a basic editor and interpreter environment + which ships with the standard distribution of Python. immutable An object with a fixed value. Immutable objects include numbers, strings and From webhook-mailer at python.org Wed Aug 10 22:13:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 02:13:38 -0000 Subject: [Python-checkins] gh-84910: Tweak IDLE Glossary entry (GH-95866) Message-ID: <mailman.607.1660184020.3313.python-checkins@python.org> https://github.com/python/cpython/commit/599b6ffb0d05acc4858958189cfd9f8e3f7534b0 commit: 599b6ffb0d05acc4858958189cfd9f8e3f7534b0 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-10T19:13:33-07:00 summary: gh-84910: Tweak IDLE Glossary entry (GH-95866) Link "IDLE" to its doc and add 'and Learning' to its expansion, as in the doc. (cherry picked from commit 3646f6cd880f8f91e189a2fe44a687798aa1fef1) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/glossary.rst diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 7950ec4e206..e0dd4fc9676 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -566,9 +566,9 @@ Glossary from their :func:`id`. IDLE - An Integrated Development Environment for Python. IDLE is a basic editor - and interpreter environment which ships with the standard distribution of - Python. + An Integrated Development and Learning Environment for Python. + :ref:`idle` is a basic editor and interpreter environment + which ships with the standard distribution of Python. immutable An object with a fixed value. Immutable objects include numbers, strings and From webhook-mailer at python.org Wed Aug 10 22:15:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 02:15:08 -0000 Subject: [Python-checkins] gh-84910: Tweak IDLE Glossary entry (GH-95866) Message-ID: <mailman.608.1660184109.3313.python-checkins@python.org> https://github.com/python/cpython/commit/fe5cc63cd7cf19ba3bcced9f76d6fd2bfd85cba8 commit: fe5cc63cd7cf19ba3bcced9f76d6fd2bfd85cba8 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-10T19:15:03-07:00 summary: gh-84910: Tweak IDLE Glossary entry (GH-95866) Link "IDLE" to its doc and add 'and Learning' to its expansion, as in the doc. (cherry picked from commit 3646f6cd880f8f91e189a2fe44a687798aa1fef1) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/glossary.rst diff --git a/Doc/glossary.rst b/Doc/glossary.rst index af6ed714b8c..24daf19f652 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -576,9 +576,9 @@ Glossary from their :func:`id`. IDLE - An Integrated Development Environment for Python. IDLE is a basic editor - and interpreter environment which ships with the standard distribution of - Python. + An Integrated Development and Learning Environment for Python. + :ref:`idle` is a basic editor and interpreter environment + which ships with the standard distribution of Python. immutable An object with a fixed value. Immutable objects include numbers, strings and From webhook-mailer at python.org Wed Aug 10 22:44:25 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 11 Aug 2022 02:44:25 -0000 Subject: [Python-checkins] gh-75510: Edit idlelib entry in doc (#95869) Message-ID: <mailman.609.1660185865.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9af4aed73af0accffd26176c09aa263b68c8ca5d commit: 9af4aed73af0accffd26176c09aa263b68c8ca5d branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-10T22:44:17-04:00 summary: gh-75510: Edit idlelib entry in doc (#95869) Make section instead of subsection and revise sentence. files: M Doc/library/idle.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 81e0182e10b..3058bcead66 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -984,16 +984,19 @@ beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + idlelib -^^^^^^^ +------- .. module:: idlelib :synopsis: Implementation package for the IDLE shell/editor. **Source code:** :source:`Lib/idlelib` -The Lib/idlelib package implements the IDLE application. See the top -of this file or content listing on the left for how to use IDLE. +-------------- + +The Lib/idlelib package implements the IDLE application. See the rest +of this page for how to use IDLE. The files in idlelib are described in idlelib/README.txt. Access it either in idlelib or click Help => About IDLE on the IDLE menu. This From webhook-mailer at python.org Wed Aug 10 23:02:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 03:02:13 -0000 Subject: [Python-checkins] gh-75510: Edit idlelib entry in doc (GH-95869) Message-ID: <mailman.610.1660186934.3313.python-checkins@python.org> https://github.com/python/cpython/commit/209f2a7b450648d6f24d84fd32f948f6a9f7c7ab commit: 209f2a7b450648d6f24d84fd32f948f6a9f7c7ab branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-10T20:02:09-07:00 summary: gh-75510: Edit idlelib entry in doc (GH-95869) Make section instead of subsection and revise sentence. (cherry picked from commit 9af4aed73af0accffd26176c09aa263b68c8ca5d) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/library/idle.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 81e0182e10b..3058bcead66 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -984,16 +984,19 @@ beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + idlelib -^^^^^^^ +------- .. module:: idlelib :synopsis: Implementation package for the IDLE shell/editor. **Source code:** :source:`Lib/idlelib` -The Lib/idlelib package implements the IDLE application. See the top -of this file or content listing on the left for how to use IDLE. +-------------- + +The Lib/idlelib package implements the IDLE application. See the rest +of this page for how to use IDLE. The files in idlelib are described in idlelib/README.txt. Access it either in idlelib or click Help => About IDLE on the IDLE menu. This From webhook-mailer at python.org Wed Aug 10 23:03:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 03:03:05 -0000 Subject: [Python-checkins] gh-75510: Edit idlelib entry in doc (GH-95869) Message-ID: <mailman.611.1660186987.3313.python-checkins@python.org> https://github.com/python/cpython/commit/759227f7e9a50ad7efd9342cfafc294655f01599 commit: 759227f7e9a50ad7efd9342cfafc294655f01599 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-10T20:03:01-07:00 summary: gh-75510: Edit idlelib entry in doc (GH-95869) Make section instead of subsection and revise sentence. (cherry picked from commit 9af4aed73af0accffd26176c09aa263b68c8ca5d) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Doc/library/idle.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 81e0182e10b..3058bcead66 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -984,16 +984,19 @@ beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + idlelib -^^^^^^^ +------- .. module:: idlelib :synopsis: Implementation package for the IDLE shell/editor. **Source code:** :source:`Lib/idlelib` -The Lib/idlelib package implements the IDLE application. See the top -of this file or content listing on the left for how to use IDLE. +-------------- + +The Lib/idlelib package implements the IDLE application. See the rest +of this page for how to use IDLE. The files in idlelib are described in idlelib/README.txt. Access it either in idlelib or click Help => About IDLE on the IDLE menu. This From webhook-mailer at python.org Thu Aug 11 02:24:01 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 11 Aug 2022 06:24:01 -0000 Subject: [Python-checkins] Docs: replace 'currying' by 'partial function'. (#91814) Message-ID: <mailman.612.1660199042.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b9e956fccf60e2083d63bdfa30d7e04c910e94c2 commit: b9e956fccf60e2083d63bdfa30d7e04c910e94c2 branch: main author: Clemens Tolboom <clemens at build2be.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-11T01:23:40-05:00 summary: Docs: replace 'currying' by 'partial function'. (#91814) files: M Doc/howto/functional.rst diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index 1c3bd23f9fe..7d30c343e37 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1223,6 +1223,8 @@ describing functional programming. https://en.wikipedia.org/wiki/Coroutine: Entry for coroutines. +https://en.wikipedia.org/wiki/Partial_application: Entry for the concept of partial function application. + https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying. Python-specific From webhook-mailer at python.org Thu Aug 11 03:31:58 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 07:31:58 -0000 Subject: [Python-checkins] gh-90385: Add pathlib.Path.walk what's new section (GH-95467) Message-ID: <mailman.613.1660203119.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5ed584cb6b4e544d307f2f1b6f28667078cc20af commit: 5ed584cb6b4e544d307f2f1b6f28667078cc20af branch: main author: Stanislav Zmiev <szmiev2000 at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T00:31:46-07:00 summary: gh-90385: Add pathlib.Path.walk what's new section (GH-95467) Automerge-Triggered-By: GH:brettcannon files: M Doc/whatsnew/3.12.rst diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index acf59616b2f..5926205ce5c 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -93,6 +93,13 @@ New Modules Improved Modules ================ +pathlib +------- + +* Add :meth:`~pathlib.Path.walk` for walking the directory trees and generating + all file or directory names within them, similar to :func:`os.walk`. + (Contributed by Stanislav Zmiev in :gh:`90385`.) + dis --- From webhook-mailer at python.org Thu Aug 11 04:56:03 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 11 Aug 2022 08:56:03 -0000 Subject: [Python-checkins] gh-95876: Fix format string in pegen error location code (#95877) Message-ID: <mailman.614.1660208165.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b4c857d0fd74abb1ede6fe083c4fa3ca728b2b83 commit: b4c857d0fd74abb1ede6fe083c4fa3ca728b2b83 branch: main author: Christian Heimes <christian at python.org> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-11T09:55:57+01:00 summary: gh-95876: Fix format string in pegen error location code (#95877) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst M Parser/pegen_errors.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst new file mode 100644 index 000000000000..96b69015a586 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst @@ -0,0 +1,4 @@ +Fix format string in ``_PyPegen_raise_error_known_location`` that can lead +to memory corruption on some 64bit systems. The function was building a +tuple with ``i`` (int) instead of ``n`` (Py_ssize_t) for Py_ssize_t +arguments. diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index c87d50abd2c7..95bbd43dc326 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -371,7 +371,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, } } } - tmp = Py_BuildValue("(OiiNii)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); + tmp = Py_BuildValue("(OnnNnn)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); if (!tmp) { goto error; } From webhook-mailer at python.org Thu Aug 11 05:19:51 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 09:19:51 -0000 Subject: [Python-checkins] gh-95876: Fix format string in pegen error location code (GH-95877) Message-ID: <mailman.615.1660209592.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1221e8c400933f24be69bd156f03cd1411746e6c commit: 1221e8c400933f24be69bd156f03cd1411746e6c branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T02:19:20-07:00 summary: gh-95876: Fix format string in pegen error location code (GH-95877) (cherry picked from commit b4c857d0fd74abb1ede6fe083c4fa3ca728b2b83) Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst M Parser/pegen_errors.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst new file mode 100644 index 000000000000..96b69015a586 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst @@ -0,0 +1,4 @@ +Fix format string in ``_PyPegen_raise_error_known_location`` that can lead +to memory corruption on some 64bit systems. The function was building a +tuple with ``i`` (int) instead of ``n`` (Py_ssize_t) for Py_ssize_t +arguments. diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index 5703088443ed..a0f4b9809e21 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -371,7 +371,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, } } } - tmp = Py_BuildValue("(OiiNii)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); + tmp = Py_BuildValue("(OnnNnn)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); if (!tmp) { goto error; } From webhook-mailer at python.org Thu Aug 11 05:58:21 2022 From: webhook-mailer at python.org (tiran) Date: Thu, 11 Aug 2022 09:58:21 -0000 Subject: [Python-checkins] gh-95878: Fix format char in datetime CAPI tests (GH-95879) Message-ID: <mailman.616.1660211901.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8b34e914bba2ccd6ae39609410db49d0beb19cb1 commit: 8b34e914bba2ccd6ae39609410db49d0beb19cb1 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-11T11:58:10+02:00 summary: gh-95878: Fix format char in datetime CAPI tests (GH-95879) files: M Modules/_testcapimodule.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 91bdeb8b6464..8d9a0c15b1b0 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2438,7 +2438,7 @@ test_PyDateTime_GET(PyObject *self, PyObject *obj) month = PyDateTime_GET_MONTH(obj); day = PyDateTime_GET_DAY(obj); - return Py_BuildValue("(lll)", year, month, day); + return Py_BuildValue("(iii)", year, month, day); } static PyObject * @@ -2452,7 +2452,7 @@ test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2466,7 +2466,7 @@ test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2478,7 +2478,7 @@ test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) seconds = PyDateTime_DELTA_GET_SECONDS(obj); microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); - return Py_BuildValue("(lll)", days, seconds, microseconds); + return Py_BuildValue("(iii)", days, seconds, microseconds); } /* test_thread_state spawns a thread of its own, and that thread releases From webhook-mailer at python.org Thu Aug 11 07:32:58 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 11 Aug 2022 11:32:58 -0000 Subject: [Python-checkins] Update _PyEval_AddPendingCall comment (#95817) Message-ID: <mailman.617.1660217578.3313.python-checkins@python.org> https://github.com/python/cpython/commit/23a757f44fbe29924da8bec7f3682f99a2c0fee5 commit: 23a757f44fbe29924da8bec7f3682f99a2c0fee5 branch: main author: zhanpon <pon.zhan at gmail.com> committer: vstinner <vstinner at python.org> date: 2022-08-11T13:32:52+02:00 summary: Update _PyEval_AddPendingCall comment (#95817) files: M Python/ceval.c diff --git a/Python/ceval.c b/Python/ceval.c index abb934d494f3..d34d6bfeec09 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -630,8 +630,8 @@ _PyEval_AddPendingCall(PyInterpreterState *interp, { struct _pending_calls *pending = &interp->ceval.pending; - /* Ensure that _PyEval_InitPendingCalls() was called - and that _PyEval_FiniPendingCalls() is not called yet. */ + /* Ensure that _PyEval_InitState() was called + and that _PyEval_FiniState() is not called yet. */ assert(pending->lock != NULL); PyThread_acquire_lock(pending->lock, WAIT_LOCK); From webhook-mailer at python.org Thu Aug 11 07:46:51 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 11 Aug 2022 11:46:51 -0000 Subject: [Python-checkins] gh-95878: Fix format char in datetime CAPI tests (GH-95879) (#95885) Message-ID: <mailman.618.1660218412.3313.python-checkins@python.org> https://github.com/python/cpython/commit/731732aa8bf71b84e4bc1dfead27f524eb710fce commit: 731732aa8bf71b84e4bc1dfead27f524eb710fce branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-11T12:46:14+01:00 summary: gh-95878: Fix format char in datetime CAPI tests (GH-95879) (#95885) (cherry picked from commit 8b34e914bba2ccd6ae39609410db49d0beb19cb1) Co-authored-by: Christian Heimes <christian at python.org> Co-authored-by: Christian Heimes <christian at python.org> files: M Modules/_testcapimodule.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8087b444939f..1a3cbe0b212a 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2959,7 +2959,7 @@ test_PyDateTime_GET(PyObject *self, PyObject *obj) month = PyDateTime_GET_MONTH(obj); day = PyDateTime_GET_DAY(obj); - return Py_BuildValue("(lll)", year, month, day); + return Py_BuildValue("(iii)", year, month, day); } static PyObject * @@ -2973,7 +2973,7 @@ test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2987,7 +2987,7 @@ test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2999,7 +2999,7 @@ test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) seconds = PyDateTime_DELTA_GET_SECONDS(obj); microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); - return Py_BuildValue("(lll)", days, seconds, microseconds); + return Py_BuildValue("(iii)", days, seconds, microseconds); } /* test_thread_state spawns a thread of its own, and that thread releases From webhook-mailer at python.org Thu Aug 11 09:06:55 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 11 Aug 2022 13:06:55 -0000 Subject: [Python-checkins] GH-95818: Skip incomplete frames in `PyThreadState_GetFrame` (GH-95886) Message-ID: <mailman.619.1660223216.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1b46d118e6e72daa64b98cafddb406c68b419efa commit: 1b46d118e6e72daa64b98cafddb406c68b419efa branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-11T14:06:32+01:00 summary: GH-95818: Skip incomplete frames in `PyThreadState_GetFrame` (GH-95886) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst M Lib/test/test_frame.py M Python/pystate.c diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index a715e725a7e4..9fab17684eec 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -235,6 +235,28 @@ def inner(): r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code inner>$" % (file_repr, offset + 5)) +class TestIncompleteFrameAreInvisible(unittest.TestCase): + + def test_issue95818(self): + #See GH-95818 for details + import gc + self.addCleanup(gc.set_threshold, *gc.get_threshold()) + + gc.set_threshold(1,1,1) + class GCHello: + def __del__(self): + print("Destroyed from gc") + + def gen(): + yield + + fd = open(__file__) + l = [fd, GCHello()] + l.append(l) + del fd + del l + gen() + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst new file mode 100644 index 000000000000..1e243f5614f1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst @@ -0,0 +1 @@ +Skip over incomplete frames in :c:func:`PyThreadState_GetFrame`. diff --git a/Python/pystate.c b/Python/pystate.c index 11cc122185f7..bcdb825a8629 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1255,10 +1255,14 @@ PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { assert(tstate != NULL); - if (tstate->cframe->current_frame == NULL) { + _PyInterpreterFrame *f = tstate->cframe->current_frame; + while (f && _PyFrame_IsIncomplete(f)) { + f = f->previous; + } + if (f == NULL) { return NULL; } - PyFrameObject *frame = _PyFrame_GetFrameObject(tstate->cframe->current_frame); + PyFrameObject *frame = _PyFrame_GetFrameObject(f); if (frame == NULL) { PyErr_Clear(); } From webhook-mailer at python.org Thu Aug 11 12:17:23 2022 From: webhook-mailer at python.org (mdickinson) Date: Thu, 11 Aug 2022 16:17:23 -0000 Subject: [Python-checkins] gh-95605: Fix `float(s)` error message when `s` contains only whitespace (GH-95665) (GH-95858) Message-ID: <mailman.620.1660234644.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3ea9ba647850442ade8aec2c84c7f20afd0fb7c4 commit: 3ea9ba647850442ade8aec2c84c7f20afd0fb7c4 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: mdickinson <dickinsm at gmail.com> date: 2022-08-11T17:16:53+01:00 summary: gh-95605: Fix `float(s)` error message when `s` contains only whitespace (GH-95665) (GH-95858) This PR fixes the error message from float(s) in the case where s contains only whitespace. (cherry picked from commit 97e9cfa75a80b54a0630b7371f35e368a12749d1) Co-authored-by: Mark Dickinson <dickinsm at gmail.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst M Lib/test/test_float.py M Objects/floatobject.c diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index e99250199975..304388e1f78c 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -138,6 +138,10 @@ def check(s): check('123\xbd') check(' 123 456 ') check(b' 123 456 ') + # all whitespace (cf. https://github.com/python/cpython/issues/95605) + check('') + check(' ') + check('\t \n') # non-ascii digits (error came from non-digit '!') check('\u0663\u0661\u0664!') diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst new file mode 100644 index 000000000000..49441c6b3118 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-04-18-46-54.gh-issue-95605.FbpCoG.rst @@ -0,0 +1,2 @@ +Fix misleading contents of error message when converting an all-whitespace +string to :class:`float`. diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 47d308b8eb37..be6024659ab8 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -162,11 +162,18 @@ float_from_string_inner(const char *s, Py_ssize_t len, void *obj) double x; const char *end; const char *last = s + len; - /* strip space */ + /* strip leading whitespace */ while (s < last && Py_ISSPACE(*s)) { s++; } + if (s == last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", obj); + return NULL; + } + /* strip trailing whitespace */ while (s < last - 1 && Py_ISSPACE(last[-1])) { last--; } From webhook-mailer at python.org Thu Aug 11 12:41:12 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 11 Aug 2022 16:41:12 -0000 Subject: [Python-checkins] gh-87092: compiler's codegen stage uses int jump target labels, and the target pointer is only calculated just before optimization stage (GH-95655) Message-ID: <mailman.621.1660236073.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9533b40ccec3f196982dfb139379fc736d339bf1 commit: 9533b40ccec3f196982dfb139379fc736d339bf1 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-11T17:40:49+01:00 summary: gh-87092: compiler's codegen stage uses int jump target labels, and the target pointer is only calculated just before optimization stage (GH-95655) files: M Python/compile.c diff --git a/Python/compile.c b/Python/compile.c index 3c4dd56b059..a971b09c530 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -85,6 +85,9 @@ (opcode) == SETUP_WITH || \ (opcode) == SETUP_CLEANUP) +#define HAS_TARGET(opcode) \ + (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) + /* opcodes that must be last in the basicblock */ #define IS_TERMINATOR_OPCODE(opcode) \ (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode)) @@ -141,33 +144,31 @@ static struct location NO_LOCATION = {-1, -1, -1, -1}; typedef struct jump_target_label_ { int id; - struct basicblock_ *block; } jump_target_label; -static struct jump_target_label_ NO_LABEL = {-1, NULL}; +static struct jump_target_label_ NO_LABEL = {-1}; #define SAME_LABEL(L1, L2) ((L1).id == (L2).id) #define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) #define NEW_JUMP_TARGET_LABEL(C, NAME) \ - jump_target_label NAME = {cfg_new_label_id(CFG_BUILDER(C)), cfg_builder_new_block(CFG_BUILDER(C))}; \ + jump_target_label NAME = cfg_new_label(CFG_BUILDER(C)); \ if (!IS_LABEL(NAME)) { \ return 0; \ } -#define USE_LABEL(C, LBL) cfg_builder_use_label(CFG_BUILDER(C), LBL) +#define USE_LABEL(C, LBL) \ + if (cfg_builder_use_label(CFG_BUILDER(C), LBL) < 0) { \ + return 0; \ + } struct instr { int i_opcode; int i_oparg; - /* target block (if jump instruction) -- we temporarily have both the label - and the block in the instr. The label is set by front end, and the block - is calculated by backend. */ - jump_target_label i_target_label; - struct basicblock_ *i_target; - /* target block when exception is raised, should not be set by front-end. */ - struct basicblock_ *i_except; struct location i_loc; + /* The following fields should not be set by the front-end: */ + struct basicblock_ *i_target; /* target block (if jump instruction) */ + struct basicblock_ *i_except; /* target block when exception is raised */ }; typedef struct exceptstack { @@ -351,12 +352,12 @@ enum { typedef struct cfg_builder_ { /* The entryblock, at which control flow begins. All blocks of the CFG are reachable through the b_next links */ - basicblock *cfg_entryblock; + basicblock *g_entryblock; /* Pointer to the most recently allocated block. By following b_list links, you can reach all allocated blocks. */ - basicblock *block_list; + basicblock *g_block_list; /* pointer to the block currently being constructed */ - basicblock *curblock; + basicblock *g_curblock; /* label for the next instruction to be placed */ jump_target_label g_current_label; /* next free label id */ @@ -752,7 +753,7 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) static void cfg_builder_check(cfg_builder *g) { - for (basicblock *block = g->block_list; block != NULL; block = block->b_list) { + for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) { assert(!_PyMem_IsPtrFreed(block)); if (block->b_instr != NULL) { assert(block->b_ialloc > 0); @@ -770,7 +771,7 @@ static void cfg_builder_free(cfg_builder* g) { cfg_builder_check(g); - basicblock *b = g->block_list; + basicblock *b = g->g_block_list; while (b != NULL) { if (b->b_instr) { PyObject_Free((void *)b->b_instr); @@ -867,10 +868,11 @@ compiler_set_qualname(struct compiler *c) return 1; } -static int -cfg_new_label_id(cfg_builder *g) +static jump_target_label +cfg_new_label(cfg_builder *g) { - return g->g_next_free_label++; + jump_target_label lbl = {g->g_next_free_label++}; + return lbl; } /* Allocate a new block and return a pointer to it. @@ -885,8 +887,8 @@ cfg_builder_new_block(cfg_builder *g) return NULL; } /* Extend the singly linked list of blocks with new block. */ - b->b_list = g->block_list; - g->block_list = b; + b->b_list = g->g_block_list; + g->g_block_list = b; b->b_label = -1; return b; } @@ -895,8 +897,8 @@ static basicblock * cfg_builder_use_next_block(cfg_builder *g, basicblock *block) { assert(block != NULL); - g->curblock->b_next = block; - g->curblock = block; + g->g_curblock->b_next = block; + g->g_curblock = block; return block; } @@ -1282,17 +1284,12 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) */ static int -basicblock_addop(basicblock *b, int opcode, int oparg, - jump_target_label target, struct location loc) +basicblock_addop(basicblock *b, int opcode, int oparg, struct location loc) { assert(IS_WITHIN_OPCODE_RANGE(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); - assert(HAS_ARG(opcode) || oparg == 0); + assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0); assert(0 <= oparg && oparg < (1 << 30)); - assert(!IS_LABEL(target) || - IS_JUMP_OPCODE(opcode) || - IS_BLOCK_PUSH_OPCODE(opcode)); - assert(oparg == 0 || !IS_LABEL(target)); int off = basicblock_next_instr(b); if (off < 0) { @@ -1301,7 +1298,6 @@ basicblock_addop(basicblock *b, int opcode, int oparg, struct instr *i = &b->b_instr[off]; i->i_opcode = opcode; i->i_oparg = oparg; - i->i_target_label = target; i->i_target = NULL; i->i_loc = loc; @@ -1314,7 +1310,7 @@ cfg_builder_current_block_is_terminated(cfg_builder *g) if (IS_LABEL(g->g_current_label)) { return true; } - struct instr *last = basicblock_last_instr(g->curblock); + struct instr *last = basicblock_last_instr(g->g_curblock); return last && IS_TERMINATOR_OPCODE(last->i_opcode); } @@ -1322,38 +1318,31 @@ static int cfg_builder_maybe_start_new_block(cfg_builder *g) { if (cfg_builder_current_block_is_terminated(g)) { - basicblock *b; - if (IS_LABEL(g->g_current_label)) { - b = g->g_current_label.block; - b->b_label = g->g_current_label.id; - g->g_current_label = NO_LABEL; - } - else { - b = cfg_builder_new_block(g); - } + basicblock *b = cfg_builder_new_block(g); if (b == NULL) { return -1; } + b->b_label = g->g_current_label.id; + g->g_current_label = NO_LABEL; cfg_builder_use_next_block(g, b); } return 0; } static int -cfg_builder_addop(cfg_builder *g, int opcode, int oparg, jump_target_label target, - struct location loc) +cfg_builder_addop(cfg_builder *g, int opcode, int oparg, struct location loc) { if (cfg_builder_maybe_start_new_block(g) != 0) { return -1; } - return basicblock_addop(g->curblock, opcode, oparg, target, loc); + return basicblock_addop(g->g_curblock, opcode, oparg, loc); } static int cfg_builder_addop_noarg(cfg_builder *g, int opcode, struct location loc) { assert(!HAS_ARG(opcode)); - return cfg_builder_addop(g, opcode, 0, NO_LABEL, loc); + return cfg_builder_addop(g, opcode, 0, loc); } static Py_ssize_t @@ -1565,7 +1554,7 @@ cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct locatio EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - return cfg_builder_addop(g, opcode, oparg_, NO_LABEL, loc); + return cfg_builder_addop(g, opcode, oparg_, loc); } static int @@ -1573,7 +1562,7 @@ cfg_builder_addop_j(cfg_builder *g, int opcode, jump_target_label target, struct { assert(IS_LABEL(target)); assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); - return cfg_builder_addop(g, opcode, 0, target, loc); + return cfg_builder_addop(g, opcode, target.id, loc); } @@ -1795,11 +1784,11 @@ compiler_enter_scope(struct compiler *c, identifier name, c->c_nestlevel++; cfg_builder *g = CFG_BUILDER(c); - g->block_list = NULL; + g->g_block_list = NULL; block = cfg_builder_new_block(g); if (block == NULL) return 0; - g->curblock = g->cfg_entryblock = block; + g->g_curblock = g->g_entryblock = block; g->g_current_label = NO_LABEL; if (u->u_scope_type == COMPILER_SCOPE_MODULE) { @@ -7092,7 +7081,7 @@ stackdepth(basicblock *entryblock, int code_flags) maxdepth = new_depth; } assert(depth >= 0); /* invalid code or bug in stackdepth() */ - if (is_jump(instr) || is_block_push(instr)) { + if (HAS_TARGET(instr->i_opcode)) { effect = stack_effect(instr->i_opcode, instr->i_oparg, 1); assert(effect != PY_INVALID_STACK_EFFECT); int target_depth = depth + effect; @@ -7393,7 +7382,7 @@ mark_cold(basicblock *entryblock) { static int push_cold_blocks_to_end(cfg_builder *g, int code_flags) { - basicblock *entryblock = g->cfg_entryblock; + basicblock *entryblock = g->g_entryblock; if (entryblock->b_next == NULL) { /* single basicblock, no need to reorder */ return 0; @@ -7410,17 +7399,14 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) { if (explicit_jump == NULL) { return -1; } - jump_target_label next_label = {b->b_next->b_label, b->b_next}; - basicblock_addop(explicit_jump, JUMP, 0, next_label, NO_LOCATION); + basicblock_addop(explicit_jump, JUMP, b->b_next->b_label, NO_LOCATION); explicit_jump->b_cold = 1; explicit_jump->b_next = b->b_next; b->b_next = explicit_jump; - /* calculate target from target_label */ - /* TODO: formalize an API for adding jumps in the backend */ + /* set target */ struct instr *last = basicblock_last_instr(explicit_jump); - last->i_target = last->i_target_label.block; - last->i_target_label = NO_LABEL; + last->i_target = explicit_jump->b_next; } } @@ -8226,12 +8212,9 @@ dump_instr(struct instr *i) if (HAS_ARG(i->i_opcode)) { sprintf(arg, "arg: %d ", i->i_oparg); } - if (is_jump(i)) { + if (HAS_TARGET(i->i_opcode)) { sprintf(arg, "target: %p ", i->i_target); } - if (is_block_push(i)) { - sprintf(arg, "except_target: %p ", i->i_target); - } fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", i->i_loc.lineno, i->i_opcode, arg, jabs, jrel); } @@ -8524,7 +8507,7 @@ assemble(struct compiler *c, int addNone) } /* Make sure every block that falls off the end returns None. */ - if (!basicblock_returns(CFG_BUILDER(c)->curblock)) { + if (!basicblock_returns(CFG_BUILDER(c)->g_curblock)) { UNSET_LOC(c); if (addNone) ADDOP_LOAD_CONST(c, Py_None); @@ -8546,7 +8529,7 @@ assemble(struct compiler *c, int addNone) } int nblocks = 0; - for (basicblock *b = CFG_BUILDER(c)->block_list; b != NULL; b = b->b_list) { + for (basicblock *b = CFG_BUILDER(c)->g_block_list; b != NULL; b = b->b_list) { nblocks++; } if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { @@ -8555,7 +8538,7 @@ assemble(struct compiler *c, int addNone) } cfg_builder *g = CFG_BUILDER(c); - basicblock *entryblock = g->cfg_entryblock; + basicblock *entryblock = g->g_entryblock; assert(entryblock != NULL); /* Set firstlineno if it wasn't explicitly set. */ @@ -8974,7 +8957,7 @@ optimize_basic_block(PyObject *const_cache, 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 (is_jump(inst) || is_block_push(inst)) { + if (HAS_TARGET(inst->i_opcode)) { /* Skip over empty basic blocks. */ while (inst->i_target->b_iused == 0) { inst->i_target = inst->i_target->b_next; @@ -9379,7 +9362,7 @@ eliminate_empty_basic_blocks(basicblock *entryblock) { } for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; - if (is_jump(instr) || is_block_push(instr)) { + if (HAS_TARGET(instr->i_opcode)) { basicblock *target = instr->i_target; while (target->b_iused == 0) { target = target->b_next; @@ -9458,14 +9441,13 @@ calculate_jump_targets(basicblock *entryblock) for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; assert(instr->i_target == NULL); - if (is_jump(instr) || is_block_push(instr)) { - int lbl = instr->i_target_label.id; + if (HAS_TARGET(instr->i_opcode)) { + int lbl = instr->i_oparg; assert(lbl >= 0 && lbl <= max_label); instr->i_target = label2block[lbl]; assert(instr->i_target != NULL); assert(instr->i_target->b_label == lbl); } - instr->i_target_label = NO_LABEL; } } PyMem_Free(label2block); @@ -9577,7 +9559,7 @@ duplicate_exits_without_lineno(cfg_builder *g) { /* Copy all exit blocks without line number that are targets of a jump. */ - basicblock *entryblock = g->cfg_entryblock; + basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { if (b->b_iused > 0 && is_jump(&b->b_instr[b->b_iused-1])) { basicblock *target = b->b_instr[b->b_iused-1].i_target; From webhook-mailer at python.org Thu Aug 11 14:07:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 18:07:21 -0000 Subject: [Python-checkins] gh-95878: Fix format char in datetime CAPI tests (GH-95879) Message-ID: <mailman.622.1660241242.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9c04e25308ef2bfa44f2cca0b56bfe46be1f6b1b commit: 9c04e25308ef2bfa44f2cca0b56bfe46be1f6b1b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T11:06:48-07:00 summary: gh-95878: Fix format char in datetime CAPI tests (GH-95879) (cherry picked from commit 8b34e914bba2ccd6ae39609410db49d0beb19cb1) Co-authored-by: Christian Heimes <christian at python.org> files: M Modules/_testcapimodule.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7cce4e5a3f3b..9f74c9976911 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2800,7 +2800,7 @@ test_PyDateTime_GET(PyObject *self, PyObject *obj) month = PyDateTime_GET_MONTH(obj); day = PyDateTime_GET_DAY(obj); - return Py_BuildValue("(lll)", year, month, day); + return Py_BuildValue("(iii)", year, month, day); } static PyObject * @@ -2814,7 +2814,7 @@ test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2828,7 +2828,7 @@ test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); } static PyObject * @@ -2840,7 +2840,7 @@ test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) seconds = PyDateTime_DELTA_GET_SECONDS(obj); microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); - return Py_BuildValue("(lll)", days, seconds, microseconds); + return Py_BuildValue("(iii)", days, seconds, microseconds); } /* test_thread_state spawns a thread of its own, and that thread releases From webhook-mailer at python.org Thu Aug 11 15:42:06 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 19:42:06 -0000 Subject: [Python-checkins] [3.10] gh-95876: Fix format string in pegen error location code (GH-95877 (GH-95901) Message-ID: <mailman.623.1660246928.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2a6b67f1c516d0e693abd0dc13c7c7799815fd18 commit: 2a6b67f1c516d0e693abd0dc13c7c7799815fd18 branch: 3.10 author: Christian Heimes <christian at python.org> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T12:41:35-07:00 summary: [3.10] gh-95876: Fix format string in pegen error location code (GH-95877 (GH-95901) (cherry picked from commit b4c857d0fd74abb1ede6fe083c4fa3ca728b2b83) Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst M Parser/pegen.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst new file mode 100644 index 000000000000..96b69015a586 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-09-19-55.gh-issue-95876.YpQfoV.rst @@ -0,0 +1,4 @@ +Fix format string in ``_PyPegen_raise_error_known_location`` that can lead +to memory corruption on some 64bit systems. The function was building a +tuple with ``i`` (int) instead of ``n`` (Py_ssize_t) for Py_ssize_t +arguments. diff --git a/Parser/pegen.c b/Parser/pegen.c index 016f070c4745..acad95520a9f 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -547,7 +547,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, byte_offset_to_character_offset(error_line, end_col_offset) : end_col_number; } - tmp = Py_BuildValue("(OiiNii)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); + tmp = Py_BuildValue("(OnnNnn)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); if (!tmp) { goto error; } From webhook-mailer at python.org Thu Aug 11 16:50:59 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 11 Aug 2022 20:50:59 -0000 Subject: [Python-checkins] gh-84910: Change 'IDLE Help' to 'IDLE Doc' (#95873) Message-ID: <mailman.624.1660251060.3313.python-checkins@python.org> https://github.com/python/cpython/commit/05a0f37029f8ef917ed7ddbf7871856fc73aaca1 commit: 05a0f37029f8ef917ed7ddbf7871856fc73aaca1 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-11T16:50:49-04:00 summary: gh-84910: Change 'IDLE Help' to 'IDLE Doc' (#95873) 'IDLE Help' was a plain text file. It was superceded years ago by a copy of the much more complete html doc. . files: M Lib/idlelib/mainmenu.py diff --git a/Lib/idlelib/mainmenu.py b/Lib/idlelib/mainmenu.py index 429c8660ce0d..91a32cebb513 100644 --- a/Lib/idlelib/mainmenu.py +++ b/Lib/idlelib/mainmenu.py @@ -111,7 +111,7 @@ ('help', [ ('_About IDLE', '<<about-idle>>'), None, - ('_IDLE Help', '<<help>>'), + ('_IDLE Doc', '<<help>>'), ('Python _Docs', '<<python-docs>>'), ]), ] From webhook-mailer at python.org Thu Aug 11 16:54:13 2022 From: webhook-mailer at python.org (terryjreedy) Date: Thu, 11 Aug 2022 20:54:13 -0000 Subject: [Python-checkins] gh-95841: IDLE - Revise Windows local doc url (#95845) Message-ID: <mailman.625.1660251254.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bdb2cf8e913c041f26e8976abe58414819b3e8ff commit: bdb2cf8e913c041f26e8976abe58414819b3e8ff branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-11T16:54:03-04:00 summary: gh-95841: IDLE - Revise Windows local doc url (#95845) #91242 replaced the Windows chm help file with a copy of the html docs. This PR replaces the IDLE code that fetches the Windows local help url passed to os.startfile. Co-authored-by: Steve Dower files: M Lib/idlelib/editor.py diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 859a288b4bc..08d6aa2efde 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -86,10 +86,20 @@ def __init__(self, flist=None, filename=None, key=None, root=None): dochome = os.path.join(basepath, pyver, 'Doc', 'index.html') elif sys.platform[:3] == 'win': - chmfile = os.path.join(sys.base_prefix, 'Doc', - 'Python%s.chm' % _sphinx_version()) - if os.path.isfile(chmfile): - dochome = chmfile + import winreg # Windows only, block only executed once. + docfile = '' + KEY = (rf"Software\Python\PythonCore\{sys.winver}" + r"\Help\Main Python Documentation") + try: + docfile = winreg.QueryValue(winreg.HKEY_CURRENT_USER, KEY) + except FileNotFoundError: + try: + docfile = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, + KEY) + except FileNotFoundError: + pass + if os.path.isfile(docfile): + dochome = docfile elif sys.platform == 'darwin': # documentation may be stored inside a python framework dochome = os.path.join(sys.base_prefix, From webhook-mailer at python.org Thu Aug 11 17:14:40 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 21:14:40 -0000 Subject: [Python-checkins] gh-84910: Change 'IDLE Help' to 'IDLE Doc' (GH-95873) Message-ID: <mailman.626.1660252481.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f8df88e07a731acb10ef52e5794f2ffe179d8799 commit: f8df88e07a731acb10ef52e5794f2ffe179d8799 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T14:14:30-07:00 summary: gh-84910: Change 'IDLE Help' to 'IDLE Doc' (GH-95873) 'IDLE Help' was a plain text file. It was superceded years ago by a copy of the much more complete html doc. . (cherry picked from commit 05a0f37029f8ef917ed7ddbf7871856fc73aaca1) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/mainmenu.py diff --git a/Lib/idlelib/mainmenu.py b/Lib/idlelib/mainmenu.py index 429c8660ce0d..91a32cebb513 100644 --- a/Lib/idlelib/mainmenu.py +++ b/Lib/idlelib/mainmenu.py @@ -111,7 +111,7 @@ ('help', [ ('_About IDLE', '<<about-idle>>'), None, - ('_IDLE Help', '<<help>>'), + ('_IDLE Doc', '<<help>>'), ('Python _Docs', '<<python-docs>>'), ]), ] From webhook-mailer at python.org Thu Aug 11 17:17:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 21:17:21 -0000 Subject: [Python-checkins] gh-84910: Change 'IDLE Help' to 'IDLE Doc' (GH-95873) Message-ID: <mailman.627.1660252641.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2579c4954f93e25652974f7d1a16b3c8d763cc36 commit: 2579c4954f93e25652974f7d1a16b3c8d763cc36 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T14:17:11-07:00 summary: gh-84910: Change 'IDLE Help' to 'IDLE Doc' (GH-95873) 'IDLE Help' was a plain text file. It was superceded years ago by a copy of the much more complete html doc. . (cherry picked from commit 05a0f37029f8ef917ed7ddbf7871856fc73aaca1) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/mainmenu.py diff --git a/Lib/idlelib/mainmenu.py b/Lib/idlelib/mainmenu.py index 429c8660ce0d..91a32cebb513 100644 --- a/Lib/idlelib/mainmenu.py +++ b/Lib/idlelib/mainmenu.py @@ -111,7 +111,7 @@ ('help', [ ('_About IDLE', '<<about-idle>>'), None, - ('_IDLE Help', '<<help>>'), + ('_IDLE Doc', '<<help>>'), ('Python _Docs', '<<python-docs>>'), ]), ] From webhook-mailer at python.org Thu Aug 11 17:26:00 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Thu, 11 Aug 2022 21:26:00 -0000 Subject: [Python-checkins] gh-90928: Statically Initialize the Keywords Tuple in Clinic-Generated Code (gh-95860) Message-ID: <mailman.628.1660253161.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6f6a4e6cc5cd76af4a53ffbb62b686142646ac9a commit: 6f6a4e6cc5cd76af4a53ffbb62b686142646ac9a branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-11T15:25:49-06:00 summary: gh-90928: Statically Initialize the Keywords Tuple in Clinic-Generated Code (gh-95860) We only statically initialize for core code and builtin modules. Extension modules still create the tuple at runtime. We'll solve that part of interpreter isolation separately. This change includes generated code. The non-generated changes are in: * Tools/clinic/clinic.py * Python/getargs.c * Include/cpython/modsupport.h * Makefile.pre.in (re-generate global strings after running clinic) * very minor tweaks to Modules/_codecsmodule.c and Python/Python-tokenize.c All other changes are generated code (clinic, global strings). files: M Include/cpython/modsupport.h M Include/internal/pycore_global_strings.h M Include/internal/pycore_runtime_init_generated.h M Lib/test/clinic.test M Makefile.pre.in M Modules/_blake2/clinic/blake2b_impl.c.h M Modules/_blake2/clinic/blake2s_impl.c.h M Modules/_codecsmodule.c M Modules/_io/clinic/_iomodule.c.h M Modules/_io/clinic/bufferedio.c.h M Modules/_io/clinic/bytesio.c.h M Modules/_io/clinic/fileio.c.h M Modules/_io/clinic/iobase.c.h M Modules/_io/clinic/stringio.c.h M Modules/_io/clinic/textio.c.h M Modules/_io/clinic/winconsoleio.c.h M Modules/_multiprocessing/clinic/multiprocessing.c.h M Modules/_multiprocessing/clinic/posixshmem.c.h M Modules/_multiprocessing/clinic/semaphore.c.h M Modules/_randommodule.c M Modules/_sha3/clinic/sha3module.c.h M Modules/_sqlite/clinic/blob.c.h M Modules/_sqlite/clinic/connection.c.h M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/clinic/module.c.h M Modules/_sqlite/clinic/row.c.h M Modules/_sre/clinic/sre.c.h M Modules/_ssl/clinic/cert.c.h M Modules/_testcapi/clinic/vectorcall.c.h M Modules/cjkcodecs/clinic/multibytecodec.c.h M Modules/clinic/_abc.c.h M Modules/clinic/_asynciomodule.c.h M Modules/clinic/_bisectmodule.c.h M Modules/clinic/_bz2module.c.h M Modules/clinic/_codecsmodule.c.h M Modules/clinic/_collectionsmodule.c.h M Modules/clinic/_contextvarsmodule.c.h M Modules/clinic/_cryptmodule.c.h M Modules/clinic/_csv.c.h M Modules/clinic/_curses_panel.c.h M Modules/clinic/_cursesmodule.c.h M Modules/clinic/_datetimemodule.c.h M Modules/clinic/_dbmmodule.c.h M Modules/clinic/_elementtree.c.h M Modules/clinic/_gdbmmodule.c.h M Modules/clinic/_hashopenssl.c.h M Modules/clinic/_heapqmodule.c.h M Modules/clinic/_localemodule.c.h M Modules/clinic/_lsprof.c.h M Modules/clinic/_lzmamodule.c.h M Modules/clinic/_opcode.c.h M Modules/clinic/_operator.c.h M Modules/clinic/_pickle.c.h M Modules/clinic/_queuemodule.c.h M Modules/clinic/_randommodule.c.h M Modules/clinic/_ssl.c.h M Modules/clinic/_statisticsmodule.c.h M Modules/clinic/_struct.c.h M Modules/clinic/_testmultiphase.c.h M Modules/clinic/_tkinter.c.h M Modules/clinic/_tracemalloc.c.h M Modules/clinic/_typingmodule.c.h M Modules/clinic/_weakref.c.h M Modules/clinic/_winapi.c.h M Modules/clinic/arraymodule.c.h M Modules/clinic/audioop.c.h M Modules/clinic/binascii.c.h M Modules/clinic/cmathmodule.c.h M Modules/clinic/fcntlmodule.c.h M Modules/clinic/gcmodule.c.h M Modules/clinic/grpmodule.c.h M Modules/clinic/itertoolsmodule.c.h M Modules/clinic/mathmodule.c.h M Modules/clinic/md5module.c.h M Modules/clinic/overlapped.c.h M Modules/clinic/posixmodule.c.h M Modules/clinic/pwdmodule.c.h M Modules/clinic/pyexpat.c.h M Modules/clinic/readline.c.h M Modules/clinic/resource.c.h M Modules/clinic/selectmodule.c.h M Modules/clinic/sha1module.c.h M Modules/clinic/sha256module.c.h M Modules/clinic/sha512module.c.h M Modules/clinic/signalmodule.c.h M Modules/clinic/socketmodule.c.h M Modules/clinic/spwdmodule.c.h M Modules/clinic/symtablemodule.c.h M Modules/clinic/termios.c.h M Modules/clinic/unicodedata.c.h M Modules/clinic/zlibmodule.c.h M Objects/clinic/bytearrayobject.c.h M Objects/clinic/bytesobject.c.h M Objects/clinic/classobject.c.h M Objects/clinic/codeobject.c.h M Objects/clinic/complexobject.c.h M Objects/clinic/descrobject.c.h M Objects/clinic/dictobject.c.h M Objects/clinic/enumobject.c.h M Objects/clinic/floatobject.c.h M Objects/clinic/funcobject.c.h M Objects/clinic/listobject.c.h M Objects/clinic/longobject.c.h M Objects/clinic/memoryobject.c.h M Objects/clinic/moduleobject.c.h M Objects/clinic/odictobject.c.h M Objects/clinic/structseq.c.h M Objects/clinic/tupleobject.c.h M Objects/clinic/typeobject.c.h M Objects/clinic/unicodeobject.c.h M Objects/stringlib/clinic/transmogrify.h.h M PC/clinic/_msi.c.h M PC/clinic/_testconsole.c.h M PC/clinic/msvcrtmodule.c.h M PC/clinic/winreg.c.h M PC/clinic/winsound.c.h M Python/Python-tokenize.c M Python/clinic/Python-tokenize.c.h M Python/clinic/_warnings.c.h M Python/clinic/bltinmodule.c.h M Python/clinic/context.c.h M Python/clinic/import.c.h M Python/clinic/marshal.c.h M Python/clinic/sysmodule.c.h M Python/clinic/traceback.c.h M Python/getargs.c M Tools/clinic/clinic.py diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h index 591dcb132961..d8458923b3fa 100644 --- a/Include/cpython/modsupport.h +++ b/Include/cpython/modsupport.h @@ -51,6 +51,7 @@ PyAPI_FUNC(PyObject **) _Py_VaBuildStack( Py_ssize_t *p_nargs); typedef struct _PyArg_Parser { + int initialized; const char *format; const char * const *keywords; const char *fname; diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 2bf16c30e1bc..aada22039502 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -215,6 +215,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(_blksize) STRUCT_FOR_ID(_bootstrap) STRUCT_FOR_ID(_dealloc_warn) + STRUCT_FOR_ID(_feature_version) STRUCT_FOR_ID(_finalizing) STRUCT_FOR_ID(_find_and_load) STRUCT_FOR_ID(_fix_up_module) @@ -229,93 +230,302 @@ struct _Py_global_strings { STRUCT_FOR_ID(_uninitialized_submodules) STRUCT_FOR_ID(_warn_unawaited_coroutine) STRUCT_FOR_ID(_xoptions) + STRUCT_FOR_ID(a) + STRUCT_FOR_ID(abs_tol) + STRUCT_FOR_ID(access) STRUCT_FOR_ID(add) + STRUCT_FOR_ID(after_in_child) + STRUCT_FOR_ID(after_in_parent) + STRUCT_FOR_ID(aggregate_class) STRUCT_FOR_ID(append) + STRUCT_FOR_ID(argdefs) + STRUCT_FOR_ID(arguments) + STRUCT_FOR_ID(argv) + STRUCT_FOR_ID(attribute) + STRUCT_FOR_ID(authorizer_callback) + STRUCT_FOR_ID(b) + STRUCT_FOR_ID(backtick) + STRUCT_FOR_ID(base) + STRUCT_FOR_ID(before) STRUCT_FOR_ID(big) + STRUCT_FOR_ID(binary_form) + STRUCT_FOR_ID(block) STRUCT_FOR_ID(buffer) + STRUCT_FOR_ID(buffer_callback) + STRUCT_FOR_ID(buffer_size) + STRUCT_FOR_ID(buffering) + STRUCT_FOR_ID(buffers) + STRUCT_FOR_ID(bufsize) STRUCT_FOR_ID(builtins) + STRUCT_FOR_ID(byteorder) + STRUCT_FOR_ID(bytes) + STRUCT_FOR_ID(bytes_per_sep) STRUCT_FOR_ID(c_call) STRUCT_FOR_ID(c_exception) STRUCT_FOR_ID(c_return) + STRUCT_FOR_ID(cached_statements) + STRUCT_FOR_ID(cadata) + STRUCT_FOR_ID(cafile) STRUCT_FOR_ID(call) + STRUCT_FOR_ID(capath) + STRUCT_FOR_ID(category) + STRUCT_FOR_ID(cb_type) + STRUCT_FOR_ID(certfile) + STRUCT_FOR_ID(check_same_thread) STRUCT_FOR_ID(clear) STRUCT_FOR_ID(close) STRUCT_FOR_ID(closed) + STRUCT_FOR_ID(closefd) + STRUCT_FOR_ID(closure) + STRUCT_FOR_ID(co_argcount) + STRUCT_FOR_ID(co_cellvars) + STRUCT_FOR_ID(co_code) + STRUCT_FOR_ID(co_consts) + STRUCT_FOR_ID(co_exceptiontable) + STRUCT_FOR_ID(co_filename) + STRUCT_FOR_ID(co_firstlineno) + STRUCT_FOR_ID(co_flags) + STRUCT_FOR_ID(co_freevars) + STRUCT_FOR_ID(co_kwonlyargcount) + STRUCT_FOR_ID(co_linetable) + STRUCT_FOR_ID(co_name) + STRUCT_FOR_ID(co_names) + STRUCT_FOR_ID(co_nlocals) + STRUCT_FOR_ID(co_posonlyargcount) + STRUCT_FOR_ID(co_qualname) + STRUCT_FOR_ID(co_stacksize) + STRUCT_FOR_ID(co_varnames) STRUCT_FOR_ID(code) + STRUCT_FOR_ID(command) + STRUCT_FOR_ID(comment_factory) + STRUCT_FOR_ID(context) + STRUCT_FOR_ID(cookie) STRUCT_FOR_ID(copy) STRUCT_FOR_ID(copyreg) + STRUCT_FOR_ID(coro) + STRUCT_FOR_ID(count) + STRUCT_FOR_ID(cwd) + STRUCT_FOR_ID(data) + STRUCT_FOR_ID(database) STRUCT_FOR_ID(decode) + STRUCT_FOR_ID(decoder) STRUCT_FOR_ID(default) STRUCT_FOR_ID(defaultaction) + STRUCT_FOR_ID(delete) + STRUCT_FOR_ID(depth) + STRUCT_FOR_ID(detect_types) + STRUCT_FOR_ID(deterministic) + STRUCT_FOR_ID(device) + STRUCT_FOR_ID(dict) STRUCT_FOR_ID(dictcomp) STRUCT_FOR_ID(difference_update) + STRUCT_FOR_ID(digest) + STRUCT_FOR_ID(digest_size) + STRUCT_FOR_ID(digestmod) + STRUCT_FOR_ID(dir_fd) STRUCT_FOR_ID(dispatch_table) STRUCT_FOR_ID(displayhook) + STRUCT_FOR_ID(dklen) + STRUCT_FOR_ID(doc) + STRUCT_FOR_ID(dont_inherit) + STRUCT_FOR_ID(dst) + STRUCT_FOR_ID(dst_dir_fd) + STRUCT_FOR_ID(duration) + STRUCT_FOR_ID(effective_ids) + STRUCT_FOR_ID(element_factory) STRUCT_FOR_ID(encode) STRUCT_FOR_ID(encoding) + STRUCT_FOR_ID(end) STRUCT_FOR_ID(end_lineno) STRUCT_FOR_ID(end_offset) + STRUCT_FOR_ID(endpos) + STRUCT_FOR_ID(env) STRUCT_FOR_ID(errors) + STRUCT_FOR_ID(event) + STRUCT_FOR_ID(eventmask) + STRUCT_FOR_ID(exc_type) + STRUCT_FOR_ID(exc_value) STRUCT_FOR_ID(excepthook) STRUCT_FOR_ID(exception) + STRUCT_FOR_ID(exp) STRUCT_FOR_ID(extend) + STRUCT_FOR_ID(factory) + STRUCT_FOR_ID(family) + STRUCT_FOR_ID(fanout) + STRUCT_FOR_ID(fd) + STRUCT_FOR_ID(fd2) + STRUCT_FOR_ID(fdel) + STRUCT_FOR_ID(fget) + STRUCT_FOR_ID(file) + STRUCT_FOR_ID(file_actions) STRUCT_FOR_ID(filename) STRUCT_FOR_ID(fileno) + STRUCT_FOR_ID(filepath) STRUCT_FOR_ID(fillvalue) STRUCT_FOR_ID(filters) + STRUCT_FOR_ID(final) STRUCT_FOR_ID(find_class) + STRUCT_FOR_ID(fix_imports) + STRUCT_FOR_ID(flags) STRUCT_FOR_ID(flush) + STRUCT_FOR_ID(follow_symlinks) + STRUCT_FOR_ID(format) + STRUCT_FOR_ID(frequency) + STRUCT_FOR_ID(fromlist) + STRUCT_FOR_ID(fset) + STRUCT_FOR_ID(func) + STRUCT_FOR_ID(generation) STRUCT_FOR_ID(genexpr) STRUCT_FOR_ID(get) STRUCT_FOR_ID(get_source) STRUCT_FOR_ID(getattr) STRUCT_FOR_ID(getstate) + STRUCT_FOR_ID(gid) + STRUCT_FOR_ID(globals) + STRUCT_FOR_ID(groupindex) + STRUCT_FOR_ID(groups) + STRUCT_FOR_ID(handle) + STRUCT_FOR_ID(hash_name) + STRUCT_FOR_ID(header) + STRUCT_FOR_ID(headers) + STRUCT_FOR_ID(hi) + STRUCT_FOR_ID(hook) + STRUCT_FOR_ID(id) STRUCT_FOR_ID(ignore) + STRUCT_FOR_ID(imag) STRUCT_FOR_ID(importlib) + STRUCT_FOR_ID(in_fd) + STRUCT_FOR_ID(incoming) + STRUCT_FOR_ID(indexgroup) STRUCT_FOR_ID(inf) + STRUCT_FOR_ID(inheritable) + STRUCT_FOR_ID(initial) + STRUCT_FOR_ID(initial_bytes) + STRUCT_FOR_ID(initial_value) + STRUCT_FOR_ID(initval) + STRUCT_FOR_ID(inner_size) + STRUCT_FOR_ID(input) + STRUCT_FOR_ID(insert_comments) + STRUCT_FOR_ID(insert_pis) + STRUCT_FOR_ID(intern) STRUCT_FOR_ID(intersection) STRUCT_FOR_ID(isatty) STRUCT_FOR_ID(isinstance) + STRUCT_FOR_ID(isolation_level) + STRUCT_FOR_ID(istext) + STRUCT_FOR_ID(item) STRUCT_FOR_ID(items) STRUCT_FOR_ID(iter) + STRUCT_FOR_ID(iterable) + STRUCT_FOR_ID(iterations) STRUCT_FOR_ID(join) + STRUCT_FOR_ID(jump) + STRUCT_FOR_ID(keepends) + STRUCT_FOR_ID(key) + STRUCT_FOR_ID(keyfile) STRUCT_FOR_ID(keys) + STRUCT_FOR_ID(kind) STRUCT_FOR_ID(lambda) + STRUCT_FOR_ID(last) + STRUCT_FOR_ID(last_node) STRUCT_FOR_ID(last_traceback) STRUCT_FOR_ID(last_type) STRUCT_FOR_ID(last_value) STRUCT_FOR_ID(latin1) + STRUCT_FOR_ID(leaf_size) STRUCT_FOR_ID(len) + STRUCT_FOR_ID(length) + STRUCT_FOR_ID(level) + STRUCT_FOR_ID(limit) STRUCT_FOR_ID(line) + STRUCT_FOR_ID(line_buffering) STRUCT_FOR_ID(lineno) STRUCT_FOR_ID(listcomp) STRUCT_FOR_ID(little) + STRUCT_FOR_ID(lo) STRUCT_FOR_ID(locale) + STRUCT_FOR_ID(locals) + STRUCT_FOR_ID(loop) + STRUCT_FOR_ID(mapping) STRUCT_FOR_ID(match) + STRUCT_FOR_ID(max_length) + STRUCT_FOR_ID(maxevents) + STRUCT_FOR_ID(maxmem) + STRUCT_FOR_ID(maxsplit) + STRUCT_FOR_ID(maxvalue) + STRUCT_FOR_ID(memLevel) + STRUCT_FOR_ID(memlimit) + STRUCT_FOR_ID(message) STRUCT_FOR_ID(metaclass) + STRUCT_FOR_ID(method) + STRUCT_FOR_ID(mod) STRUCT_FOR_ID(mode) + STRUCT_FOR_ID(module) + STRUCT_FOR_ID(module_globals) STRUCT_FOR_ID(modules) STRUCT_FOR_ID(mro) STRUCT_FOR_ID(msg) + STRUCT_FOR_ID(n) + STRUCT_FOR_ID(n_arg) STRUCT_FOR_ID(n_fields) STRUCT_FOR_ID(n_sequence_fields) STRUCT_FOR_ID(n_unnamed_fields) STRUCT_FOR_ID(name) + STRUCT_FOR_ID(namespace_separator) + STRUCT_FOR_ID(namespaces) + STRUCT_FOR_ID(narg) + STRUCT_FOR_ID(ndigits) + STRUCT_FOR_ID(new_limit) + STRUCT_FOR_ID(newline) STRUCT_FOR_ID(newlines) STRUCT_FOR_ID(next) + STRUCT_FOR_ID(node_depth) + STRUCT_FOR_ID(node_offset) + STRUCT_FOR_ID(ns) + STRUCT_FOR_ID(number) STRUCT_FOR_ID(obj) + STRUCT_FOR_ID(object) STRUCT_FOR_ID(offset) + STRUCT_FOR_ID(offset_dst) + STRUCT_FOR_ID(offset_src) + STRUCT_FOR_ID(on_type_read) STRUCT_FOR_ID(onceregistry) + STRUCT_FOR_ID(oparg) STRUCT_FOR_ID(opcode) STRUCT_FOR_ID(open) + STRUCT_FOR_ID(opener) + STRUCT_FOR_ID(operation) + STRUCT_FOR_ID(optimize) + STRUCT_FOR_ID(options) + STRUCT_FOR_ID(order) + STRUCT_FOR_ID(out_fd) + STRUCT_FOR_ID(outgoing) + STRUCT_FOR_ID(overlapped) + STRUCT_FOR_ID(owner) + STRUCT_FOR_ID(p) + STRUCT_FOR_ID(pages) STRUCT_FOR_ID(parent) + STRUCT_FOR_ID(password) STRUCT_FOR_ID(path) + STRUCT_FOR_ID(pattern) STRUCT_FOR_ID(peek) STRUCT_FOR_ID(persistent_id) STRUCT_FOR_ID(persistent_load) + STRUCT_FOR_ID(person) + STRUCT_FOR_ID(pi_factory) + STRUCT_FOR_ID(pid) + STRUCT_FOR_ID(policy) + STRUCT_FOR_ID(pos) STRUCT_FOR_ID(print_file_and_line) + STRUCT_FOR_ID(priority) + STRUCT_FOR_ID(progress) + STRUCT_FOR_ID(progress_handler) + STRUCT_FOR_ID(proto) + STRUCT_FOR_ID(protocol) STRUCT_FOR_ID(ps1) STRUCT_FOR_ID(ps2) + STRUCT_FOR_ID(quotetabs) + STRUCT_FOR_ID(r) STRUCT_FOR_ID(raw) STRUCT_FOR_ID(read) STRUCT_FOR_ID(read1) @@ -324,36 +534,115 @@ struct _Py_global_strings { STRUCT_FOR_ID(readinto) STRUCT_FOR_ID(readinto1) STRUCT_FOR_ID(readline) + STRUCT_FOR_ID(readonly) + STRUCT_FOR_ID(real) STRUCT_FOR_ID(reducer_override) + STRUCT_FOR_ID(registry) + STRUCT_FOR_ID(rel_tol) STRUCT_FOR_ID(reload) + STRUCT_FOR_ID(repl) STRUCT_FOR_ID(replace) + STRUCT_FOR_ID(reserved) STRUCT_FOR_ID(reset) + STRUCT_FOR_ID(resetids) STRUCT_FOR_ID(return) + STRUCT_FOR_ID(reverse) STRUCT_FOR_ID(reversed) + STRUCT_FOR_ID(s) + STRUCT_FOR_ID(salt) + STRUCT_FOR_ID(sched_priority) + STRUCT_FOR_ID(scheduler) STRUCT_FOR_ID(seek) STRUCT_FOR_ID(seekable) + STRUCT_FOR_ID(selectors) STRUCT_FOR_ID(send) + STRUCT_FOR_ID(sep) + STRUCT_FOR_ID(sequence) + STRUCT_FOR_ID(server_hostname) + STRUCT_FOR_ID(server_side) + STRUCT_FOR_ID(session) STRUCT_FOR_ID(setcomp) + STRUCT_FOR_ID(setpgroup) + STRUCT_FOR_ID(setsid) + STRUCT_FOR_ID(setsigdef) + STRUCT_FOR_ID(setsigmask) STRUCT_FOR_ID(setstate) + STRUCT_FOR_ID(shape) + STRUCT_FOR_ID(show_cmd) + STRUCT_FOR_ID(signed) + STRUCT_FOR_ID(size) + STRUCT_FOR_ID(sizehint) + STRUCT_FOR_ID(sleep) + STRUCT_FOR_ID(sock) STRUCT_FOR_ID(sort) + STRUCT_FOR_ID(sound) + STRUCT_FOR_ID(source) + STRUCT_FOR_ID(src) + STRUCT_FOR_ID(src_dir_fd) + STRUCT_FOR_ID(stacklevel) + STRUCT_FOR_ID(start) + STRUCT_FOR_ID(statement) + STRUCT_FOR_ID(status) STRUCT_FOR_ID(stderr) STRUCT_FOR_ID(stdin) STRUCT_FOR_ID(stdout) + STRUCT_FOR_ID(step) + STRUCT_FOR_ID(store_name) + STRUCT_FOR_ID(strategy) STRUCT_FOR_ID(strict) + STRUCT_FOR_ID(strict_mode) + STRUCT_FOR_ID(string) + STRUCT_FOR_ID(sub_key) STRUCT_FOR_ID(symmetric_difference_update) + STRUCT_FOR_ID(tabsize) + STRUCT_FOR_ID(tag) + STRUCT_FOR_ID(target) + STRUCT_FOR_ID(target_is_directory) + STRUCT_FOR_ID(task) + STRUCT_FOR_ID(tb_frame) + STRUCT_FOR_ID(tb_lasti) + STRUCT_FOR_ID(tb_lineno) + STRUCT_FOR_ID(tb_next) STRUCT_FOR_ID(tell) + STRUCT_FOR_ID(template) + STRUCT_FOR_ID(term) STRUCT_FOR_ID(text) STRUCT_FOR_ID(threading) STRUCT_FOR_ID(throw) + STRUCT_FOR_ID(timeout) + STRUCT_FOR_ID(times) STRUCT_FOR_ID(top) + STRUCT_FOR_ID(trace_callback) + STRUCT_FOR_ID(traceback) + STRUCT_FOR_ID(trailers) + STRUCT_FOR_ID(translate) STRUCT_FOR_ID(truncate) + STRUCT_FOR_ID(twice) + STRUCT_FOR_ID(txt) + STRUCT_FOR_ID(type) + STRUCT_FOR_ID(tz) + STRUCT_FOR_ID(uid) + STRUCT_FOR_ID(unlink) STRUCT_FOR_ID(unraisablehook) + STRUCT_FOR_ID(uri) + STRUCT_FOR_ID(usedforsecurity) + STRUCT_FOR_ID(value) STRUCT_FOR_ID(values) STRUCT_FOR_ID(version) STRUCT_FOR_ID(warnings) STRUCT_FOR_ID(warnoptions) + STRUCT_FOR_ID(wbits) + STRUCT_FOR_ID(week) + STRUCT_FOR_ID(weekday) + STRUCT_FOR_ID(which) + STRUCT_FOR_ID(who) + STRUCT_FOR_ID(withdata) STRUCT_FOR_ID(writable) STRUCT_FOR_ID(write) + STRUCT_FOR_ID(write_through) + STRUCT_FOR_ID(x) + STRUCT_FOR_ID(year) + STRUCT_FOR_ID(zdict) } identifiers; struct { PyASCIIObject _ascii; diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 9fe7c31dcb44..09890cd81201 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -724,6 +724,7 @@ extern "C" { INIT_ID(_blksize), \ INIT_ID(_bootstrap), \ INIT_ID(_dealloc_warn), \ + INIT_ID(_feature_version), \ INIT_ID(_finalizing), \ INIT_ID(_find_and_load), \ INIT_ID(_fix_up_module), \ @@ -738,93 +739,302 @@ extern "C" { INIT_ID(_uninitialized_submodules), \ INIT_ID(_warn_unawaited_coroutine), \ INIT_ID(_xoptions), \ + INIT_ID(a), \ + INIT_ID(abs_tol), \ + INIT_ID(access), \ INIT_ID(add), \ + INIT_ID(after_in_child), \ + INIT_ID(after_in_parent), \ + INIT_ID(aggregate_class), \ INIT_ID(append), \ + INIT_ID(argdefs), \ + INIT_ID(arguments), \ + INIT_ID(argv), \ + INIT_ID(attribute), \ + INIT_ID(authorizer_callback), \ + INIT_ID(b), \ + INIT_ID(backtick), \ + INIT_ID(base), \ + INIT_ID(before), \ INIT_ID(big), \ + INIT_ID(binary_form), \ + INIT_ID(block), \ INIT_ID(buffer), \ + INIT_ID(buffer_callback), \ + INIT_ID(buffer_size), \ + INIT_ID(buffering), \ + INIT_ID(buffers), \ + INIT_ID(bufsize), \ INIT_ID(builtins), \ + INIT_ID(byteorder), \ + INIT_ID(bytes), \ + INIT_ID(bytes_per_sep), \ INIT_ID(c_call), \ INIT_ID(c_exception), \ INIT_ID(c_return), \ + INIT_ID(cached_statements), \ + INIT_ID(cadata), \ + INIT_ID(cafile), \ INIT_ID(call), \ + INIT_ID(capath), \ + INIT_ID(category), \ + INIT_ID(cb_type), \ + INIT_ID(certfile), \ + INIT_ID(check_same_thread), \ INIT_ID(clear), \ INIT_ID(close), \ INIT_ID(closed), \ + INIT_ID(closefd), \ + INIT_ID(closure), \ + INIT_ID(co_argcount), \ + INIT_ID(co_cellvars), \ + INIT_ID(co_code), \ + INIT_ID(co_consts), \ + INIT_ID(co_exceptiontable), \ + INIT_ID(co_filename), \ + INIT_ID(co_firstlineno), \ + INIT_ID(co_flags), \ + INIT_ID(co_freevars), \ + INIT_ID(co_kwonlyargcount), \ + INIT_ID(co_linetable), \ + INIT_ID(co_name), \ + INIT_ID(co_names), \ + INIT_ID(co_nlocals), \ + INIT_ID(co_posonlyargcount), \ + INIT_ID(co_qualname), \ + INIT_ID(co_stacksize), \ + INIT_ID(co_varnames), \ INIT_ID(code), \ + INIT_ID(command), \ + INIT_ID(comment_factory), \ + INIT_ID(context), \ + INIT_ID(cookie), \ INIT_ID(copy), \ INIT_ID(copyreg), \ + INIT_ID(coro), \ + INIT_ID(count), \ + INIT_ID(cwd), \ + INIT_ID(data), \ + INIT_ID(database), \ INIT_ID(decode), \ + INIT_ID(decoder), \ INIT_ID(default), \ INIT_ID(defaultaction), \ + INIT_ID(delete), \ + INIT_ID(depth), \ + INIT_ID(detect_types), \ + INIT_ID(deterministic), \ + INIT_ID(device), \ + INIT_ID(dict), \ INIT_ID(dictcomp), \ INIT_ID(difference_update), \ + INIT_ID(digest), \ + INIT_ID(digest_size), \ + INIT_ID(digestmod), \ + INIT_ID(dir_fd), \ INIT_ID(dispatch_table), \ INIT_ID(displayhook), \ + INIT_ID(dklen), \ + INIT_ID(doc), \ + INIT_ID(dont_inherit), \ + INIT_ID(dst), \ + INIT_ID(dst_dir_fd), \ + INIT_ID(duration), \ + INIT_ID(effective_ids), \ + INIT_ID(element_factory), \ INIT_ID(encode), \ INIT_ID(encoding), \ + INIT_ID(end), \ INIT_ID(end_lineno), \ INIT_ID(end_offset), \ + INIT_ID(endpos), \ + INIT_ID(env), \ INIT_ID(errors), \ + INIT_ID(event), \ + INIT_ID(eventmask), \ + INIT_ID(exc_type), \ + INIT_ID(exc_value), \ INIT_ID(excepthook), \ INIT_ID(exception), \ + INIT_ID(exp), \ INIT_ID(extend), \ + INIT_ID(factory), \ + INIT_ID(family), \ + INIT_ID(fanout), \ + INIT_ID(fd), \ + INIT_ID(fd2), \ + INIT_ID(fdel), \ + INIT_ID(fget), \ + INIT_ID(file), \ + INIT_ID(file_actions), \ INIT_ID(filename), \ INIT_ID(fileno), \ + INIT_ID(filepath), \ INIT_ID(fillvalue), \ INIT_ID(filters), \ + INIT_ID(final), \ INIT_ID(find_class), \ + INIT_ID(fix_imports), \ + INIT_ID(flags), \ INIT_ID(flush), \ + INIT_ID(follow_symlinks), \ + INIT_ID(format), \ + INIT_ID(frequency), \ + INIT_ID(fromlist), \ + INIT_ID(fset), \ + INIT_ID(func), \ + INIT_ID(generation), \ INIT_ID(genexpr), \ INIT_ID(get), \ INIT_ID(get_source), \ INIT_ID(getattr), \ INIT_ID(getstate), \ + INIT_ID(gid), \ + INIT_ID(globals), \ + INIT_ID(groupindex), \ + INIT_ID(groups), \ + INIT_ID(handle), \ + INIT_ID(hash_name), \ + INIT_ID(header), \ + INIT_ID(headers), \ + INIT_ID(hi), \ + INIT_ID(hook), \ + INIT_ID(id), \ INIT_ID(ignore), \ + INIT_ID(imag), \ INIT_ID(importlib), \ + INIT_ID(in_fd), \ + INIT_ID(incoming), \ + INIT_ID(indexgroup), \ INIT_ID(inf), \ + INIT_ID(inheritable), \ + INIT_ID(initial), \ + INIT_ID(initial_bytes), \ + INIT_ID(initial_value), \ + INIT_ID(initval), \ + INIT_ID(inner_size), \ + INIT_ID(input), \ + INIT_ID(insert_comments), \ + INIT_ID(insert_pis), \ + INIT_ID(intern), \ INIT_ID(intersection), \ INIT_ID(isatty), \ INIT_ID(isinstance), \ + INIT_ID(isolation_level), \ + INIT_ID(istext), \ + INIT_ID(item), \ INIT_ID(items), \ INIT_ID(iter), \ + INIT_ID(iterable), \ + INIT_ID(iterations), \ INIT_ID(join), \ + INIT_ID(jump), \ + INIT_ID(keepends), \ + INIT_ID(key), \ + INIT_ID(keyfile), \ INIT_ID(keys), \ + INIT_ID(kind), \ INIT_ID(lambda), \ + INIT_ID(last), \ + INIT_ID(last_node), \ INIT_ID(last_traceback), \ INIT_ID(last_type), \ INIT_ID(last_value), \ INIT_ID(latin1), \ + INIT_ID(leaf_size), \ INIT_ID(len), \ + INIT_ID(length), \ + INIT_ID(level), \ + INIT_ID(limit), \ INIT_ID(line), \ + INIT_ID(line_buffering), \ INIT_ID(lineno), \ INIT_ID(listcomp), \ INIT_ID(little), \ + INIT_ID(lo), \ INIT_ID(locale), \ + INIT_ID(locals), \ + INIT_ID(loop), \ + INIT_ID(mapping), \ INIT_ID(match), \ + INIT_ID(max_length), \ + INIT_ID(maxevents), \ + INIT_ID(maxmem), \ + INIT_ID(maxsplit), \ + INIT_ID(maxvalue), \ + INIT_ID(memLevel), \ + INIT_ID(memlimit), \ + INIT_ID(message), \ INIT_ID(metaclass), \ + INIT_ID(method), \ + INIT_ID(mod), \ INIT_ID(mode), \ + INIT_ID(module), \ + INIT_ID(module_globals), \ INIT_ID(modules), \ INIT_ID(mro), \ INIT_ID(msg), \ + INIT_ID(n), \ + INIT_ID(n_arg), \ INIT_ID(n_fields), \ INIT_ID(n_sequence_fields), \ INIT_ID(n_unnamed_fields), \ INIT_ID(name), \ + INIT_ID(namespace_separator), \ + INIT_ID(namespaces), \ + INIT_ID(narg), \ + INIT_ID(ndigits), \ + INIT_ID(new_limit), \ + INIT_ID(newline), \ INIT_ID(newlines), \ INIT_ID(next), \ + INIT_ID(node_depth), \ + INIT_ID(node_offset), \ + INIT_ID(ns), \ + INIT_ID(number), \ INIT_ID(obj), \ + INIT_ID(object), \ INIT_ID(offset), \ + INIT_ID(offset_dst), \ + INIT_ID(offset_src), \ + INIT_ID(on_type_read), \ INIT_ID(onceregistry), \ + INIT_ID(oparg), \ INIT_ID(opcode), \ INIT_ID(open), \ + INIT_ID(opener), \ + INIT_ID(operation), \ + INIT_ID(optimize), \ + INIT_ID(options), \ + INIT_ID(order), \ + INIT_ID(out_fd), \ + INIT_ID(outgoing), \ + INIT_ID(overlapped), \ + INIT_ID(owner), \ + INIT_ID(p), \ + INIT_ID(pages), \ INIT_ID(parent), \ + INIT_ID(password), \ INIT_ID(path), \ + INIT_ID(pattern), \ INIT_ID(peek), \ INIT_ID(persistent_id), \ INIT_ID(persistent_load), \ + INIT_ID(person), \ + INIT_ID(pi_factory), \ + INIT_ID(pid), \ + INIT_ID(policy), \ + INIT_ID(pos), \ INIT_ID(print_file_and_line), \ + INIT_ID(priority), \ + INIT_ID(progress), \ + INIT_ID(progress_handler), \ + INIT_ID(proto), \ + INIT_ID(protocol), \ INIT_ID(ps1), \ INIT_ID(ps2), \ + INIT_ID(quotetabs), \ + INIT_ID(r), \ INIT_ID(raw), \ INIT_ID(read), \ INIT_ID(read1), \ @@ -833,36 +1043,115 @@ extern "C" { INIT_ID(readinto), \ INIT_ID(readinto1), \ INIT_ID(readline), \ + INIT_ID(readonly), \ + INIT_ID(real), \ INIT_ID(reducer_override), \ + INIT_ID(registry), \ + INIT_ID(rel_tol), \ INIT_ID(reload), \ + INIT_ID(repl), \ INIT_ID(replace), \ + INIT_ID(reserved), \ INIT_ID(reset), \ + INIT_ID(resetids), \ INIT_ID(return), \ + INIT_ID(reverse), \ INIT_ID(reversed), \ + INIT_ID(s), \ + INIT_ID(salt), \ + INIT_ID(sched_priority), \ + INIT_ID(scheduler), \ INIT_ID(seek), \ INIT_ID(seekable), \ + INIT_ID(selectors), \ INIT_ID(send), \ + INIT_ID(sep), \ + INIT_ID(sequence), \ + INIT_ID(server_hostname), \ + INIT_ID(server_side), \ + INIT_ID(session), \ INIT_ID(setcomp), \ + INIT_ID(setpgroup), \ + INIT_ID(setsid), \ + INIT_ID(setsigdef), \ + INIT_ID(setsigmask), \ INIT_ID(setstate), \ + INIT_ID(shape), \ + INIT_ID(show_cmd), \ + INIT_ID(signed), \ + INIT_ID(size), \ + INIT_ID(sizehint), \ + INIT_ID(sleep), \ + INIT_ID(sock), \ INIT_ID(sort), \ + INIT_ID(sound), \ + INIT_ID(source), \ + INIT_ID(src), \ + INIT_ID(src_dir_fd), \ + INIT_ID(stacklevel), \ + INIT_ID(start), \ + INIT_ID(statement), \ + INIT_ID(status), \ INIT_ID(stderr), \ INIT_ID(stdin), \ INIT_ID(stdout), \ + INIT_ID(step), \ + INIT_ID(store_name), \ + INIT_ID(strategy), \ INIT_ID(strict), \ + INIT_ID(strict_mode), \ + INIT_ID(string), \ + INIT_ID(sub_key), \ INIT_ID(symmetric_difference_update), \ + INIT_ID(tabsize), \ + INIT_ID(tag), \ + INIT_ID(target), \ + INIT_ID(target_is_directory), \ + INIT_ID(task), \ + INIT_ID(tb_frame), \ + INIT_ID(tb_lasti), \ + INIT_ID(tb_lineno), \ + INIT_ID(tb_next), \ INIT_ID(tell), \ + INIT_ID(template), \ + INIT_ID(term), \ INIT_ID(text), \ INIT_ID(threading), \ INIT_ID(throw), \ + INIT_ID(timeout), \ + INIT_ID(times), \ INIT_ID(top), \ + INIT_ID(trace_callback), \ + INIT_ID(traceback), \ + INIT_ID(trailers), \ + INIT_ID(translate), \ INIT_ID(truncate), \ + INIT_ID(twice), \ + INIT_ID(txt), \ + INIT_ID(type), \ + INIT_ID(tz), \ + INIT_ID(uid), \ + INIT_ID(unlink), \ INIT_ID(unraisablehook), \ + INIT_ID(uri), \ + INIT_ID(usedforsecurity), \ + INIT_ID(value), \ INIT_ID(values), \ INIT_ID(version), \ INIT_ID(warnings), \ INIT_ID(warnoptions), \ + INIT_ID(wbits), \ + INIT_ID(week), \ + INIT_ID(weekday), \ + INIT_ID(which), \ + INIT_ID(who), \ + INIT_ID(withdata), \ INIT_ID(writable), \ INIT_ID(write), \ + INIT_ID(write_through), \ + INIT_ID(x), \ + INIT_ID(year), \ + INIT_ID(zdict), \ }, \ .ascii = { \ _PyASCIIObject_INIT("\x00"), \ @@ -1461,6 +1750,8 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(_dealloc_warn); PyUnicode_InternInPlace(&string); + string = &_Py_ID(_feature_version); + PyUnicode_InternInPlace(&string); string = &_Py_ID(_finalizing); PyUnicode_InternInPlace(&string); string = &_Py_ID(_find_and_load); @@ -1489,78 +1780,296 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(_xoptions); PyUnicode_InternInPlace(&string); + string = &_Py_ID(a); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(abs_tol); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(access); + PyUnicode_InternInPlace(&string); string = &_Py_ID(add); PyUnicode_InternInPlace(&string); + string = &_Py_ID(after_in_child); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(after_in_parent); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(aggregate_class); + PyUnicode_InternInPlace(&string); string = &_Py_ID(append); PyUnicode_InternInPlace(&string); + string = &_Py_ID(argdefs); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(arguments); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(argv); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(attribute); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(authorizer_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(b); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(backtick); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(base); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(before); + PyUnicode_InternInPlace(&string); string = &_Py_ID(big); PyUnicode_InternInPlace(&string); + string = &_Py_ID(binary_form); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(block); + PyUnicode_InternInPlace(&string); string = &_Py_ID(buffer); PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffer_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffer_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffering); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffers); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(bufsize); + PyUnicode_InternInPlace(&string); string = &_Py_ID(builtins); PyUnicode_InternInPlace(&string); + string = &_Py_ID(byteorder); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(bytes); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(bytes_per_sep); + PyUnicode_InternInPlace(&string); string = &_Py_ID(c_call); PyUnicode_InternInPlace(&string); string = &_Py_ID(c_exception); PyUnicode_InternInPlace(&string); string = &_Py_ID(c_return); PyUnicode_InternInPlace(&string); + string = &_Py_ID(cached_statements); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cadata); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cafile); + PyUnicode_InternInPlace(&string); string = &_Py_ID(call); PyUnicode_InternInPlace(&string); + string = &_Py_ID(capath); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(category); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cb_type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(certfile); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(check_same_thread); + PyUnicode_InternInPlace(&string); string = &_Py_ID(clear); PyUnicode_InternInPlace(&string); string = &_Py_ID(close); PyUnicode_InternInPlace(&string); string = &_Py_ID(closed); PyUnicode_InternInPlace(&string); + string = &_Py_ID(closefd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(closure); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_argcount); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_cellvars); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_code); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_consts); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_exceptiontable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_filename); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_firstlineno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_flags); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_freevars); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_kwonlyargcount); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_linetable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_names); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_nlocals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_posonlyargcount); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_qualname); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_stacksize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_varnames); + PyUnicode_InternInPlace(&string); string = &_Py_ID(code); PyUnicode_InternInPlace(&string); + string = &_Py_ID(command); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(comment_factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(context); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cookie); + PyUnicode_InternInPlace(&string); string = &_Py_ID(copy); PyUnicode_InternInPlace(&string); string = &_Py_ID(copyreg); PyUnicode_InternInPlace(&string); + string = &_Py_ID(coro); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(count); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cwd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(data); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(database); + PyUnicode_InternInPlace(&string); string = &_Py_ID(decode); PyUnicode_InternInPlace(&string); + string = &_Py_ID(decoder); + PyUnicode_InternInPlace(&string); string = &_Py_ID(default); PyUnicode_InternInPlace(&string); string = &_Py_ID(defaultaction); PyUnicode_InternInPlace(&string); + string = &_Py_ID(delete); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(depth); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(detect_types); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(deterministic); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(device); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dict); + PyUnicode_InternInPlace(&string); string = &_Py_ID(dictcomp); PyUnicode_InternInPlace(&string); string = &_Py_ID(difference_update); PyUnicode_InternInPlace(&string); + string = &_Py_ID(digest); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(digest_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(digestmod); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dir_fd); + PyUnicode_InternInPlace(&string); string = &_Py_ID(dispatch_table); PyUnicode_InternInPlace(&string); string = &_Py_ID(displayhook); PyUnicode_InternInPlace(&string); + string = &_Py_ID(dklen); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(doc); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dont_inherit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dst); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dst_dir_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(duration); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(effective_ids); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(element_factory); + PyUnicode_InternInPlace(&string); string = &_Py_ID(encode); PyUnicode_InternInPlace(&string); string = &_Py_ID(encoding); PyUnicode_InternInPlace(&string); + string = &_Py_ID(end); + PyUnicode_InternInPlace(&string); string = &_Py_ID(end_lineno); PyUnicode_InternInPlace(&string); string = &_Py_ID(end_offset); PyUnicode_InternInPlace(&string); + string = &_Py_ID(endpos); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(env); + PyUnicode_InternInPlace(&string); string = &_Py_ID(errors); PyUnicode_InternInPlace(&string); + string = &_Py_ID(event); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(eventmask); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(exc_type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(exc_value); + PyUnicode_InternInPlace(&string); string = &_Py_ID(excepthook); PyUnicode_InternInPlace(&string); string = &_Py_ID(exception); PyUnicode_InternInPlace(&string); + string = &_Py_ID(exp); + PyUnicode_InternInPlace(&string); string = &_Py_ID(extend); PyUnicode_InternInPlace(&string); + string = &_Py_ID(factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(family); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fanout); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fd2); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fdel); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fget); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(file); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(file_actions); + PyUnicode_InternInPlace(&string); string = &_Py_ID(filename); PyUnicode_InternInPlace(&string); string = &_Py_ID(fileno); PyUnicode_InternInPlace(&string); + string = &_Py_ID(filepath); + PyUnicode_InternInPlace(&string); string = &_Py_ID(fillvalue); PyUnicode_InternInPlace(&string); string = &_Py_ID(filters); PyUnicode_InternInPlace(&string); + string = &_Py_ID(final); + PyUnicode_InternInPlace(&string); string = &_Py_ID(find_class); PyUnicode_InternInPlace(&string); + string = &_Py_ID(fix_imports); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(flags); + PyUnicode_InternInPlace(&string); string = &_Py_ID(flush); PyUnicode_InternInPlace(&string); + string = &_Py_ID(follow_symlinks); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(format); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(frequency); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fromlist); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(func); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(generation); + PyUnicode_InternInPlace(&string); string = &_Py_ID(genexpr); PyUnicode_InternInPlace(&string); string = &_Py_ID(get); @@ -1571,28 +2080,102 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(getstate); PyUnicode_InternInPlace(&string); + string = &_Py_ID(gid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(globals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(groupindex); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(groups); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(handle); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(hash_name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(header); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(headers); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(hi); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(hook); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(id); + PyUnicode_InternInPlace(&string); string = &_Py_ID(ignore); PyUnicode_InternInPlace(&string); + string = &_Py_ID(imag); + PyUnicode_InternInPlace(&string); string = &_Py_ID(importlib); PyUnicode_InternInPlace(&string); + string = &_Py_ID(in_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(incoming); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(indexgroup); + PyUnicode_InternInPlace(&string); string = &_Py_ID(inf); PyUnicode_InternInPlace(&string); + string = &_Py_ID(inheritable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initial); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initial_bytes); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initial_value); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initval); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(inner_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(input); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(insert_comments); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(insert_pis); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(intern); + PyUnicode_InternInPlace(&string); string = &_Py_ID(intersection); PyUnicode_InternInPlace(&string); string = &_Py_ID(isatty); PyUnicode_InternInPlace(&string); string = &_Py_ID(isinstance); PyUnicode_InternInPlace(&string); + string = &_Py_ID(isolation_level); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(istext); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(item); + PyUnicode_InternInPlace(&string); string = &_Py_ID(items); PyUnicode_InternInPlace(&string); string = &_Py_ID(iter); PyUnicode_InternInPlace(&string); + string = &_Py_ID(iterable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(iterations); + PyUnicode_InternInPlace(&string); string = &_Py_ID(join); PyUnicode_InternInPlace(&string); + string = &_Py_ID(jump); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(keepends); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(key); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(keyfile); + PyUnicode_InternInPlace(&string); string = &_Py_ID(keys); PyUnicode_InternInPlace(&string); + string = &_Py_ID(kind); + PyUnicode_InternInPlace(&string); string = &_Py_ID(lambda); PyUnicode_InternInPlace(&string); + string = &_Py_ID(last); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(last_node); + PyUnicode_InternInPlace(&string); string = &_Py_ID(last_traceback); PyUnicode_InternInPlace(&string); string = &_Py_ID(last_type); @@ -1601,30 +2184,76 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(latin1); PyUnicode_InternInPlace(&string); + string = &_Py_ID(leaf_size); + PyUnicode_InternInPlace(&string); string = &_Py_ID(len); PyUnicode_InternInPlace(&string); + string = &_Py_ID(length); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(level); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(limit); + PyUnicode_InternInPlace(&string); string = &_Py_ID(line); PyUnicode_InternInPlace(&string); + string = &_Py_ID(line_buffering); + PyUnicode_InternInPlace(&string); string = &_Py_ID(lineno); PyUnicode_InternInPlace(&string); string = &_Py_ID(listcomp); PyUnicode_InternInPlace(&string); string = &_Py_ID(little); PyUnicode_InternInPlace(&string); + string = &_Py_ID(lo); + PyUnicode_InternInPlace(&string); string = &_Py_ID(locale); PyUnicode_InternInPlace(&string); + string = &_Py_ID(locals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(loop); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mapping); + PyUnicode_InternInPlace(&string); string = &_Py_ID(match); PyUnicode_InternInPlace(&string); + string = &_Py_ID(max_length); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxevents); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxmem); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxsplit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxvalue); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(memLevel); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(memlimit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(message); + PyUnicode_InternInPlace(&string); string = &_Py_ID(metaclass); PyUnicode_InternInPlace(&string); + string = &_Py_ID(method); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mod); + PyUnicode_InternInPlace(&string); string = &_Py_ID(mode); PyUnicode_InternInPlace(&string); + string = &_Py_ID(module); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(module_globals); + PyUnicode_InternInPlace(&string); string = &_Py_ID(modules); PyUnicode_InternInPlace(&string); string = &_Py_ID(mro); PyUnicode_InternInPlace(&string); string = &_Py_ID(msg); PyUnicode_InternInPlace(&string); + string = &_Py_ID(n); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(n_arg); + PyUnicode_InternInPlace(&string); string = &_Py_ID(n_fields); PyUnicode_InternInPlace(&string); string = &_Py_ID(n_sequence_fields); @@ -1633,36 +2262,116 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(name); PyUnicode_InternInPlace(&string); + string = &_Py_ID(namespace_separator); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(namespaces); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(narg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ndigits); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(new_limit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(newline); + PyUnicode_InternInPlace(&string); string = &_Py_ID(newlines); PyUnicode_InternInPlace(&string); string = &_Py_ID(next); PyUnicode_InternInPlace(&string); + string = &_Py_ID(node_depth); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(node_offset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ns); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(number); + PyUnicode_InternInPlace(&string); string = &_Py_ID(obj); PyUnicode_InternInPlace(&string); + string = &_Py_ID(object); + PyUnicode_InternInPlace(&string); string = &_Py_ID(offset); PyUnicode_InternInPlace(&string); + string = &_Py_ID(offset_dst); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(offset_src); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(on_type_read); + PyUnicode_InternInPlace(&string); string = &_Py_ID(onceregistry); PyUnicode_InternInPlace(&string); + string = &_Py_ID(oparg); + PyUnicode_InternInPlace(&string); string = &_Py_ID(opcode); PyUnicode_InternInPlace(&string); string = &_Py_ID(open); PyUnicode_InternInPlace(&string); + string = &_Py_ID(opener); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(operation); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(optimize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(options); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(order); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(out_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(outgoing); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(overlapped); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(owner); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(p); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pages); + PyUnicode_InternInPlace(&string); string = &_Py_ID(parent); PyUnicode_InternInPlace(&string); + string = &_Py_ID(password); + PyUnicode_InternInPlace(&string); string = &_Py_ID(path); PyUnicode_InternInPlace(&string); + string = &_Py_ID(pattern); + PyUnicode_InternInPlace(&string); string = &_Py_ID(peek); PyUnicode_InternInPlace(&string); string = &_Py_ID(persistent_id); PyUnicode_InternInPlace(&string); string = &_Py_ID(persistent_load); PyUnicode_InternInPlace(&string); + string = &_Py_ID(person); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pi_factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(policy); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pos); + PyUnicode_InternInPlace(&string); string = &_Py_ID(print_file_and_line); PyUnicode_InternInPlace(&string); + string = &_Py_ID(priority); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(progress); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(progress_handler); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(proto); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(protocol); + PyUnicode_InternInPlace(&string); string = &_Py_ID(ps1); PyUnicode_InternInPlace(&string); string = &_Py_ID(ps2); PyUnicode_InternInPlace(&string); + string = &_Py_ID(quotetabs); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(r); + PyUnicode_InternInPlace(&string); string = &_Py_ID(raw); PyUnicode_InternInPlace(&string); string = &_Py_ID(read); @@ -1679,67 +2388,225 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(readline); PyUnicode_InternInPlace(&string); + string = &_Py_ID(readonly); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(real); + PyUnicode_InternInPlace(&string); string = &_Py_ID(reducer_override); PyUnicode_InternInPlace(&string); + string = &_Py_ID(registry); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(rel_tol); + PyUnicode_InternInPlace(&string); string = &_Py_ID(reload); PyUnicode_InternInPlace(&string); + string = &_Py_ID(repl); + PyUnicode_InternInPlace(&string); string = &_Py_ID(replace); PyUnicode_InternInPlace(&string); + string = &_Py_ID(reserved); + PyUnicode_InternInPlace(&string); string = &_Py_ID(reset); PyUnicode_InternInPlace(&string); + string = &_Py_ID(resetids); + PyUnicode_InternInPlace(&string); string = &_Py_ID(return); PyUnicode_InternInPlace(&string); + string = &_Py_ID(reverse); + PyUnicode_InternInPlace(&string); string = &_Py_ID(reversed); PyUnicode_InternInPlace(&string); + string = &_Py_ID(s); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(salt); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sched_priority); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(scheduler); + PyUnicode_InternInPlace(&string); string = &_Py_ID(seek); PyUnicode_InternInPlace(&string); string = &_Py_ID(seekable); PyUnicode_InternInPlace(&string); + string = &_Py_ID(selectors); + PyUnicode_InternInPlace(&string); string = &_Py_ID(send); PyUnicode_InternInPlace(&string); + string = &_Py_ID(sep); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sequence); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(server_hostname); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(server_side); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(session); + PyUnicode_InternInPlace(&string); string = &_Py_ID(setcomp); PyUnicode_InternInPlace(&string); + string = &_Py_ID(setpgroup); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setsid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setsigdef); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setsigmask); + PyUnicode_InternInPlace(&string); string = &_Py_ID(setstate); PyUnicode_InternInPlace(&string); - string = &_Py_ID(sort); + string = &_Py_ID(shape); PyUnicode_InternInPlace(&string); - string = &_Py_ID(stderr); + string = &_Py_ID(show_cmd); PyUnicode_InternInPlace(&string); - string = &_Py_ID(stdin); + string = &_Py_ID(signed); PyUnicode_InternInPlace(&string); - string = &_Py_ID(stdout); + string = &_Py_ID(size); PyUnicode_InternInPlace(&string); - string = &_Py_ID(strict); + string = &_Py_ID(sizehint); PyUnicode_InternInPlace(&string); - string = &_Py_ID(symmetric_difference_update); + string = &_Py_ID(sleep); PyUnicode_InternInPlace(&string); - string = &_Py_ID(tell); + string = &_Py_ID(sock); PyUnicode_InternInPlace(&string); - string = &_Py_ID(text); + string = &_Py_ID(sort); PyUnicode_InternInPlace(&string); - string = &_Py_ID(threading); + string = &_Py_ID(sound); PyUnicode_InternInPlace(&string); - string = &_Py_ID(throw); + string = &_Py_ID(source); PyUnicode_InternInPlace(&string); - string = &_Py_ID(top); + string = &_Py_ID(src); PyUnicode_InternInPlace(&string); - string = &_Py_ID(truncate); + string = &_Py_ID(src_dir_fd); PyUnicode_InternInPlace(&string); - string = &_Py_ID(unraisablehook); + string = &_Py_ID(stacklevel); PyUnicode_InternInPlace(&string); - string = &_Py_ID(values); + string = &_Py_ID(start); PyUnicode_InternInPlace(&string); - string = &_Py_ID(version); + string = &_Py_ID(statement); PyUnicode_InternInPlace(&string); - string = &_Py_ID(warnings); + string = &_Py_ID(status); PyUnicode_InternInPlace(&string); - string = &_Py_ID(warnoptions); + string = &_Py_ID(stderr); PyUnicode_InternInPlace(&string); - string = &_Py_ID(writable); + string = &_Py_ID(stdin); PyUnicode_InternInPlace(&string); - string = &_Py_ID(write); + string = &_Py_ID(stdout); PyUnicode_InternInPlace(&string); -} + string = &_Py_ID(step); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(store_name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strategy); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strict); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strict_mode); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(string); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sub_key); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(symmetric_difference_update); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tabsize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tag); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(target); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(target_is_directory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(task); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_frame); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_lasti); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_lineno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_next); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tell); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(template); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(term); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(text); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(threading); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(throw); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(timeout); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(times); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(top); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(trace_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(traceback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(trailers); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(translate); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(truncate); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(twice); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(txt); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tz); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(uid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(unlink); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(unraisablehook); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(uri); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(usedforsecurity); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(value); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(values); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(version); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(warnings); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(warnoptions); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(wbits); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(week); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(weekday); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(which); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(who); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(withdata); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(writable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(write); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(write_through); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(x); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(year); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(zdict); + PyUnicode_InternInPlace(&string); +} #ifdef Py_DEBUG static inline void @@ -4556,6 +5423,10 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(_dealloc_warn)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(_feature_version)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(_feature_version)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(_finalizing)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(_finalizing)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -4612,314 +5483,1050 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(_xoptions)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(add)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(add)); + if (Py_REFCNT((PyObject *)&_Py_ID(a)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(a)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(append)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(append)); + if (Py_REFCNT((PyObject *)&_Py_ID(abs_tol)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(abs_tol)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(big)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(big)); + if (Py_REFCNT((PyObject *)&_Py_ID(access)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(access)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(buffer)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(buffer)); + if (Py_REFCNT((PyObject *)&_Py_ID(add)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(add)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(builtins)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(builtins)); + if (Py_REFCNT((PyObject *)&_Py_ID(after_in_child)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(after_in_child)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(c_call)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(c_call)); + if (Py_REFCNT((PyObject *)&_Py_ID(after_in_parent)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(after_in_parent)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(c_exception)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(c_exception)); + if (Py_REFCNT((PyObject *)&_Py_ID(aggregate_class)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(aggregate_class)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(c_return)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(c_return)); + if (Py_REFCNT((PyObject *)&_Py_ID(append)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(append)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(call)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(call)); + if (Py_REFCNT((PyObject *)&_Py_ID(argdefs)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(argdefs)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(clear)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(clear)); + if (Py_REFCNT((PyObject *)&_Py_ID(arguments)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(arguments)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(close)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(close)); + if (Py_REFCNT((PyObject *)&_Py_ID(argv)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(argv)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(closed)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(closed)); + if (Py_REFCNT((PyObject *)&_Py_ID(attribute)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(attribute)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(code)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(code)); + if (Py_REFCNT((PyObject *)&_Py_ID(authorizer_callback)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(authorizer_callback)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(copy)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(copy)); + if (Py_REFCNT((PyObject *)&_Py_ID(b)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(b)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(copyreg)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(copyreg)); + if (Py_REFCNT((PyObject *)&_Py_ID(backtick)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(backtick)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(decode)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(decode)); + if (Py_REFCNT((PyObject *)&_Py_ID(base)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(base)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(default)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(default)); + if (Py_REFCNT((PyObject *)&_Py_ID(before)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(before)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(defaultaction)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(defaultaction)); + if (Py_REFCNT((PyObject *)&_Py_ID(big)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(big)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(dictcomp)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(dictcomp)); + if (Py_REFCNT((PyObject *)&_Py_ID(binary_form)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(binary_form)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(difference_update)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(difference_update)); + if (Py_REFCNT((PyObject *)&_Py_ID(block)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(block)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(dispatch_table)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(dispatch_table)); + if (Py_REFCNT((PyObject *)&_Py_ID(buffer)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(buffer)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(displayhook)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(displayhook)); + if (Py_REFCNT((PyObject *)&_Py_ID(buffer_callback)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(buffer_callback)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(encode)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(encode)); + if (Py_REFCNT((PyObject *)&_Py_ID(buffer_size)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(buffer_size)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(encoding)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(encoding)); + if (Py_REFCNT((PyObject *)&_Py_ID(buffering)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(buffering)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(end_lineno)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(end_lineno)); + if (Py_REFCNT((PyObject *)&_Py_ID(buffers)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(buffers)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(end_offset)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(end_offset)); + if (Py_REFCNT((PyObject *)&_Py_ID(bufsize)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(bufsize)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(errors)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(errors)); + if (Py_REFCNT((PyObject *)&_Py_ID(builtins)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(builtins)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(excepthook)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(excepthook)); + if (Py_REFCNT((PyObject *)&_Py_ID(byteorder)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(byteorder)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(exception)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(exception)); + if (Py_REFCNT((PyObject *)&_Py_ID(bytes)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(bytes)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(extend)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(extend)); + if (Py_REFCNT((PyObject *)&_Py_ID(bytes_per_sep)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(bytes_per_sep)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(filename)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(filename)); + if (Py_REFCNT((PyObject *)&_Py_ID(c_call)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(c_call)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(fileno)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(fileno)); + if (Py_REFCNT((PyObject *)&_Py_ID(c_exception)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(c_exception)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(fillvalue)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(fillvalue)); + if (Py_REFCNT((PyObject *)&_Py_ID(c_return)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(c_return)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(filters)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(filters)); + if (Py_REFCNT((PyObject *)&_Py_ID(cached_statements)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(cached_statements)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(find_class)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(find_class)); + if (Py_REFCNT((PyObject *)&_Py_ID(cadata)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(cadata)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(flush)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(flush)); + if (Py_REFCNT((PyObject *)&_Py_ID(cafile)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(cafile)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(genexpr)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(genexpr)); + if (Py_REFCNT((PyObject *)&_Py_ID(call)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(call)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(get)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(get)); + if (Py_REFCNT((PyObject *)&_Py_ID(capath)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(capath)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(get_source)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(get_source)); + if (Py_REFCNT((PyObject *)&_Py_ID(category)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(category)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(getattr)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(getattr)); + if (Py_REFCNT((PyObject *)&_Py_ID(cb_type)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(cb_type)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(getstate)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(getstate)); + if (Py_REFCNT((PyObject *)&_Py_ID(certfile)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(certfile)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(ignore)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(ignore)); + if (Py_REFCNT((PyObject *)&_Py_ID(check_same_thread)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(check_same_thread)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(importlib)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(importlib)); + if (Py_REFCNT((PyObject *)&_Py_ID(clear)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(clear)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(inf)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(inf)); + if (Py_REFCNT((PyObject *)&_Py_ID(close)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(close)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(intersection)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(intersection)); + if (Py_REFCNT((PyObject *)&_Py_ID(closed)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(closed)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(isatty)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(isatty)); + if (Py_REFCNT((PyObject *)&_Py_ID(closefd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(closefd)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(isinstance)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(isinstance)); + if (Py_REFCNT((PyObject *)&_Py_ID(closure)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(closure)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(items)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(items)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_argcount)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_argcount)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(iter)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(iter)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_cellvars)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_cellvars)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(join)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(join)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_code)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_code)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(keys)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(keys)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_consts)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_consts)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(lambda)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(lambda)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_exceptiontable)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_exceptiontable)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(last_traceback)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(last_traceback)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_filename)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_filename)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(last_type)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(last_type)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_firstlineno)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_firstlineno)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(last_value)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(last_value)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_flags)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_flags)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(latin1)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(latin1)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_freevars)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_freevars)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(len)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(len)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_kwonlyargcount)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_kwonlyargcount)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(line)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(line)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_linetable)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_linetable)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(lineno)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(lineno)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_name)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_name)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(listcomp)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(listcomp)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_names)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_names)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(little)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(little)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_nlocals)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_nlocals)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(locale)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(locale)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_posonlyargcount)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_posonlyargcount)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(match)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(match)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_qualname)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_qualname)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(metaclass)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(metaclass)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_stacksize)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_stacksize)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(mode)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(mode)); + if (Py_REFCNT((PyObject *)&_Py_ID(co_varnames)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(co_varnames)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(modules)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(modules)); + if (Py_REFCNT((PyObject *)&_Py_ID(code)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(code)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(mro)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(mro)); + if (Py_REFCNT((PyObject *)&_Py_ID(command)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(command)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(msg)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(msg)); + if (Py_REFCNT((PyObject *)&_Py_ID(comment_factory)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(comment_factory)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(n_fields)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(n_fields)); + if (Py_REFCNT((PyObject *)&_Py_ID(context)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(context)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(n_sequence_fields)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(n_sequence_fields)); + if (Py_REFCNT((PyObject *)&_Py_ID(cookie)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(cookie)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(n_unnamed_fields)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(n_unnamed_fields)); + if (Py_REFCNT((PyObject *)&_Py_ID(copy)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(copy)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(name)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(name)); + if (Py_REFCNT((PyObject *)&_Py_ID(copyreg)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(copyreg)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(newlines)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(newlines)); + if (Py_REFCNT((PyObject *)&_Py_ID(coro)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(coro)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(next)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(next)); + if (Py_REFCNT((PyObject *)&_Py_ID(count)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(count)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(obj)) < _PyObject_IMMORTAL_REFCNT) { - _PyObject_Dump((PyObject *)&_Py_ID(obj)); + if (Py_REFCNT((PyObject *)&_Py_ID(cwd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(cwd)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; - if (Py_REFCNT((PyObject *)&_Py_ID(offset)) < _PyObject_IMMORTAL_REFCNT) { + if (Py_REFCNT((PyObject *)&_Py_ID(data)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(data)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(database)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(database)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(decode)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(decode)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(decoder)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(decoder)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(default)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(default)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(defaultaction)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(defaultaction)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(delete)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(delete)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(depth)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(depth)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(detect_types)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(detect_types)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(deterministic)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(deterministic)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(device)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(device)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dict)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dict)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dictcomp)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dictcomp)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(difference_update)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(difference_update)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(digest)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(digest)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(digest_size)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(digest_size)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(digestmod)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(digestmod)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dir_fd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dir_fd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dispatch_table)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dispatch_table)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(displayhook)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(displayhook)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dklen)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dklen)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(doc)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(doc)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dont_inherit)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dont_inherit)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dst)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dst)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(dst_dir_fd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(dst_dir_fd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(duration)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(duration)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(effective_ids)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(effective_ids)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(element_factory)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(element_factory)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(encode)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(encode)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(encoding)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(encoding)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(end)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(end)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(end_lineno)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(end_lineno)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(end_offset)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(end_offset)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(endpos)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(endpos)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(env)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(env)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(errors)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(errors)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(event)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(event)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(eventmask)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(eventmask)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(exc_type)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(exc_type)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(exc_value)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(exc_value)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(excepthook)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(excepthook)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(exception)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(exception)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(exp)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(exp)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(extend)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(extend)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(factory)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(factory)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(family)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(family)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fanout)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fanout)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fd2)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fd2)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fdel)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fdel)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fget)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fget)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(file)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(file)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(file_actions)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(file_actions)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(filename)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(filename)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fileno)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fileno)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(filepath)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(filepath)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fillvalue)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fillvalue)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(filters)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(filters)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(final)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(final)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(find_class)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(find_class)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fix_imports)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fix_imports)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(flags)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(flags)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(flush)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(flush)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(follow_symlinks)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(follow_symlinks)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(format)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(format)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(frequency)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(frequency)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fromlist)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fromlist)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(fset)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(fset)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(func)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(func)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(generation)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(generation)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(genexpr)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(genexpr)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(get)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(get)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(get_source)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(get_source)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(getattr)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(getattr)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(getstate)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(getstate)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(gid)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(gid)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(globals)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(globals)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(groupindex)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(groupindex)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(groups)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(groups)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(handle)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(handle)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(hash_name)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(hash_name)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(header)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(header)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(headers)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(headers)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(hi)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(hi)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(hook)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(hook)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(id)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(id)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(ignore)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(ignore)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(imag)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(imag)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(importlib)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(importlib)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(in_fd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(in_fd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(incoming)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(incoming)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(indexgroup)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(indexgroup)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(inf)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(inf)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(inheritable)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(inheritable)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(initial)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(initial)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(initial_bytes)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(initial_bytes)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(initial_value)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(initial_value)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(initval)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(initval)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(inner_size)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(inner_size)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(input)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(input)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(insert_comments)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(insert_comments)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(insert_pis)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(insert_pis)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(intern)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(intern)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(intersection)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(intersection)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(isatty)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(isatty)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(isinstance)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(isinstance)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(isolation_level)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(isolation_level)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(istext)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(istext)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(item)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(item)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(items)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(items)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(iter)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(iter)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(iterable)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(iterable)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(iterations)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(iterations)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(join)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(join)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(jump)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(jump)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(keepends)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(keepends)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(key)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(key)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(keyfile)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(keyfile)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(keys)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(keys)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(kind)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(kind)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(lambda)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(lambda)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(last)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(last)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(last_node)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(last_node)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(last_traceback)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(last_traceback)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(last_type)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(last_type)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(last_value)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(last_value)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(latin1)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(latin1)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(leaf_size)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(leaf_size)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(len)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(len)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(length)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(length)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(level)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(level)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(limit)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(limit)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(line)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(line)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(line_buffering)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(line_buffering)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(lineno)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(lineno)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(listcomp)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(listcomp)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(little)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(little)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(lo)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(lo)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(locale)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(locale)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(locals)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(locals)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(loop)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(loop)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(mapping)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(mapping)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(match)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(match)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(max_length)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(max_length)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(maxevents)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(maxevents)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(maxmem)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(maxmem)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(maxsplit)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(maxsplit)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(maxvalue)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(maxvalue)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(memLevel)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(memLevel)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(memlimit)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(memlimit)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(message)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(message)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(metaclass)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(metaclass)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(method)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(method)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(mod)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(mod)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(mode)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(mode)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(module)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(module)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(module_globals)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(module_globals)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(modules)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(modules)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(mro)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(mro)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(msg)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(msg)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(n)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(n)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(n_arg)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(n_arg)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(n_fields)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(n_fields)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(n_sequence_fields)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(n_sequence_fields)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(n_unnamed_fields)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(n_unnamed_fields)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(name)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(name)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(namespace_separator)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(namespace_separator)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(namespaces)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(namespaces)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(narg)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(narg)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(ndigits)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(ndigits)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(new_limit)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(new_limit)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(newline)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(newline)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(newlines)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(newlines)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(next)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(next)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(node_depth)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(node_depth)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(node_offset)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(node_offset)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(ns)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(ns)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(number)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(number)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(obj)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(obj)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(object)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(object)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(offset)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(offset)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(offset_dst)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(offset_dst)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(offset_src)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(offset_src)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(on_type_read)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(on_type_read)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(onceregistry)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(onceregistry)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(oparg)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(oparg)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(opcode)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(opcode)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -4928,14 +6535,66 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(open)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(opener)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(opener)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(operation)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(operation)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(optimize)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(optimize)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(options)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(options)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(order)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(order)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(out_fd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(out_fd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(outgoing)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(outgoing)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(overlapped)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(overlapped)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(owner)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(owner)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(p)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(p)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(pages)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(pages)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(parent)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(parent)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(password)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(password)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(path)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(path)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(pattern)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(pattern)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(peek)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(peek)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -4948,10 +6607,50 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(persistent_load)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(person)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(person)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(pi_factory)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(pi_factory)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(pid)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(pid)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(policy)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(policy)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(pos)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(pos)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(print_file_and_line)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(print_file_and_line)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(priority)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(priority)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(progress)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(progress)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(progress_handler)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(progress_handler)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(proto)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(proto)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(protocol)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(protocol)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(ps1)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(ps1)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -4960,6 +6659,14 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(ps2)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(quotetabs)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(quotetabs)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(r)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(r)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(raw)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(raw)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -4992,30 +6699,78 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(readline)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(readonly)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(readonly)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(real)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(real)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(reducer_override)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(reducer_override)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(registry)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(registry)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(rel_tol)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(rel_tol)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(reload)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(reload)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(repl)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(repl)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(replace)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(replace)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(reserved)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(reserved)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(reset)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(reset)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(resetids)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(resetids)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(return)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(return)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(reverse)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(reverse)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(reversed)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(reversed)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(s)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(s)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(salt)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(salt)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(sched_priority)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sched_priority)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(scheduler)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(scheduler)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(seek)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(seek)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -5024,22 +6779,122 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(seekable)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(selectors)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(selectors)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(send)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(send)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(sep)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sep)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(sequence)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sequence)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(server_hostname)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(server_hostname)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(server_side)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(server_side)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(session)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(session)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(setcomp)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(setcomp)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(setpgroup)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(setpgroup)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(setsid)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(setsid)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(setsigdef)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(setsigdef)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(setsigmask)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(setsigmask)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(setstate)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(setstate)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(shape)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(shape)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(show_cmd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(show_cmd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(signed)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(signed)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(size)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(size)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(sizehint)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sizehint)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(sleep)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sleep)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(sock)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sock)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(sort)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(sort)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(sound)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sound)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(source)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(source)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(src)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(src)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(src_dir_fd)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(src_dir_fd)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(stacklevel)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(stacklevel)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(start)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(start)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(statement)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(statement)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(status)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(status)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(stderr)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(stderr)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -5052,18 +6907,86 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(stdout)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(step)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(step)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(store_name)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(store_name)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(strategy)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(strategy)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(strict)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(strict)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(strict_mode)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(strict_mode)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(string)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(string)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(sub_key)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(sub_key)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(symmetric_difference_update)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(symmetric_difference_update)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(tabsize)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tabsize)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(tag)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tag)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(target)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(target)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(target_is_directory)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(target_is_directory)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(task)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(task)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(tb_frame)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tb_frame)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(tb_lasti)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tb_lasti)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(tb_lineno)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tb_lineno)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(tb_next)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tb_next)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(tell)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(tell)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(template)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(template)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(term)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(term)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(text)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(text)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -5076,18 +6999,78 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(throw)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(timeout)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(timeout)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(times)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(times)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(top)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(top)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(trace_callback)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(trace_callback)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(traceback)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(traceback)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(trailers)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(trailers)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(translate)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(translate)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(truncate)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(truncate)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(twice)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(twice)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(txt)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(txt)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(type)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(type)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(tz)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(tz)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(uid)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(uid)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(unlink)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(unlink)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(unraisablehook)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(unraisablehook)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(uri)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(uri)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(usedforsecurity)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(usedforsecurity)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(value)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(value)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(values)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(values)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -5104,6 +7087,30 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(warnoptions)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(wbits)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(wbits)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(week)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(week)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(weekday)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(weekday)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(which)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(which)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(who)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(who)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(withdata)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(withdata)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(writable)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(writable)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -5112,6 +7119,22 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(write)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(write_through)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(write_through)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(x)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(x)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(year)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(year)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; + if (Py_REFCNT((PyObject *)&_Py_ID(zdict)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(zdict)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_SINGLETON(strings).ascii[0]) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_SINGLETON(strings).ascii[0]); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index e981b5a28504..7169a3b0d173 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -1930,8 +1930,41 @@ static PyObject * test_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1950,7 +1983,7 @@ exit: static PyObject * test_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=c03a52cfca192d3b input=0d3484844749c05b]*/ +/*[clinic end generated code: output=81a23d66426e594e input=0d3484844749c05b]*/ /*[clinic input] @@ -1977,8 +2010,41 @@ static PyObject * test_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1997,7 +2063,7 @@ exit: static PyObject * test_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4704adcb6c7df928 input=384adc78bfa0bff7]*/ +/*[clinic end generated code: output=26470df56608cccd input=384adc78bfa0bff7]*/ /*[clinic input] @@ -2025,8 +2091,41 @@ static PyObject * test_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2058,7 +2157,7 @@ exit: static PyObject * test_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=de3ee1039da35fa1 input=eda7964f784f4607]*/ +/*[clinic end generated code: output=3408978bedb2d3f9 input=eda7964f784f4607]*/ /*[clinic input] @@ -2088,8 +2187,41 @@ static PyObject * test_keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_opt_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_opt_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2132,7 +2264,7 @@ exit: static PyObject * test_keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=996394678586854e input=209387a4815e5082]*/ +/*[clinic end generated code: output=becd35b9038b2a64 input=209387a4815e5082]*/ /*[clinic input] @@ -2161,8 +2293,41 @@ static PyObject * test_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2194,7 +2359,7 @@ exit: static PyObject * test_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=4ea9947a903a2f24 input=18393cc64fa000f4]*/ +/*[clinic end generated code: output=f853e626095f43bc input=18393cc64fa000f4]*/ /*[clinic input] @@ -2221,8 +2386,41 @@ static PyObject * test_posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -2241,7 +2439,7 @@ exit: static PyObject * test_posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=478aad346a188a80 input=1767b0ebdf06060e]*/ +/*[clinic end generated code: output=3b097475f4929159 input=1767b0ebdf06060e]*/ /*[clinic input] @@ -2269,8 +2467,41 @@ static PyObject * test_posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *c; @@ -2289,7 +2520,7 @@ exit: static PyObject * test_posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *c) -/*[clinic end generated code: output=d747975a0b28e9c2 input=9042f2818f664839]*/ +/*[clinic end generated code: output=ef7fa0f9e58a0335 input=9042f2818f664839]*/ /*[clinic input] @@ -2319,8 +2550,41 @@ static PyObject * test_posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *a; PyObject *b; @@ -2342,7 +2606,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=5b99f692f8ddaa4a input=29546ebdca492fea]*/ +/*[clinic end generated code: output=0b6617a6d5a560c8 input=29546ebdca492fea]*/ /*[clinic input] @@ -2372,8 +2636,41 @@ static PyObject * test_posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2407,7 +2704,7 @@ exit: static PyObject * test_posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=fd5dfbac5727aebb input=cdf5a9625e554e9b]*/ +/*[clinic end generated code: output=ad36c238a8627f8d input=cdf5a9625e554e9b]*/ /*[clinic input] @@ -2436,8 +2733,41 @@ static PyObject * test_posonly_keywords_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2469,7 +2799,7 @@ exit: static PyObject * test_posonly_keywords_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=777f58ac70775420 input=1581299d21d16f14]*/ +/*[clinic end generated code: output=7abd948bad976638 input=1581299d21d16f14]*/ /*[clinic input] @@ -2499,8 +2829,41 @@ static PyObject * test_posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2539,7 +2902,7 @@ exit: static PyObject * test_posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=2c18b8edff78ed22 input=408798ec3d42949f]*/ +/*[clinic end generated code: output=e702747150ad367d input=408798ec3d42949f]*/ /*[clinic input] @@ -2570,8 +2933,41 @@ static PyObject * test_posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2605,7 +3001,7 @@ exit: static PyObject * test_posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=8db9ab5602e1efaf input=8d8e5643bbbc2309]*/ +/*[clinic end generated code: output=79deca12adfac6a3 input=8d8e5643bbbc2309]*/ /*[clinic input] @@ -2635,8 +3031,41 @@ static PyObject * test_posonly_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2668,7 +3097,7 @@ exit: static PyObject * test_posonly_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=6cfe546265d85d2c input=f7e5eed94f75fff0]*/ +/*[clinic end generated code: output=997d180f3d1c69c5 input=f7e5eed94f75fff0]*/ /*[clinic input] @@ -2699,8 +3128,41 @@ static PyObject * test_posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2739,7 +3201,7 @@ exit: static PyObject * test_posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=8b5e21a30cad22b7 input=1e557dc979d120fd]*/ +/*[clinic end generated code: output=0c9000c9f87ab430 input=1e557dc979d120fd]*/ /*[clinic input] @@ -2772,8 +3234,41 @@ static PyObject * test_posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *a; @@ -2810,7 +3305,7 @@ static PyObject * test_posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=950b9ace38b8b4a7 input=c3884a4f956fdc89]*/ +/*[clinic end generated code: output=6a5eaed3c057fda5 input=c3884a4f956fdc89]*/ /*[clinic input] @@ -2841,8 +3336,41 @@ static PyObject * test_posonly_keywords_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2876,7 +3404,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=fb6951a21b517317 input=68d01d7c0f6dafb0]*/ +/*[clinic end generated code: output=033e6cfc772d4fc2 input=68d01d7c0f6dafb0]*/ /*[clinic input] @@ -2910,8 +3438,41 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2957,7 +3518,7 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=4db10815a99a857e input=d0883d45876f186c]*/ +/*[clinic end generated code: output=5d3e7607d3d814e7 input=d0883d45876f186c]*/ /*[clinic input] @@ -2991,8 +3552,41 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt2_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt2_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3043,7 +3637,7 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=0416689b23ebf66e input=c95e2e1ec93035ad]*/ +/*[clinic end generated code: output=ed0301cc659624fe input=c95e2e1ec93035ad]*/ /*[clinic input] @@ -3079,8 +3673,41 @@ static PyObject * test_posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "c", "d", "e", "f", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3139,7 +3766,7 @@ test_posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e, PyObject *f) -/*[clinic end generated code: output=8892a137a8c8f46f input=9914857713c5bbf8]*/ +/*[clinic end generated code: output=352bbf976ebdd729 input=9914857713c5bbf8]*/ /*[clinic input] test_keyword_only_parameter @@ -3165,8 +3792,41 @@ static PyObject * test_keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_lnotab), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"co_lnotab", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keyword_only_parameter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keyword_only_parameter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab; @@ -3192,7 +3852,7 @@ exit: static PyObject * test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab) -/*[clinic end generated code: output=332b5f4b444c5d55 input=303df5046c7e37a3]*/ +/*[clinic end generated code: output=a1c32e78f625dce1 input=303df5046c7e37a3]*/ /*[clinic input] @@ -3370,8 +4030,41 @@ static PyObject * test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3392,7 +4085,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=a2baf8c1fade41d2 input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=ac4d536e5b76c9fa input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -3420,8 +4113,41 @@ static PyObject * test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_default", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg_with_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3452,7 +4178,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=3821d282c29f8616 input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=f0c70f7e2e1c0523 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults @@ -3480,8 +4206,41 @@ static PyObject * test_vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_only_defaults", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg_with_only_defaults", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -3517,7 +4276,7 @@ exit: static PyObject * test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b, PyObject *c) -/*[clinic end generated code: output=7e393689e6ce61a3 input=fa56a709a035666e]*/ +/*[clinic end generated code: output=0a918b65f7b076f9 input=fa56a709a035666e]*/ /*[clinic input] test_paramname_module @@ -3540,8 +4299,41 @@ static PyObject * test_paramname_module(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(module), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"module", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_paramname_module", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_paramname_module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *mod; @@ -3558,4 +4350,4 @@ exit: static PyObject * test_paramname_module_impl(PyObject *module, PyObject *mod) -/*[clinic end generated code: output=23379a7ffa65c514 input=afefe259667f13ba]*/ +/*[clinic end generated code: output=28b032fb28df75cd input=afefe259667f13ba]*/ diff --git a/Makefile.pre.in b/Makefile.pre.in index 79616160e495..c647853c2238 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -690,6 +690,7 @@ coverage-report: regen-token regen-frozen .PHONY=clinic clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py # Build the interpreter $(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 4e74e0885cf2..7e07f60036b7 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_blake2b_new__doc__, "blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" " key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" @@ -22,8 +28,41 @@ static PyObject * py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 12 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blake2b", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blake2b", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -247,4 +286,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=10eb47aba77f192d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6daedbc1dba8c284 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index 0f0d9835fbfe..ee746d417d48 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_blake2s_new__doc__, "blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" " key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" @@ -22,8 +28,41 @@ static PyObject * py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 12 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blake2s", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blake2s", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -247,4 +286,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=f7ee8092ed67e9c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1b0381231f840d4d input=a9049054013a1b77]*/ diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 50afc097b350..8a0df4266e83 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -42,6 +42,7 @@ module _codecs [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ +#include "pycore_runtime.h" #include "clinic/_codecsmodule.c.h" /* --- Registry ----------------------------------------------------------- */ diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 0249dd184b1d..470b0cb08e9c 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_open__doc__, "open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" " errors=None, newline=None, closefd=True, opener=None)\n" @@ -133,8 +139,41 @@ static PyObject * _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 8 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(buffering), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[8]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; @@ -333,8 +372,41 @@ static PyObject * _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open_code", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open_code", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -355,4 +427,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=c4d7e4ef878985f8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea13625ef5c1c5ef input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 3700451232c1..bfd07e49b733 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, "readinto($self, buffer, /)\n" "--\n" @@ -402,8 +408,41 @@ static int _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedReader", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedReader", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -456,8 +495,41 @@ static int _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedWriter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedWriter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -603,8 +675,41 @@ static int _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedRandom", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedRandom", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -638,4 +743,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=820461c6b0e29e48 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=40ab0d3319282df2 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 049d3473110f..27e0f313682b 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_BytesIO_readable__doc__, "readable($self, /)\n" "--\n" @@ -483,8 +489,41 @@ static int _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial_bytes), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"initial_bytes", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BytesIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BytesIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -505,4 +544,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=93d9700a6cf395b8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a43adab5280d645c input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index bb0b36c8502a..1695385c86e4 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_FileIO_close__doc__, "close($self, /)\n" "--\n" @@ -49,8 +55,41 @@ static int _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "FileIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "FileIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -437,4 +476,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ -/*[clinic end generated code: output=fdcf0f9277d44415 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fa61bf880de0de90 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index ed3fdc9bb122..01c035dad264 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io__IOBase_tell__doc__, "tell($self, /)\n" "--\n" @@ -310,4 +316,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=0362e134da2d8641 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7246a2087eb966b input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index 6758ee05f910..d853cf4312a5 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_StringIO_getvalue__doc__, "getvalue($self, /)\n" "--\n" @@ -255,8 +261,41 @@ static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial_value), &_Py_ID(newline), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"initial_value", "newline", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "StringIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "StringIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -338,4 +377,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=3207dc548c305ad8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b1bde306e2928b19 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 907785b2beaf..c9b25124dcb4 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_IncrementalNewlineDecoder___init____doc__, "IncrementalNewlineDecoder(decoder, translate, errors=\'strict\')\n" "--\n" @@ -24,8 +30,41 @@ static int _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(decoder), &_Py_ID(translate), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "IncrementalNewlineDecoder", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "IncrementalNewlineDecoder", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -70,8 +109,41 @@ static PyObject * _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -182,8 +254,41 @@ static int _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 6 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TextIOWrapper", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TextIOWrapper", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -297,8 +402,41 @@ static PyObject * _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "reconfigure", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "reconfigure", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *encoding = Py_None; @@ -671,4 +809,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=bb78b568b24759d6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=29563d0807382d7a input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index 75102a3d3715..5808a60b6a8e 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, @@ -48,8 +54,41 @@ static int _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_WindowsConsoleIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_WindowsConsoleIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -378,4 +417,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ -/*[clinic end generated code: output=2d8648fab31ec60e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=440125d1e2745fff input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/multiprocessing.c.h b/Modules/_multiprocessing/clinic/multiprocessing.c.h index 3a3083390479..885cd5c2fff8 100644 --- a/Modules/_multiprocessing/clinic/multiprocessing.c.h +++ b/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_closesocket__doc__, @@ -166,4 +172,4 @@ _multiprocessing_sem_unlink(PyObject *module, PyObject *arg) #ifndef _MULTIPROCESSING_SEND_METHODDEF #define _MULTIPROCESSING_SEND_METHODDEF #endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ -/*[clinic end generated code: output=ab64ce752f933c55 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4a6afc67c1f5ec85 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index be21f836b955..9894af4c561a 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_SHM_OPEN) PyDoc_STRVAR(_posixshmem_shm_open__doc__, @@ -21,8 +27,41 @@ static PyObject * _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "flags", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "shm_open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *path; @@ -88,8 +127,41 @@ static PyObject * _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "shm_unlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -120,4 +192,4 @@ _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs #ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF #define _POSIXSHMEM_SHM_UNLINK_METHODDEF #endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ -/*[clinic end generated code: output=a6db931a47d36e1b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4c889c75d55353a6 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h index adb47476c018..28c9d4a8fb2f 100644 --- a/Modules/_multiprocessing/clinic/semaphore.c.h +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, @@ -21,8 +27,41 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int blocking = 1; @@ -95,8 +134,41 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int blocking = 1; @@ -160,8 +232,41 @@ static PyObject * _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(kind), &_Py_ID(value), &_Py_ID(maxvalue), &_Py_ID(name), &_Py_ID(unlink), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "SemLock", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "SemLock", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -467,4 +572,4 @@ _multiprocessing_SemLock___exit__(SemLockObject *self, PyObject *const *args, Py #ifndef _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #endif /* !defined(_MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF) */ -/*[clinic end generated code: output=64ba32544811c9e6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7eaf752dcfef6204 input=a9049054013a1b77]*/ diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index d96c0371ec7f..95f1e505dd18 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -72,6 +72,7 @@ #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_runtime.h" #ifdef HAVE_PROCESS_H # include <process.h> // getpid() #endif diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/_sha3/clinic/sha3module.c.h index 1c79c269391c..b53a244a230c 100644 --- a/Modules/_sha3/clinic/sha3module.c.h +++ b/Modules/_sha3/clinic/sha3module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_sha3_new__doc__, "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n" "--\n" @@ -15,8 +21,41 @@ static PyObject * py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha3_224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha3_224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -164,4 +203,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=c8a97b34e80def62 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f601d854411f9bea input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h index b467c99e2eb5..f3d8a35be461 100644 --- a/Modules/_sqlite/clinic/blob.c.h +++ b/Modules/_sqlite/clinic/blob.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(blob_close__doc__, "close($self, /)\n" "--\n" @@ -213,4 +219,4 @@ blob_exit(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=382cbf0977bb158a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ad6a402f70e85977 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 62d31b787ad7..066675d49630 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, double timeout, int detect_types, @@ -13,8 +19,41 @@ static int pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 8 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(database), &_Py_ID(timeout), &_Py_ID(detect_types), &_Py_ID(isolation_level), &_Py_ID(check_same_thread), &_Py_ID(factory), &_Py_ID(cached_statements), &_Py_ID(uri), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Connection", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Connection", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[8]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -119,8 +158,41 @@ static PyObject * pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(factory), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"factory", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cursor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *factory = NULL; @@ -168,8 +240,41 @@ static PyObject * blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(readonly), &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "", "readonly", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blobopen", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blobopen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; const char *table; @@ -323,8 +428,41 @@ static PyObject * pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(narg), &_Py_ID(func), &_Py_ID(deterministic), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", "narg", "func", "deterministic", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; const char *name; @@ -397,8 +535,41 @@ static PyObject * create_window_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_window_function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_window_function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; const char *name; int num_params; @@ -453,8 +624,41 @@ static PyObject * pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(n_arg), &_Py_ID(aggregate_class), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", "n_arg", "aggregate_class", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_aggregate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_aggregate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; const char *name; int n_arg; @@ -506,8 +710,41 @@ static PyObject * pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(authorizer_callback), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"authorizer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_authorizer", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_authorizer", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *callable; @@ -540,8 +777,41 @@ static PyObject * pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(progress_handler), &_Py_ID(n), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"progress_handler", "n", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_progress_handler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_progress_handler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *callable; int n; @@ -579,8 +849,41 @@ static PyObject * pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(trace_callback), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"trace_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_trace_callback", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_trace_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *callable; @@ -815,8 +1118,41 @@ static PyObject * pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(target), &_Py_ID(pages), &_Py_ID(progress), &_Py_ID(name), &_Py_ID(sleep), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "backup", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; pysqlite_Connection *target; @@ -906,8 +1242,41 @@ static PyObject * pysqlite_connection_create_collation(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_collation", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_collation", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; const char *name; PyObject *callable; @@ -962,8 +1331,41 @@ static PyObject * serialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "serialize", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "serialize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *name = "main"; @@ -1028,8 +1430,41 @@ static PyObject * deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "deserialize", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "deserialize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -1237,4 +1672,4 @@ getlimit(pysqlite_Connection *self, PyObject *arg) #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=8818c1c3ec9425aa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e6873a956553d806 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index b29c33307488..d01abb856794 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int pysqlite_cursor_init_impl(pysqlite_Cursor *self, pysqlite_Connection *connection); @@ -186,8 +192,41 @@ static PyObject * pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(size), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fetchmany", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int maxrows = self->arraysize; @@ -289,4 +328,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=2b9c6a3ca8a8caff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=13c24313ce3a0fec input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index 3e932a6117eb..0137918a48ad 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" "--\n" @@ -18,8 +24,41 @@ static PyObject * pysqlite_complete_statement(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(statement), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"statement", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complete_statement", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complete_statement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *statement; @@ -182,4 +221,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=d7f142e9a7a80468 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4b5c237e3cf49908 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h index c936ef75fdea..c543b398db3f 100644 --- a/Modules/_sqlite/clinic/row.c.h +++ b/Modules/_sqlite/clinic/row.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, PyObject *data); @@ -54,4 +60,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_row_keys_impl(self); } -/*[clinic end generated code: output=9d54919dbb4ba5f1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=87b91f234633702e input=a9049054013a1b77]*/ diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index 048a494f1bc7..dc5c6c132151 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_sre_getcodesize__doc__, "getcodesize($module, /)\n" "--\n" @@ -175,8 +181,41 @@ static PyObject * _sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "match", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "match", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -245,8 +284,41 @@ static PyObject * _sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fullmatch", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fullmatch", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -317,8 +389,41 @@ static PyObject * _sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "search", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "search", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -386,8 +491,41 @@ static PyObject * _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findall", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -458,8 +596,41 @@ static PyObject * _sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "finditer", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "finditer", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -527,8 +698,41 @@ static PyObject * _sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scanner", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scanner", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -596,8 +800,41 @@ static PyObject * _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -647,8 +884,41 @@ static PyObject * _sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sub", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sub", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; @@ -701,8 +971,41 @@ static PyObject * _sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "subn", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "subn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; @@ -780,8 +1083,41 @@ static PyObject * _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 6 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pattern), &_Py_ID(flags), &_Py_ID(code), &_Py_ID(groups), &_Py_ID(groupindex), &_Py_ID(indexgroup), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; PyObject *pattern; int flags; @@ -848,8 +1184,41 @@ static PyObject * _sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(template), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"template", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expand", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expand", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *template; @@ -883,8 +1252,41 @@ static PyObject * _sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(default), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groups", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groups", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *default_value = Py_None; @@ -923,8 +1325,41 @@ static PyObject * _sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(default), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groupdict", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groupdict", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *default_value = Py_None; @@ -1116,4 +1551,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const } return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=fd2f45c941620e6e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d686111c67a7d0aa input=a9049054013a1b77]*/ diff --git a/Modules/_ssl/clinic/cert.c.h b/Modules/_ssl/clinic/cert.c.h index 53cedabc3f7b..e90aa137503a 100644 --- a/Modules/_ssl/clinic/cert.c.h +++ b/Modules/_ssl/clinic/cert.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_ssl_Certificate_public_bytes__doc__, "public_bytes($self, /, format=Encoding.PEM)\n" "--\n" @@ -17,8 +23,41 @@ static PyObject * _ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"format", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "public_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "public_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int format = PY_SSL_ENCODING_PEM; @@ -57,4 +96,4 @@ _ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) { return _ssl_Certificate_get_info_impl(self); } -/*[clinic end generated code: output=18885c4d167d5244 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39d0c03e76b5f361 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/vectorcall.c.h b/Modules/_testcapi/clinic/vectorcall.c.h index 14cdf23304be..765afeda9b30 100644 --- a/Modules/_testcapi/clinic/vectorcall.c.h +++ b/Modules/_testcapi/clinic/vectorcall.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_testcapi_VectorCallClass_set_vectorcall__doc__, "set_vectorcall($self, type, /)\n" "--\n" @@ -104,4 +110,4 @@ _testcapi_has_vectorcall_flag(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=cf39927be151aebd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=609569aa9942584f input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 8f850aa8195c..d251bdba1d5d 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, "encode($self, /, input, errors=None)\n" "--\n" @@ -25,8 +31,41 @@ static PyObject * _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"input", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -88,8 +127,41 @@ static PyObject * _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"input", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer input = {NULL, NULL}; @@ -156,8 +228,41 @@ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -262,8 +367,41 @@ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer input = {NULL, NULL}; @@ -492,8 +630,41 @@ static PyObject * _multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "write", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *strobj; @@ -525,8 +696,41 @@ static PyObject * _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "writelines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "writelines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *lines; @@ -570,4 +774,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=9e4e3da5ca3c8288 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1e596a9dfd1c97cd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_abc.c.h b/Modules/clinic/_abc.c.h index 8d3832e1b83d..2adec818c913 100644 --- a/Modules/clinic/_abc.c.h +++ b/Modules/clinic/_abc.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_abc__reset_registry__doc__, "_reset_registry($module, self, /)\n" "--\n" @@ -159,4 +165,4 @@ _abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _abc_get_cache_token_impl(module); } -/*[clinic end generated code: output=babb3ce445fa9b21 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c2e69611a495c98d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index add6bb2e08b5..7428fc20dc27 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_asyncio_Future___init____doc__, "Future(*, loop=None)\n" "--\n" @@ -26,8 +32,41 @@ static int _asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"loop", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Future", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Future", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -139,8 +178,41 @@ static PyObject * _asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(context), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "context", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "add_done_callback", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "add_done_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *fn; @@ -193,8 +265,41 @@ static PyObject * _asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cancel", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *msg = Py_None; @@ -306,8 +411,41 @@ static int _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(coro), &_Py_ID(loop), &_Py_ID(name), &_Py_ID(context), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"coro", "loop", "name", "context", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -401,8 +539,41 @@ static PyObject * _asyncio_Task_cancel(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cancel", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *msg = Py_None; @@ -500,8 +671,41 @@ static PyObject * _asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(limit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"limit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_stack", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_stack", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *limit = Py_None; @@ -544,8 +748,41 @@ static PyObject * _asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(limit), &_Py_ID(file), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"limit", "file", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "print_stack", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "print_stack", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *limit = Py_None; @@ -703,8 +940,41 @@ static PyObject * _asyncio__get_event_loop(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(stacklevel), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"stacklevel", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_get_event_loop", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_get_event_loop", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int stacklevel = 3; @@ -765,8 +1035,41 @@ static PyObject * _asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_register_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_register_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *task; @@ -799,8 +1102,41 @@ static PyObject * _asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_unregister_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_unregister_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *task; @@ -835,8 +1171,41 @@ static PyObject * _asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"loop", "task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_enter_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_enter_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *loop; PyObject *task; @@ -873,8 +1242,41 @@ static PyObject * _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"loop", "task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_leave_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_leave_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *loop; PyObject *task; @@ -890,4 +1292,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=b4e678c915567934 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f923801842642bd9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h index 2f0a3575cc5c..667ed478eea4 100644 --- a/Modules/clinic/_bisectmodule.c.h +++ b/Modules/clinic/_bisectmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_bisect_bisect_right__doc__, "bisect_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" @@ -26,8 +32,41 @@ static PyObject * _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bisect_right", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bisect_right", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -109,8 +148,41 @@ static PyObject * _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "insort_right", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "insort_right", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -189,8 +261,41 @@ static PyObject * _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bisect_left", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bisect_left", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -272,8 +377,41 @@ static PyObject * _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "insort_left", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "insort_left", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -327,4 +465,4 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=ee8c32ff8d3d1fac input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8028ae01b2fd14b6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 3ed72f8bceb1..178cae88f38e 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, "compress($self, data, /)\n" "--\n" @@ -95,8 +101,41 @@ static PyObject * _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -139,4 +178,4 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py return return_value; } -/*[clinic end generated code: output=a1175204a414fe2a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fe780ceebc3d3826 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 29e9d5ea86aa..be8b11a47c53 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_codecs_register__doc__, "register($module, search_function, /)\n" "--\n" @@ -86,8 +92,41 @@ static PyObject * _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -163,8 +202,41 @@ static PyObject * _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -2817,4 +2889,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=92250568c3a6f0a0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=58003a0c706e89c2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index e53acd6afb44..ad4da8856ac3 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_collections__count_elements__doc__, "_count_elements($module, mapping, iterable, /)\n" "--\n" @@ -69,4 +75,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=36b0948c4676c831 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12168d58a11a4fb9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_contextvarsmodule.c.h b/Modules/clinic/_contextvarsmodule.c.h index b1885e41c355..461d4845635e 100644 --- a/Modules/clinic/_contextvarsmodule.c.h +++ b/Modules/clinic/_contextvarsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_contextvars_copy_context__doc__, "copy_context($module, /)\n" "--\n" @@ -18,4 +24,4 @@ _contextvars_copy_context(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _contextvars_copy_context_impl(module); } -/*[clinic end generated code: output=26e07024451baf52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1736c27450823e70 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h index 401d04623e43..97b70b3c17e9 100644 --- a/Modules/clinic/_cryptmodule.c.h +++ b/Modules/clinic/_cryptmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(crypt_crypt__doc__, "crypt($module, word, salt, /)\n" "--\n" @@ -60,4 +66,4 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=6f61ab29e361f9d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=235ccef9211184f4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_csv.c.h b/Modules/clinic/_csv.c.h index ae5dec74a173..c035c44ebdee 100644 --- a/Modules/clinic/_csv.c.h +++ b/Modules/clinic/_csv.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_csv_list_dialects__doc__, "list_dialects($module, /)\n" "--\n" @@ -40,8 +46,41 @@ static PyObject * _csv_unregister_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unregister_dialect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unregister_dialect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -74,8 +113,41 @@ static PyObject * _csv_get_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_dialect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_dialect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -111,8 +183,41 @@ static PyObject * _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(new_limit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"new_limit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "field_size_limit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "field_size_limit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *new_limit = NULL; @@ -131,4 +236,4 @@ _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=6235abc491b02188 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=46fe87be9980e02e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index 31101c1011cc..c5e9c2e5675d 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "bottom($self, /)\n" "--\n" @@ -163,8 +169,41 @@ static PyObject * _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "move", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int y; int x; @@ -223,8 +262,41 @@ static PyObject * _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyCursesWindowObject *win; @@ -260,8 +332,41 @@ static PyObject * _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_userptr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_userptr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *obj; @@ -383,4 +488,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=c471aed62bc31e79 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4bbea7cfaaf3982 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index c7d1eca6559b..715b9c35d2d4 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_curses_window_addch__doc__, "addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" "Paint the character.\n" @@ -2678,8 +2684,41 @@ static PyObject * _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(term), &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"term", "fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setupterm", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setupterm", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *term = NULL; @@ -4284,4 +4323,4 @@ _curses_has_extended_color_support(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=1e2a8a160a0fe811 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=048542c478241231 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 31d2f75f7a86..955e5fe8eafe 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, "fromtimestamp($type, timestamp, /)\n" "--\n" @@ -22,8 +28,41 @@ static PyObject * iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(year), &_Py_ID(week), &_Py_ID(weekday), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"year", "week", "weekday", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "IsoCalendarDate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "IsoCalendarDate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -74,8 +113,41 @@ static PyObject * datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tz), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"tz", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "now", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "now", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *tz = Py_None; @@ -94,4 +166,4 @@ datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=1a3da7479e443e17 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=faf7b2ab25ab94b9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index 8157716a9408..e368378e6b87 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_dbm_dbm_close__doc__, "close($self, /)\n" "--\n" @@ -59,8 +65,41 @@ static PyObject * _dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"s#|O:get", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#|O:get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; PyObject *default_value = Py_None; @@ -94,8 +133,41 @@ static PyObject * _dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"s#|O:setdefault", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#|O:setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; PyObject *default_value = NULL; @@ -172,4 +244,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=5798278a05032d0e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a2232bc0c1994f03 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 047203eefa35..9afe2af7593a 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_elementtree_Element_append__doc__, "append($self, subelement, /)\n" "--\n" @@ -168,8 +174,41 @@ static PyObject * _elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "find", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -208,8 +247,41 @@ static PyObject * _elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(default), &_Py_ID(namespaces), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findtext", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findtext", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -254,8 +326,41 @@ static PyObject * _elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findall", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -293,8 +398,41 @@ static PyObject * _elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "iterfind", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "iterfind", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -332,8 +470,41 @@ static PyObject * _elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -370,8 +541,41 @@ static PyObject * _elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tag), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"tag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "iter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "iter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *tag = Py_None; @@ -590,8 +794,41 @@ static int _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(element_factory), &_Py_ID(comment_factory), &_Py_ID(pi_factory), &_Py_ID(insert_comments), &_Py_ID(insert_pis), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"element_factory", "comment_factory", "pi_factory", "insert_comments", "insert_pis", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TreeBuilder", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TreeBuilder", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -801,8 +1038,41 @@ static int _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(target), &_Py_ID(encoding), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"target", "encoding", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "XMLParser", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "XMLParser", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -915,4 +1185,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=3fd6fa2ce1aeca76 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=62ed1bab17b4297a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index e4cb1e9477f3..ca1bfde1d2d6 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_gdbm_gdbm_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -162,8 +168,41 @@ static PyObject * _gdbm_gdbm_nextkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"s#:nextkey", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#:nextkey", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; @@ -305,4 +344,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=617117d16956ac4d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=72d3e46432e2d324 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index 5d84f4ac4e55..67532787e996 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(EVP_copy__doc__, "copy($self, /)\n" "--\n" @@ -83,8 +89,41 @@ static PyObject * EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "digest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "digest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length; @@ -130,8 +169,41 @@ static PyObject * EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hexdigest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hexdigest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length; @@ -181,8 +253,41 @@ static PyObject * EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", "string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "new", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "new", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name_obj; @@ -235,8 +340,41 @@ static PyObject * _hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_md5", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -287,8 +425,41 @@ static PyObject * _hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -339,8 +510,41 @@ static PyObject * _hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -391,8 +595,41 @@ static PyObject * _hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -443,8 +680,41 @@ static PyObject * _hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -495,8 +765,41 @@ static PyObject * _hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -549,8 +852,41 @@ static PyObject * _hashlib_openssl_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -605,8 +941,41 @@ static PyObject * _hashlib_openssl_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -661,8 +1030,41 @@ static PyObject * _hashlib_openssl_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -717,8 +1119,41 @@ static PyObject * _hashlib_openssl_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -773,8 +1208,41 @@ static PyObject * _hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_128", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_shake_128", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -829,8 +1297,41 @@ static PyObject * _hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_shake_256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -885,8 +1386,41 @@ static PyObject * pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(hash_name), &_Py_ID(password), &_Py_ID(salt), &_Py_ID(iterations), &_Py_ID(dklen), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"hash_name", "password", "salt", "iterations", "dklen", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pbkdf2_hmac", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pbkdf2_hmac", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; const char *hash_name; @@ -971,8 +1505,41 @@ static PyObject * _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 7 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(password), &_Py_ID(salt), &_Py_ID(n), &_Py_ID(r), &_Py_ID(p), &_Py_ID(maxmem), &_Py_ID(dklen), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scrypt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scrypt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer password = {NULL, NULL}; @@ -1087,8 +1654,41 @@ static PyObject * _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digest), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "msg", "digest", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hmac_digest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hmac_digest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_buffer key = {NULL, NULL}; Py_buffer msg = {NULL, NULL}; @@ -1145,8 +1745,41 @@ static PyObject * _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digestmod), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "msg", "digestmod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hmac_new", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hmac_new", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer key = {NULL, NULL}; @@ -1220,8 +1853,41 @@ static PyObject * _hashlib_HMAC_update(HMACobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "update", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "update", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *msg; @@ -1385,4 +2051,4 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=69f2374071bff707 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c1bb9faad2b6b57 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_heapqmodule.c.h b/Modules/clinic/_heapqmodule.c.h index 8d73b5b48d6a..3ee3f51702fa 100644 --- a/Modules/clinic/_heapqmodule.c.h +++ b/Modules/clinic/_heapqmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_heapq_heappush__doc__, "heappush($module, heap, item, /)\n" "--\n" @@ -265,4 +271,4 @@ _heapq__heapify_max(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9a22715a8bf0c91d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=29e99a48c57f82bb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_localemodule.c.h b/Modules/clinic/_localemodule.c.h index 069426357394..e6b99962d15f 100644 --- a/Modules/clinic/_localemodule.c.h +++ b/Modules/clinic/_localemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_locale_setlocale__doc__, "setlocale($module, category, locale=<unrepresentable>, /)\n" "--\n" @@ -602,4 +608,4 @@ _locale_getencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif /* !defined(_LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF) */ -/*[clinic end generated code: output=cfde12e987960245 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=406842c3441559cb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index dfc003eb5477..5fcc7ae02e3b 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, "getstats($self, /)\n" "--\n" @@ -45,4 +51,4 @@ _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *con } return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=0615a53cce828f06 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7425d3481349629a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index d98af74b4aac..8fce25686afd 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, "compress($self, data, /)\n" "--\n" @@ -95,8 +101,41 @@ static PyObject * _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -171,8 +210,41 @@ static int _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(memlimit), &_Py_ID(filters), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "LZMADecompressor", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "LZMADecompressor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -286,4 +358,4 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz return return_value; } -/*[clinic end generated code: output=bce20bac13b0f252 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2713a1ba282060d3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index d7e96a95c084..1844d7000529 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_opcode_stack_effect__doc__, "stack_effect($module, opcode, oparg=None, /, *, jump=None)\n" "--\n" @@ -19,8 +25,41 @@ static PyObject * _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(jump), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "jump", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stack_effect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stack_effect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; int opcode; @@ -74,4 +113,4 @@ _opcode_get_specialization_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _opcode_get_specialization_stats_impl(module); } -/*[clinic end generated code: output=b904260bf022f953 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=99bf9024ab436fa3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_operator.c.h b/Modules/clinic/_operator.c.h index 3b5be7bf2c07..b68e6e0144a5 100644 --- a/Modules/clinic/_operator.c.h +++ b/Modules/clinic/_operator.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_operator_truth__doc__, "truth($module, a, /)\n" "--\n" @@ -1486,4 +1492,4 @@ _operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=44164c4fbd67e5c5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=227cbcfed44f736e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 5dc62fe19017..a9bb84377df8 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, "clear_memo($self, /)\n" "--\n" @@ -106,8 +112,41 @@ static int _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Pickler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Pickler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -326,8 +365,41 @@ static int _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Unpickler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Unpickler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -497,8 +569,41 @@ static PyObject * _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dump", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dump", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *obj; @@ -578,8 +683,41 @@ static PyObject * _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"obj", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dumps", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dumps", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -663,8 +801,41 @@ static PyObject * _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; @@ -766,8 +937,41 @@ static PyObject * _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "loads", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "loads", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *data; @@ -836,4 +1040,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=1bb1ead3c828e108 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fecab7d905b02139 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index b0b00f8199b5..c2f0d6ed86bd 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" "--\n" @@ -52,8 +58,41 @@ static PyObject * _queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(item), &_Py_ID(block), &_Py_ID(timeout), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"item", "block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "put", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "put", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *item; @@ -104,8 +143,41 @@ static PyObject * _queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(item), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"item", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "put_nowait", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "put_nowait", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *item; @@ -145,8 +217,41 @@ static PyObject * _queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int block = 1; @@ -257,4 +362,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=88ec8033aeb7241c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=def30d57235bc720 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_randommodule.c.h b/Modules/clinic/_randommodule.c.h index 503c1f93ed81..ec8531ce0066 100644 --- a/Modules/clinic/_randommodule.c.h +++ b/Modules/clinic/_randommodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_random_Random_random__doc__, "random($self, /)\n" "--\n" @@ -109,4 +115,4 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=d144826cde89e605 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bc17406a886824fc input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 24604dd43687..819c7ee878ff 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, "do_handshake($self, /)\n" "--\n" @@ -348,8 +354,41 @@ static PyObject * _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cb_type), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"cb_type", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_channel_binding", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_channel_binding", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *cb_type = "tls-unique"; @@ -531,8 +570,41 @@ static PyObject * _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(certfile), &_Py_ID(keyfile), &_Py_ID(password), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load_cert_chain", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_cert_chain", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *certfile; @@ -579,8 +651,41 @@ static PyObject * _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cafile), &_Py_ID(capath), &_Py_ID(cadata), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load_verify_locations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_verify_locations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *cafile = Py_None; @@ -640,8 +745,41 @@ static PyObject * _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sock), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_socket", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_wrap_socket", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *sock; @@ -709,8 +847,41 @@ static PyObject * _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 6 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(incoming), &_Py_ID(outgoing), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_bio", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_wrap_bio", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PySSLMemoryBIO *incoming; @@ -853,8 +1024,41 @@ static PyObject * _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(binary_form), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"binary_form", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_ca_certs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_ca_certs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int binary_form = 0; @@ -1150,8 +1354,41 @@ static PyObject * _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(txt), &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"txt", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "txt2obj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "txt2obj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; const char *txt; @@ -1240,8 +1477,41 @@ static PyObject * _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(store_name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"store_name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enum_certificates", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enum_certificates", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *store_name; @@ -1293,8 +1563,41 @@ static PyObject * _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(store_name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"store_name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enum_crls", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enum_crls", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *store_name; @@ -1330,4 +1633,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=9d806f8ff4a06ed3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=243724694a274b72 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h index 03543e41af7f..4dedadd2939a 100644 --- a/Modules/clinic/_statisticsmodule.c.h +++ b/Modules/clinic/_statisticsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_statistics__normal_dist_inv_cdf__doc__, "_normal_dist_inv_cdf($module, p, mu, sigma, /)\n" "--\n" @@ -65,4 +71,4 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi exit: return return_value; } -/*[clinic end generated code: output=b807a8243e7801e6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6899dc752cc6b457 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index 39b8ccb5ca49..c7fa663f7861 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(Struct___init____doc__, "Struct(format)\n" "--\n" @@ -20,8 +26,41 @@ static int Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"format", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Struct", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Struct", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -103,8 +142,41 @@ static PyObject * Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"buffer", "offset", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unpack_from", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer buffer = {NULL, NULL}; @@ -285,8 +357,41 @@ static PyObject * unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "buffer", "offset", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unpack_from", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyStructObject *s_object = NULL; @@ -376,4 +481,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=2065c9b007be631c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f968221cff7bc5b3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index eabaea635d50..2add29fe8a6d 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_testmultiphase_StateAccessType_get_defining_module__doc__, "get_defining_module($self, /)\n" "--\n" @@ -73,8 +79,41 @@ static PyObject * _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(n), &_Py_ID(twice), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"n", "twice", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "increment_count_clinic", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "increment_count_clinic", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int n = 1; @@ -133,4 +172,4 @@ _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObj } return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=48739d81c3834078 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=34ad05704fd7f815 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 9103565ead70..a251202f9bba 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, "eval($self, script, /)\n" "--\n" @@ -859,4 +865,4 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=b0667ac928eb0c28 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d022835d05fc8608 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tracemalloc.c.h b/Modules/clinic/_tracemalloc.c.h index 20c4d5d81b9e..a89cd9aabca8 100644 --- a/Modules/clinic/_tracemalloc.c.h +++ b/Modules/clinic/_tracemalloc.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, "is_tracing($module, /)\n" "--\n" @@ -212,4 +218,4 @@ _tracemalloc_reset_peak(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _tracemalloc_reset_peak_impl(module); } -/*[clinic end generated code: output=2ae4fe05f1a340c9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=44e3f8553aae2535 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_typingmodule.c.h b/Modules/clinic/_typingmodule.c.h index ea415e67153e..f980aa0d0844 100644 --- a/Modules/clinic/_typingmodule.c.h +++ b/Modules/clinic/_typingmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_typing__idfunc__doc__, "_idfunc($module, x, /)\n" "--\n" @@ -9,4 +15,4 @@ PyDoc_STRVAR(_typing__idfunc__doc__, #define _TYPING__IDFUNC_METHODDEF \ {"_idfunc", (PyCFunction)_typing__idfunc, METH_O, _typing__idfunc__doc__}, -/*[clinic end generated code: output=e7ea2a3cb7ab301a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=97457fda45072c7d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index 541cba75e681..48feb042cac0 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_weakref_getweakrefcount__doc__, "getweakrefcount($module, object, /)\n" "--\n" @@ -110,4 +116,4 @@ _weakref_proxy(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=f4be6b8177fbceb8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=28265e89d583273d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 486029a63003..07cd442a96d5 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, "GetOverlappedResult($self, wait, /)\n" "--\n" @@ -106,8 +112,41 @@ static PyObject * _winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(overlapped), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"handle", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "|i:ConnectNamedPipe", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "|i:ConnectNamedPipe", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; int use_overlapped = 0; @@ -836,8 +875,41 @@ static PyObject * _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(locale), &_Py_ID(flags), &_Py_ID(src), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"locale", "flags", "src", NULL}; - static _PyArg_Parser _parser = {"O&kO&:LCMapStringEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "O&kO&:LCMapStringEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE LPCWSTR locale; DWORD flags; LPCWSTR src; @@ -873,8 +945,41 @@ static PyObject * _winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(size), &_Py_ID(overlapped), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "k|i:ReadFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "k|i:ReadFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; DWORD size; int use_overlapped = 0; @@ -1098,8 +1203,41 @@ static PyObject * _winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(buffer), &_Py_ID(overlapped), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "O|i:WriteFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "O|i:WriteFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; PyObject *buffer; int use_overlapped = 0; @@ -1147,8 +1285,41 @@ static PyObject * _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"handle", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE ":GetFileType", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE ":GetFileType", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; DWORD _return_value; @@ -1186,8 +1357,41 @@ static PyObject * _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(on_type_read), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"on_type_read", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_mimetypes_read_windows_registry", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_mimetypes_read_windows_registry", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *on_type_read; @@ -1201,4 +1405,4 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=6cdefec63a1d7f12 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5febc912fc8ff4ec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 6358ba2f81fa..b9ce96f3f7e9 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(array_array___copy____doc__, "__copy__($self, /)\n" "--\n" @@ -154,8 +160,41 @@ static PyObject * array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "extend", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "extend", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *bb; @@ -297,8 +336,41 @@ static PyObject * array_array_fromfile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fromfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *f; Py_ssize_t n; @@ -342,8 +414,41 @@ static PyObject * array_array_tofile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tofile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tofile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *f; @@ -584,8 +689,41 @@ static PyObject * array_array___reduce_ex__(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__reduce_ex__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__reduce_ex__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *value; @@ -630,4 +768,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=85a5fec90d9615b9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6cdb18b06fc993e0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h index 43103855fa1a..1a7ccf8b8284 100644 --- a/Modules/clinic/audioop.c.h +++ b/Modules/clinic/audioop.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(audioop_getsample__doc__, "getsample($module, fragment, width, index, /)\n" "--\n" @@ -1309,4 +1315,4 @@ audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=a581c3893ef8ad75 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a7e36f1179f0223 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index 2c766eddee8d..5afae34e8a2d 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(binascii_a2b_uu__doc__, "a2b_uu($module, data, /)\n" "--\n" @@ -49,8 +55,41 @@ static PyObject * binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(backtick), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "backtick", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_uu", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_uu", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -106,8 +145,41 @@ static PyObject * binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(strict_mode), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "strict_mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "a2b_base64", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_base64", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -154,8 +226,41 @@ static PyObject * binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(newline), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "newline", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_base64", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_base64", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -322,8 +427,41 @@ static PyObject * binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -392,8 +530,41 @@ static PyObject * binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hexlify", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hexlify", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -519,8 +690,41 @@ static PyObject * binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(header), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "header", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "a2b_qp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_qp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -572,8 +776,41 @@ static PyObject * binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(quotetabs), &_Py_ID(istext), &_Py_ID(header), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_qp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_qp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -628,4 +865,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=ba9ed7b810b8762d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=83eb1173ff9f6393 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index ab556922c029..6aa3d571711e 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(cmath_acos__doc__, "acos($module, z, /)\n" "--\n" @@ -893,8 +899,41 @@ static PyObject * cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "isclose", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; Py_complex a; @@ -953,4 +992,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=b8e445fcd2a3da65 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d87babbf69f095b8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index c41f088ff152..20eb50b0e76b 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(fcntl_fcntl__doc__, "fcntl($module, fd, cmd, arg=0, /)\n" "--\n" @@ -243,4 +249,4 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=b8cb14ab35de4c6a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1db859412172dd53 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 5391b8be42db..af04398ac7a0 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(gc_enable__doc__, "enable($module, /)\n" "--\n" @@ -88,8 +94,41 @@ static PyObject * gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(generation), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"generation", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "collect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "collect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int generation = NUM_GENERATIONS - 1; @@ -242,8 +281,41 @@ static PyObject * gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(generation), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"generation", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_objects", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_objects", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t generation = -1; @@ -372,4 +444,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=71f7136d6e3f2323 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c73502d349c8726 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index 3dd35e7e6ba0..58dd2e22512a 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(grp_getgrgid__doc__, "getgrgid($module, /, id)\n" "--\n" @@ -20,8 +26,41 @@ static PyObject * grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(id), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"id", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getgrgid", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getgrgid", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *id; @@ -54,8 +93,41 @@ static PyObject * grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getgrnam", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getgrnam", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -97,4 +169,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=ba680465f71ed779 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=82d55ad1c7c612d2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index 81608ccc089b..b62c04acd6a7 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pairwise_new__doc__, "pairwise(iterable, /)\n" "--\n" @@ -54,8 +60,41 @@ static PyObject * itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(key), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groupby", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groupby", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -377,8 +416,41 @@ static PyObject * itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "combinations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "combinations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -425,8 +497,41 @@ static PyObject * itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "combinations_with_replacement", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "combinations_with_replacement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -472,8 +577,41 @@ static PyObject * itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "permutations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "permutations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -511,8 +649,41 @@ static PyObject * itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(func), &_Py_ID(initial), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "func", "initial", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "accumulate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "accumulate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -563,8 +734,41 @@ static PyObject * itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(selectors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"data", "selectors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -638,8 +842,41 @@ static PyObject * itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), &_Py_ID(step), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"start", "step", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "count", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "count", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -667,4 +904,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=659251a811ff89ed input=a9049054013a1b77]*/ +/*[clinic end generated code: output=66bc6a70f05e9bc7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index efabbf971423..3b4e0cc54b0c 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(math_ceil__doc__, "ceil($module, x, /)\n" "--\n" @@ -578,8 +584,41 @@ static PyObject * math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "isclose", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; double a; @@ -673,8 +712,41 @@ static PyObject * math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "prod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *iterable; @@ -865,4 +937,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=965f99dabaa72165 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9f9605edaac98c6c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 999406ba1351..9dd8fd50eb27 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(MD5Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -85,8 +91,41 @@ static PyObject * _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "md5", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "md5", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -119,4 +158,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=e5dac1237beb2788 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4e0701fc285576d9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 1c216633eb95..71ad7a6f0858 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, "CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" "--\n" @@ -446,8 +452,41 @@ static PyObject * _overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(event), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"event", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Overlapped", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Overlapped", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -1225,4 +1264,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=edd05b7a6c9c3aac input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8a85a2b9616bf8f1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index ddd41cae3ec4..da5beb5ab05c 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(os_stat__doc__, "stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" "--\n" @@ -37,8 +43,41 @@ static PyObject * os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); @@ -96,8 +135,41 @@ static PyObject * os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lstat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lstat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); @@ -169,8 +241,41 @@ static PyObject * os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(effective_ids), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "access", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "access", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); @@ -306,8 +411,41 @@ static PyObject * os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); @@ -348,8 +486,41 @@ static PyObject * os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -405,8 +576,41 @@ static PyObject * os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); @@ -470,8 +674,41 @@ static PyObject * os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(mode), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; int mode; @@ -517,8 +754,41 @@ static PyObject * os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); int mode; @@ -570,8 +840,41 @@ static PyObject * os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chflags", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chflags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); @@ -630,8 +933,41 @@ static PyObject * os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchflags", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchflags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); unsigned long flags; @@ -677,8 +1013,41 @@ static PyObject * os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chroot", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chroot", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); @@ -718,8 +1087,41 @@ static PyObject * os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fsync", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fsync", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -778,8 +1180,41 @@ static PyObject * os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fdatasync", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fdatasync", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -841,8 +1276,41 @@ static PyObject * os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); @@ -911,8 +1379,41 @@ static PyObject * os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(uid), &_Py_ID(gid), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; int fd; uid_t uid; @@ -961,8 +1462,41 @@ static PyObject * os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "uid", "gid", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); uid_t uid; @@ -1058,8 +1592,41 @@ static PyObject * os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "link", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "link", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); @@ -1142,8 +1709,41 @@ static PyObject * os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "listdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); @@ -1253,8 +1853,41 @@ static PyObject * os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getvolumepathname", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getvolumepathname", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0); @@ -1294,8 +1927,41 @@ static PyObject * os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_path_splitroot", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_splitroot", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0); @@ -1333,8 +1999,41 @@ static PyObject * os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_path_normpath", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_normpath", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -1372,8 +2071,41 @@ static PyObject * os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mkdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); @@ -1466,8 +2198,41 @@ static PyObject * os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(which), &_Py_ID(who), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"which", "who", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getpriority", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getpriority", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int which; int who; @@ -1510,8 +2275,41 @@ static PyObject * os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(which), &_Py_ID(who), &_Py_ID(priority), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"which", "who", "priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setpriority", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setpriority", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; int which; int who; @@ -1564,8 +2362,41 @@ static PyObject * os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rename", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rename", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); @@ -1632,8 +2463,41 @@ static PyObject * os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); @@ -1698,8 +2562,41 @@ static PyObject * os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rmdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rmdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); @@ -1746,8 +2643,41 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(command), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "system", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const Py_UNICODE *command; long _return_value; @@ -1797,8 +2727,41 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(command), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "system", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *command = NULL; long _return_value; @@ -1878,8 +2841,41 @@ static PyObject * os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); @@ -1929,8 +2925,41 @@ static PyObject * os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "remove", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "remove", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); @@ -2024,8 +3053,41 @@ static PyObject * os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(times), &_Py_ID(ns), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "utime", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "utime", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); @@ -2098,8 +3160,41 @@ static PyObject * os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_exit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_exit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; @@ -2186,8 +3281,41 @@ static PyObject * os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(argv), &_Py_ID(env), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "argv", "env", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "execve", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "execve", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); PyObject *argv; @@ -2258,8 +3386,41 @@ static PyObject * os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 7 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawn", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posix_spawn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); @@ -2385,8 +3546,41 @@ static PyObject * os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 7 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawnp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posix_spawnp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0); @@ -2605,8 +3799,41 @@ static PyObject * os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(before), &_Py_ID(after_in_child), &_Py_ID(after_in_parent), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"before", "after_in_child", "after_in_parent", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "register_at_fork", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "register_at_fork", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *before = NULL; @@ -2708,8 +3935,41 @@ static PyObject * os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(policy), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"policy", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_max", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_get_priority_max", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int policy; @@ -2747,8 +4007,41 @@ static PyObject * os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(policy), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"policy", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_min", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_get_priority_min", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int policy; @@ -2819,8 +4112,41 @@ static PyObject * os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sched_priority), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sched_priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_param", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -3488,8 +4814,41 @@ static PyObject * os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"pid", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID ":getpgid", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID ":getpgid", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, @@ -3949,8 +5308,41 @@ static PyObject * os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(options), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"options", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "wait3", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "wait3", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int options; @@ -3991,8 +5383,41 @@ static PyObject * os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), &_Py_ID(options), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"pid", "options", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "i:wait4", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID "i:wait4", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; int options; @@ -4175,8 +5600,41 @@ static PyObject * os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"pid", "flags", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID "|O&:pidfd_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; unsigned int flags = 0; @@ -4216,8 +5674,41 @@ static PyObject * os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "readlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "readlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0); @@ -4277,8 +5768,41 @@ static PyObject * os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(target_is_directory), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "symlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "symlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); @@ -4527,8 +6051,41 @@ static PyObject * os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); @@ -4597,8 +6154,41 @@ static PyObject * os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "close", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "close", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -4703,8 +6293,41 @@ static PyObject * os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(fd2), &_Py_ID(inheritable), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dup2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dup2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; int fd; @@ -5132,8 +6755,41 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 7 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; int out_fd; @@ -5211,8 +6867,41 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 7 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; int out_fd; @@ -5297,8 +6986,41 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; int out_fd; int in_fd; @@ -5402,8 +7124,41 @@ static PyObject * os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fstat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fstat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -5731,8 +7486,41 @@ static PyObject * os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "copy_file_range", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "copy_file_range", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; int src; @@ -5822,8 +7610,41 @@ static PyObject * os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 6 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splice", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splice", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; int src; @@ -5907,8 +7728,41 @@ static PyObject * os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkfifo", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mkfifo", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); @@ -5984,8 +7838,41 @@ static PyObject * os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(device), &_Py_ID(dir_fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mknod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mknod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); @@ -6216,8 +8103,41 @@ static PyObject * os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(length), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "truncate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "truncate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); Py_off_t length; @@ -6594,8 +8514,41 @@ static PyObject * os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFCONTINUED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFCONTINUED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6638,8 +8591,41 @@ static PyObject * os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSTOPPED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFSTOPPED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6682,8 +8668,41 @@ static PyObject * os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSIGNALED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFSIGNALED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6726,8 +8745,41 @@ static PyObject * os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFEXITED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFEXITED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6770,8 +8822,41 @@ static PyObject * os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WEXITSTATUS", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WEXITSTATUS", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6814,8 +8899,41 @@ static PyObject * os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WTERMSIG", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WTERMSIG", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6858,8 +8976,41 @@ static PyObject * os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WSTOPSIG", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WSTOPSIG", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6940,8 +9091,41 @@ static PyObject * os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "statvfs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "statvfs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); @@ -6981,8 +9165,41 @@ static PyObject * os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getdiskusage", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getdiskusage", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0); @@ -7071,8 +9288,41 @@ static PyObject * os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(name), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pathconf", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pathconf", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); int name; @@ -7237,8 +9487,41 @@ static PyObject * os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(filepath), &_Py_ID(operation), &_Py_ID(arguments), &_Py_ID(cwd), &_Py_ID(show_cmd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"filepath", "operation", "arguments", "cwd", "show_cmd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "startfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "startfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); @@ -7358,8 +9641,41 @@ static PyObject * os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "device_encoding", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "device_encoding", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -7529,8 +9845,41 @@ static PyObject * os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); @@ -7593,8 +9942,41 @@ static PyObject * os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(value), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); @@ -7682,8 +10064,41 @@ static PyObject * os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "removexattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "removexattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); @@ -7745,8 +10160,41 @@ static PyObject * os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "listxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); @@ -7840,8 +10288,41 @@ static PyObject * os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memfd_create", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memfd_create", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name = NULL; @@ -7891,8 +10372,41 @@ static PyObject * os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initval), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"initval", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; unsigned int initval; @@ -7939,8 +10453,41 @@ static PyObject * os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_read", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd_read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -7977,8 +10524,41 @@ static PyObject * os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(value), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_write", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd_write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; unsigned long long value; @@ -8344,8 +10924,41 @@ static PyObject * os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; @@ -8385,8 +10998,41 @@ static PyObject * os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "is_dir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_dir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; @@ -8431,8 +11077,41 @@ static PyObject * os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "is_file", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_file", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; @@ -8518,8 +11197,41 @@ static PyObject * os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scandir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scandir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR); @@ -8564,8 +11276,41 @@ static PyObject * os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fspath", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fspath", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -8598,8 +11343,41 @@ static PyObject * os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(size), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"size", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getrandom", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getrandom", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_ssize_t size; @@ -8662,8 +11440,41 @@ static PyObject * os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_add_dll_directory", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_add_dll_directory", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0); @@ -8707,8 +11518,41 @@ static PyObject * os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cookie), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"cookie", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_remove_dll_directory", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_remove_dll_directory", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *cookie; @@ -8755,8 +11599,41 @@ static PyObject * os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "waitstatus_to_exitcode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "waitstatus_to_exitcode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *status_obj; @@ -9360,4 +12237,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=c22a8b6de4a0ccb7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=de9700c5cedd6f55 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index cb83062495dc..f2603eaf3225 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pwd_getpwuid__doc__, "getpwuid($module, uidobj, /)\n" "--\n" @@ -74,4 +80,4 @@ pwd_getpwall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef PWD_GETPWALL_METHODDEF #define PWD_GETPWALL_METHODDEF #endif /* !defined(PWD_GETPWALL_METHODDEF) */ -/*[clinic end generated code: output=7fceab7f1a85da36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a95bc08653cda56b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index b2648320aad7..e8947aad7969 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "Parse($self, data, isfinal=False, /)\n" "--\n" @@ -21,8 +27,41 @@ static PyObject * pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Parse", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Parse", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *data; int isfinal = 0; @@ -63,8 +102,41 @@ static PyObject * pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ParseFile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ParseFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *file; @@ -175,8 +247,41 @@ static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ExternalEntityParserCreate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ExternalEntityParserCreate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; const char *context; const char *encoding = NULL; @@ -282,8 +387,41 @@ static PyObject * pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "UseForeignDTD", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "UseForeignDTD", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int flag = 1; @@ -325,8 +463,41 @@ static PyObject * pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(namespace_separator), &_Py_ID(intern), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ParserCreate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ParserCreate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -425,4 +596,4 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg) #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=3e333b89da3aa58c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=94c16fdc27f36fae input=a9049054013a1b77]*/ diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h index c64a84ed81dd..e36d651f67f6 100644 --- a/Modules/clinic/readline.c.h +++ b/Modules/clinic/readline.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(readline_parse_and_bind__doc__, "parse_and_bind($module, string, /)\n" "--\n" @@ -685,4 +691,4 @@ readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef READLINE_CLEAR_HISTORY_METHODDEF #define READLINE_CLEAR_HISTORY_METHODDEF #endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ -/*[clinic end generated code: output=1fd4c04c2e7ba475 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9097fcb749c19e27 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/resource.c.h b/Modules/clinic/resource.c.h index f95321176a73..d0ca8e7150fa 100644 --- a/Modules/clinic/resource.c.h +++ b/Modules/clinic/resource.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_GETRUSAGE) PyDoc_STRVAR(resource_getrusage__doc__, @@ -172,4 +178,4 @@ resource_getpagesize(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef RESOURCE_PRLIMIT_METHODDEF #define RESOURCE_PRLIMIT_METHODDEF #endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ -/*[clinic end generated code: output=13441806729c6eaa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2fbec74335a57230 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index daa75427319a..14c4d13c2152 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(select_select__doc__, "select($module, rlist, wlist, xlist, timeout=None, /)\n" "--\n" @@ -522,8 +528,41 @@ static PyObject * select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sizehint), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sizehint", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "epoll", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "epoll", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -665,8 +704,41 @@ static PyObject * select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "register", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "register", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; int fd; @@ -719,8 +791,41 @@ static PyObject * select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "modify", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "modify", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; unsigned int eventmask; @@ -765,8 +870,41 @@ static PyObject * select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unregister", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unregister", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -813,8 +951,41 @@ static PyObject * select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(timeout), &_Py_ID(maxevents), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"timeout", "maxevents", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "poll", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "poll", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *timeout_obj = Py_None; @@ -1189,4 +1360,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=e77cc5c8a6c77860 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=54df930a8e55d87e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index e2338e4a1280..cb1354ad2a06 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA1Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -85,8 +91,41 @@ static PyObject * _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha1", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -119,4 +158,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=322d77ba0a4282fc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=cefc4e5d2d92698a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h index b94c1c548a39..a55008d2a9a5 100644 --- a/Modules/clinic/sha256module.c.h +++ b/Modules/clinic/sha256module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA256Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -85,8 +91,41 @@ static PyObject * _sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -136,8 +175,41 @@ static PyObject * _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -170,4 +242,4 @@ _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=58b48051890d3fde input=a9049054013a1b77]*/ +/*[clinic end generated code: output=15651dcd37e35962 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index b7227480c342..958de317dee6 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA512Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -85,8 +91,41 @@ static PyObject * _sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -136,8 +175,41 @@ static PyObject * _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -170,4 +242,4 @@ _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=60a0a1a28c07f391 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dff35c49c5d07fae input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 9e4a8eb0b998..f0276c63df18 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(signal_default_int_handler__doc__, "default_int_handler($module, signalnum, frame, /)\n" "--\n" @@ -698,4 +704,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=6ca1b70310eecdba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f2a3321b32b0637c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h index dab2b6dc45ce..9c5a96477138 100644 --- a/Modules/clinic/socketmodule.c.h +++ b/Modules/clinic/socketmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, PyObject *fdobj); @@ -10,8 +16,41 @@ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(family), &_Py_ID(type), &_Py_ID(proto), &_Py_ID(fileno), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"family", "type", "proto", "fileno", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "socket", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "socket", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -62,4 +101,4 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=2433d6ac51bc962a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a2c5f7be40570213 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h index 411d2344e18f..f47aa9a77f3f 100644 --- a/Modules/clinic/spwdmodule.c.h +++ b/Modules/clinic/spwdmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_GETSPNAM) PyDoc_STRVAR(spwd_getspnam__doc__, @@ -71,4 +77,4 @@ spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SPWD_GETSPALL_METHODDEF #define SPWD_GETSPALL_METHODDEF #endif /* !defined(SPWD_GETSPALL_METHODDEF) */ -/*[clinic end generated code: output=eec8d0bedcd312e5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd61827a7b708e11 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 2cd08f817820..04fdb9f2d9b7 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_symtable_symtable__doc__, "symtable($module, source, filename, startstr, /)\n" "--\n" @@ -48,4 +54,4 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3f7ccf535d750238 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=07716ddbd6c7efe1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h index 29858fe8d05e..78863e53c42f 100644 --- a/Modules/clinic/termios.c.h +++ b/Modules/clinic/termios.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(termios_tcgetattr__doc__, "tcgetattr($module, fd, /)\n" "--\n" @@ -286,4 +292,4 @@ termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=ef9ab888876fac17 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d286a3906a051869 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index 835a776fe172..6102027d07ab 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "decimal($self, chr, default=<unrepresentable>, /)\n" "--\n" @@ -559,4 +565,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=78d7a7ae57014502 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aaf601d28b352353 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index ad6a7d470c5e..8ceaf28073b3 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(zlib_compress__doc__, "compress($module, data, /, level=Z_DEFAULT_COMPRESSION, wbits=MAX_WBITS)\n" "--\n" @@ -25,8 +31,41 @@ static PyObject * zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(level), &_Py_ID(wbits), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "level", "wbits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -96,8 +135,41 @@ static PyObject * zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(wbits), &_Py_ID(bufsize), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -192,8 +264,41 @@ static PyObject * zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 6 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(level), &_Py_ID(method), &_Py_ID(wbits), &_Py_ID(memLevel), &_Py_ID(strategy), &_Py_ID(zdict), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compressobj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compressobj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int level = Z_DEFAULT_COMPRESSION; @@ -296,8 +401,41 @@ static PyObject * zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(wbits), &_Py_ID(zdict), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"wbits", "zdict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompressobj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompressobj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int wbits = MAX_WBITS; @@ -351,8 +489,41 @@ static PyObject * zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_buffer data = {NULL, NULL}; @@ -406,8 +577,41 @@ static PyObject * zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(max_length), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -473,8 +677,41 @@ static PyObject * zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "flush", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "flush", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int mode = Z_FINISH; @@ -565,8 +802,41 @@ static PyObject * zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__deepcopy__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__deepcopy__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *memo; @@ -652,8 +922,41 @@ static PyObject * zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__deepcopy__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__deepcopy__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *memo; @@ -690,8 +993,41 @@ static PyObject * zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 0 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "flush", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "flush", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length = DEF_BUF_SIZE; @@ -855,4 +1191,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=757804b3ad33454f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea8865903fb98344 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index 0b5c01a83dbe..a2b8108b1b7d 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, const char *encoding, const char *errors); @@ -10,8 +16,41 @@ static int bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytearray", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytearray", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -210,8 +249,41 @@ static PyObject * bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -390,8 +462,41 @@ static PyObject * bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -489,8 +594,41 @@ static PyObject * bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -843,8 +981,41 @@ static PyObject * bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -927,8 +1098,41 @@ static PyObject * bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -1019,8 +1223,41 @@ static PyObject * bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -1120,4 +1357,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=033e9eb5f2bb0139 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d3a4d0ae9fb8c738 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index 7e8572034175..595566b124a5 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(bytes___bytes____doc__, "__bytes__($self, /)\n" "--\n" @@ -44,8 +50,41 @@ static PyObject * bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -195,8 +234,41 @@ static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -374,8 +446,41 @@ static PyObject * bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -634,8 +739,41 @@ static PyObject * bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -705,8 +843,41 @@ static PyObject * bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -797,8 +968,41 @@ static PyObject * bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -836,8 +1040,41 @@ static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -896,4 +1133,4 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=5727702e63a0a8b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2e2262ea3fb16bd3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/classobject.c.h b/Objects/clinic/classobject.c.h index a4f190015a0d..6c449829662a 100644 --- a/Objects/clinic/classobject.c.h +++ b/Objects/clinic/classobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(method___reduce____doc__, "__reduce__($self, /)\n" "--\n" @@ -80,4 +86,4 @@ instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a230fe125f664416 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e3294c26a71d456d input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index df82524a86af..34a6fe950e9d 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" " flags, codestring, constants, names, varnames, filename, name,\n" @@ -186,8 +192,41 @@ static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 18 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_argcount), &_Py_ID(co_posonlyargcount), &_Py_ID(co_kwonlyargcount), &_Py_ID(co_nlocals), &_Py_ID(co_stacksize), &_Py_ID(co_flags), &_Py_ID(co_firstlineno), &_Py_ID(co_code), &_Py_ID(co_consts), &_Py_ID(co_names), &_Py_ID(co_varnames), &_Py_ID(co_freevars), &_Py_ID(co_cellvars), &_Py_ID(co_filename), &_Py_ID(co_name), &_Py_ID(co_qualname), &_Py_ID(co_linetable), &_Py_ID(co_exceptiontable), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_exceptiontable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[18]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int co_argcount = self->co_argcount; @@ -418,8 +457,41 @@ static PyObject * code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(oparg), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"oparg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_varname_from_oparg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_varname_from_oparg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int oparg; @@ -436,4 +508,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=9c521b6c79f90ff7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5dec2deb4a909b1b input=a9049054013a1b77]*/ diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h index e7d8065e874e..6c5ca3b4db59 100644 --- a/Objects/clinic/complexobject.c.h +++ b/Objects/clinic/complexobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(complex_conjugate__doc__, "conjugate($self, /)\n" "--\n" @@ -102,8 +108,41 @@ static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(real), &_Py_ID(imag), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"real", "imag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -131,4 +170,4 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=6d85094ace15677e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=cbd44b1d2428d4d8 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/descrobject.c.h b/Objects/clinic/descrobject.c.h index d248b91bf48d..145eba5ef33c 100644 --- a/Objects/clinic/descrobject.c.h +++ b/Objects/clinic/descrobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); @@ -9,8 +15,41 @@ static PyObject * mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(mapping), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"mapping", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mappingproxy", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mappingproxy", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -72,8 +111,41 @@ static int property_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fget), &_Py_ID(fset), &_Py_ID(fdel), &_Py_ID(doc), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "property", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "property", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -115,4 +187,4 @@ property_init(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=916624e717862abc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8079991d1579d46d input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index eda86c31fcc5..bc2452330e4e 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(dict_fromkeys__doc__, "fromkeys($type, iterable, value=None, /)\n" "--\n" @@ -191,4 +197,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=582766ac0154c8bf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c0064abbea6091c5 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/enumobject.c.h b/Objects/clinic/enumobject.c.h index 7513c9526ac5..62b1c901caa5 100644 --- a/Objects/clinic/enumobject.c.h +++ b/Objects/clinic/enumobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(enum_new__doc__, "enumerate(iterable, start=0)\n" "--\n" @@ -24,8 +30,41 @@ static PyObject * enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(start), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enumerate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enumerate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -78,4 +117,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a3937b6b33499560 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ee3984d523ead60e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index bf0748f3b3d1..1a81e173231b 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(float_is_integer__doc__, "is_integer($self, /)\n" "--\n" @@ -321,4 +327,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a6e6467624a92a43 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ac6374ac606a505e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index 17fb13fe085a..4580b3b3f959 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(func_new__doc__, "function(code, globals, name=None, argdefs=None, closure=None)\n" "--\n" @@ -27,8 +33,41 @@ static PyObject * func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(code), &_Py_ID(globals), &_Py_ID(name), &_Py_ID(argdefs), &_Py_ID(closure), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"code", "globals", "name", "argdefs", "closure", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -75,4 +114,4 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=3d96afa3396e5c82 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d1e30fc268fadb6f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index 2499383cc26c..13922f0ff09c 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(list_insert__doc__, "insert($self, index, object, /)\n" "--\n" @@ -166,8 +172,41 @@ static PyObject * list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(reverse), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "reverse", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sort", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sort", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *keyfunc = Py_None; @@ -353,4 +392,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=eab97a76b1568a03 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=45d61f54b3ab33ff input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 59b79636bee1..08138c85f102 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); @@ -9,8 +15,41 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "base", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "int", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "int", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -257,8 +296,41 @@ static PyObject * int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"length", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "to_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t length = 1; @@ -348,8 +420,41 @@ static PyObject * int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(bytes), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "from_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "from_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *bytes_obj; @@ -391,4 +496,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb exit: return return_value; } -/*[clinic end generated code: output=899e57c41861a8e9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c99dba22fab5787 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index 73ef8d143b50..dd21cf6f1cef 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(memoryview__doc__, "memoryview(object)\n" "--\n" @@ -15,8 +21,41 @@ static PyObject * memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"object", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memoryview", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memoryview", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -68,8 +107,41 @@ static PyObject * memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(shape), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"format", "shape", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cast", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cast", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *format; @@ -156,8 +228,41 @@ static PyObject * memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(order), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"order", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tobytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tobytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *order = NULL; @@ -228,8 +333,41 @@ static PyObject * memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -258,4 +396,4 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=48be570b5e6038e3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9617628ea080c887 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index c1534eaee258..1208d6cf2943 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(module___init____doc__, "module(name, doc=None)\n" "--\n" @@ -17,8 +23,41 @@ static int module___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(doc), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "module", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -48,4 +87,4 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=680276bc3a496d7a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=44f58e856e7f3821 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h index 5bb9952caa27..3485ca72e530 100644 --- a/Objects/clinic/odictobject.c.h +++ b/Objects/clinic/odictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "fromkeys($type, /, iterable, value=None)\n" "--\n" @@ -18,8 +24,41 @@ static PyObject * OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(value), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"iterable", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fromkeys", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromkeys", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *seq; @@ -60,8 +99,41 @@ static PyObject * OrderedDict_setdefault(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setdefault", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -103,8 +175,41 @@ static PyObject * OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pop", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pop", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -144,8 +249,41 @@ static PyObject * OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(last), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "popitem", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "popitem", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int last = 1; @@ -186,8 +324,41 @@ static PyObject * OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(last), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "move_to_end", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move_to_end", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -211,4 +382,4 @@ OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=4182a5dab66963d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39e6c9c21a594053 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/structseq.c.h b/Objects/clinic/structseq.c.h index b3b4836543d0..b35afa6e069d 100644 --- a/Objects/clinic/structseq.c.h +++ b/Objects/clinic/structseq.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); @@ -9,8 +15,41 @@ static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sequence), &_Py_ID(dict), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sequence", "dict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "structseq", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "structseq", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -33,4 +72,4 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=ed3019acf49b656c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=04b155379fef0f60 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/tupleobject.c.h b/Objects/clinic/tupleobject.c.h index 224fc0c374f0..a4776e14fa0a 100644 --- a/Objects/clinic/tupleobject.c.h +++ b/Objects/clinic/tupleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tuple_index__doc__, "index($self, value, start=0, stop=sys.maxsize, /)\n" "--\n" @@ -112,4 +118,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) { return tuple___getnewargs___impl(self); } -/*[clinic end generated code: output=044496dc917f8a97 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=441d2b880e865f87 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typeobject.c.h b/Objects/clinic/typeobject.c.h index dee3139bd3d8..f2864297b0f4 100644 --- a/Objects/clinic/typeobject.c.h +++ b/Objects/clinic/typeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(type___instancecheck____doc__, "__instancecheck__($self, instance, /)\n" "--\n" @@ -261,4 +267,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=a30090032b8e6195 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3312f873c970bfd1 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 07877693c26e..959e3bbc988f 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(EncodingMap_size__doc__, "size($self, /)\n" "--\n" @@ -154,8 +160,41 @@ static PyObject * unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -224,8 +263,41 @@ static PyObject * unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -902,8 +974,41 @@ static PyObject * unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -1001,8 +1106,41 @@ static PyObject * unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -1059,8 +1197,41 @@ static PyObject * unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -1293,8 +1464,41 @@ static PyObject * unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"object", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "str", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "str", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -1353,4 +1557,4 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b5dd7cefead9a8e7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7688af9eecfc6bfd input=a9049054013a1b77]*/ diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index b88517bd3649..7de659a70b03 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(stringlib_expandtabs__doc__, "expandtabs($self, /, tabsize=8)\n" "--\n" @@ -20,8 +26,41 @@ static PyObject * stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -249,4 +288,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=46d058103bffedf7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a4fa1e513dd6a2f3 input=a9049054013a1b77]*/ diff --git a/PC/clinic/_msi.c.h b/PC/clinic/_msi.c.h index ca1f8ad76a31..1b7234aa03be 100644 --- a/PC/clinic/_msi.c.h +++ b/PC/clinic/_msi.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_msi_UuidCreate__doc__, "UuidCreate($module, /)\n" "--\n" @@ -689,4 +695,4 @@ _msi_CreateRecord(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a592695c4315db22 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=583505220fadb52b input=a9049054013a1b77]*/ diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index b2fd515e77a1..7250150232b9 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_testconsole_write_input__doc__, @@ -21,8 +27,41 @@ static PyObject * _testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(s), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", "s", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "write_input", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write_input", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *file; PyBytesObject *s; @@ -63,8 +102,41 @@ static PyObject * _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"file", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "read_output", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read_output", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *file; @@ -88,4 +160,4 @@ _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF #define _TESTCONSOLE_READ_OUTPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ -/*[clinic end generated code: output=6e9f8b0766eb5a0e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=73b7768a87e295a9 input=a9049054013a1b77]*/ diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h index e60fbd0b623c..d808ef0bbd0f 100644 --- a/PC/clinic/msvcrtmodule.c.h +++ b/PC/clinic/msvcrtmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(msvcrt_heapmin__doc__, "heapmin($module, /)\n" "--\n" @@ -661,4 +667,4 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg) #ifndef MSVCRT_SET_ERROR_MODE_METHODDEF #define MSVCRT_SET_ERROR_MODE_METHODDEF #endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */ -/*[clinic end generated code: output=9d89e9414484d28c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=204bae9fee7f6124 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 7b0624919212..2cf50ef5ce34 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(winreg_HKEYType_Close__doc__, "Close($self, /)\n" "--\n" @@ -87,8 +93,41 @@ static PyObject * winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(exc_type), &_Py_ID(exc_value), &_Py_ID(traceback), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"exc_type", "exc_value", "traceback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__exit__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__exit__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *exc_type; PyObject *exc_value; @@ -286,8 +325,41 @@ static PyObject * winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "CreateKeyEx", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "CreateKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; @@ -440,8 +512,41 @@ static PyObject * winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(access), &_Py_ID(reserved), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "DeleteKeyEx", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeleteKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; @@ -821,8 +926,41 @@ static PyObject * winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "OpenKey", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "OpenKey", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; @@ -911,8 +1049,41 @@ static PyObject * winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "OpenKeyEx", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "OpenKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; @@ -1458,4 +1629,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=3faa63af6fd1653c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dc148c077a03843e input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index 9f99b8e40026..c4814104fd30 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(winsound_PlaySound__doc__, "PlaySound($module, /, sound, flags)\n" "--\n" @@ -23,8 +29,41 @@ static PyObject * winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sound), &_Py_ID(flags), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sound", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "PlaySound", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "PlaySound", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *sound; int flags; @@ -66,8 +105,41 @@ static PyObject * winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(frequency), &_Py_ID(duration), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"frequency", "duration", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Beep", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Beep", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int frequency; int duration; @@ -108,8 +180,41 @@ static PyObject * winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(type), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"type", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "MessageBeep", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "MessageBeep", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int type = MB_OK; @@ -131,4 +236,4 @@ winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=b7e53fab4f26aeaf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bdca8518ca517fd8 input=a9049054013a1b77]*/ diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c index 6acfc2a7cfd2..c5124a6942e7 100644 --- a/Python/Python-tokenize.c +++ b/Python/Python-tokenize.c @@ -15,6 +15,7 @@ get_tokenize_state(PyObject *module) { #define _tokenize_get_state_by_type(type) \ get_tokenize_state(PyType_GetModuleByDef(type, &_tokenizemodule)) +#include "pycore_runtime.h" #include "clinic/Python-tokenize.c.h" /*[clinic input] diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h index 050b4d49448c..61bf29155153 100644 --- a/Python/clinic/Python-tokenize.c.h +++ b/Python/clinic/Python-tokenize.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * tokenizeriter_new_impl(PyTypeObject *type, const char *source); @@ -9,8 +15,41 @@ static PyObject * tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tokenizeriter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tokenizeriter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -38,4 +77,4 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=dfcd64774e01bfe6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5664c98597aec79e input=a9049054013a1b77]*/ diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h index 926fb32e7c26..7944412dfdb0 100644 --- a/Python/clinic/_warnings.c.h +++ b/Python/clinic/_warnings.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(warnings_warn__doc__, "warn($module, /, message, category=None, stacklevel=1, source=None)\n" "--\n" @@ -19,8 +25,41 @@ static PyObject * warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(stacklevel), &_Py_ID(source), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "warn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *message; @@ -88,8 +127,41 @@ static PyObject * warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 8 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(filename), &_Py_ID(lineno), &_Py_ID(module), &_Py_ID(registry), &_Py_ID(module_globals), &_Py_ID(source), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"message", "category", "filename", "lineno", "module", "registry", "module_globals", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "warn_explicit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "warn_explicit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[8]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; PyObject *message; @@ -147,4 +219,4 @@ warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=596b370838b95386 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=264258fa6b1b0c36 input=a9049054013a1b77]*/ diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 48f65091164d..76f9fcab80c3 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(builtin___import____doc__, "__import__($module, /, name, globals=None, locals=None, fromlist=(),\n" " level=0)\n" @@ -34,8 +40,41 @@ static PyObject * builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 5 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(globals), &_Py_ID(locals), &_Py_ID(fromlist), &_Py_ID(level), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__import__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__import__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name; @@ -253,8 +292,41 @@ static PyObject * builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 7 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(filename), &_Py_ID(mode), &_Py_ID(flags), &_Py_ID(dont_inherit), &_Py_ID(optimize), &_Py_ID(_feature_version), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *source; @@ -432,8 +504,41 @@ static PyObject * builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(closure), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "", "", "closure", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "exec", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exec", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *source; @@ -743,8 +848,41 @@ static PyObject * builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 3 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), &_Py_ID(exp), &_Py_ID(mod), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"base", "exp", "mod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pow", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *base; @@ -794,8 +932,41 @@ static PyObject * builtin_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(end), &_Py_ID(file), &_Py_ID(flush), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"sep", "end", "file", "flush", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "print", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "print", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -910,8 +1081,41 @@ static PyObject * builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(number), &_Py_ID(ndigits), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"number", "ndigits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "round", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "round", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *number; @@ -953,8 +1157,41 @@ static PyObject * builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sum", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *iterable; @@ -1045,4 +1282,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a2c5c53e8aead7c3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4590e66a40312a9f input=a9049054013a1b77]*/ diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h index 292d3f7f4ff4..27c375717bff 100644 --- a/Python/clinic/context.c.h +++ b/Python/clinic/context.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_contextvars_Context_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -177,4 +183,4 @@ PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__, #define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \ {"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__}, -/*[clinic end generated code: output=2436b16a92452869 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0c94d4b919500438 input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 0451d97a720d..69eebde6d6b3 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_imp_lock_held__doc__, "lock_held($module, /)\n" "--\n" @@ -193,8 +199,41 @@ static PyObject * _imp_find_frozen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(withdata), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"", "withdata", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "find_frozen", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find_frozen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name; @@ -526,8 +565,41 @@ static PyObject * _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 2 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(source), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"key", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "source_hash", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; long key; Py_buffer source = {NULL, NULL}; @@ -565,4 +637,4 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=8d0f4305b1d0714b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7d75c10a93f2f26c input=a9049054013a1b77]*/ diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h index 36f2afd5241b..a593b980544b 100644 --- a/Python/clinic/marshal.c.h +++ b/Python/clinic/marshal.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(marshal_dump__doc__, "dump($module, value, file, version=version, /)\n" "--\n" @@ -155,4 +161,4 @@ marshal_loads(PyObject *module, PyObject *arg) return return_value; } -/*[clinic end generated code: output=b9e838edee43fe87 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12082d61d2942473 input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 76b4cc557826..e1021bbbd788 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(sys_addaudithook__doc__, "addaudithook($module, /, hook)\n" "--\n" @@ -18,8 +24,41 @@ static PyObject * sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(hook), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"hook", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "addaudithook", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *hook; @@ -425,8 +464,41 @@ static PyObject * sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 1 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(depth), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"depth", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_coroutine_origin_tracking_depth", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int depth; @@ -1118,4 +1190,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=41122dae1bb7158c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b8b125686bc745a6 input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index 404a0c416d34..5de11021b497 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tb_new__doc__, "TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" "--\n" @@ -16,8 +22,41 @@ static PyObject * tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #define NUM_KEYWORDS 4 + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tb_next), &_Py_ID(tb_frame), &_Py_ID(tb_lasti), &_Py_ID(tb_lineno), }, + }; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TracebackType", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -49,4 +88,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=403778d7af5ebef9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=130ba2a638849c70 input=a9049054013a1b77]*/ diff --git a/Python/getargs.c b/Python/getargs.c index 2efd330ea62d..457dd99ce4a5 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1851,118 +1851,183 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, static struct _PyArg_Parser *static_arg_parsers = NULL; static int -parser_init(struct _PyArg_Parser *parser) +scan_keywords(const char * const *keywords, int *ptotal, int *pposonly) { - const char * const *keywords; - const char *format, *msg; - int i, len, min, max, nkw; - PyObject *kwtuple; - - assert(parser->keywords != NULL); - if (parser->kwtuple != NULL) { - return 1; - } - - keywords = parser->keywords; /* scan keywords and count the number of positional-only parameters */ + int i; for (i = 0; keywords[i] && !*keywords[i]; i++) { } - parser->pos = i; + *pposonly = i; + /* scan keywords and get greatest possible nbr of args */ for (; keywords[i]; i++) { if (!*keywords[i]) { PyErr_SetString(PyExc_SystemError, "Empty keyword parameter name"); - return 0; + return -1; } } - len = i; + *ptotal = i; + return 0; +} - format = parser->format; - if (format) { - /* grab the function name or custom error msg first (mutually exclusive) */ - parser->fname = strchr(parser->format, ':'); - if (parser->fname) { - parser->fname++; - parser->custom_msg = NULL; +static int +parse_format(const char *format, int total, int npos, + const char **pfname, const char **pcustommsg, + int *pmin, int *pmax) +{ + /* grab the function name or custom error msg first (mutually exclusive) */ + const char *custommsg; + const char *fname = strchr(format, ':'); + if (fname) { + fname++; + custommsg = NULL; + } + else { + custommsg = strchr(format,';'); + if (custommsg) { + custommsg++; } - else { - parser->custom_msg = strchr(parser->format,';'); - if (parser->custom_msg) - parser->custom_msg++; - } - - min = max = INT_MAX; - for (i = 0; i < len; i++) { - if (*format == '|') { - if (min != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string (| specified twice)"); - return 0; - } - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ before |)"); - return 0; - } - min = i; - format++; + } + + int min = INT_MAX; + int max = INT_MAX; + for (int i = 0; i < total; i++) { + if (*format == '|') { + if (min != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string (| specified twice)"); + return -1; } - if (*format == '$') { - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ specified twice)"); - return 0; - } - if (i < parser->pos) { - PyErr_SetString(PyExc_SystemError, - "Empty parameter name after $"); - return 0; - } - max = i; - format++; + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ before |)"); + return -1; } - if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_SystemError, - "More keyword list entries (%d) than " - "format specifiers (%d)", len, i); - return 0; + min = i; + format++; + } + if (*format == '$') { + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ specified twice)"); + return -1; } - - msg = skipitem(&format, NULL, 0); - if (msg) { - PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, - format); - return 0; + if (i < npos) { + PyErr_SetString(PyExc_SystemError, + "Empty parameter name after $"); + return -1; } + max = i; + format++; } - parser->min = Py_MIN(min, len); - parser->max = Py_MIN(max, len); - - if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + if (IS_END_OF_FORMAT(*format)) { PyErr_Format(PyExc_SystemError, - "more argument specifiers than keyword list entries " - "(remaining format:'%s')", format); - return 0; + "More keyword list entries (%d) than " + "format specifiers (%d)", total, i); + return -1; + } + + const char *msg = skipitem(&format, NULL, 0); + if (msg) { + PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, + format); + return -1; } } + min = Py_MIN(min, total); + max = Py_MIN(max, total); - nkw = len - parser->pos; - kwtuple = PyTuple_New(nkw); + if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + PyErr_Format(PyExc_SystemError, + "more argument specifiers than keyword list entries " + "(remaining format:'%s')", format); + return -1; + } + + *pfname = fname; + *pcustommsg = custommsg; + *pmin = min; + *pmax = max; + return 0; +} + +static PyObject * +new_kwtuple(const char * const *keywords, int total, int pos) +{ + int nkw = total - pos; + PyObject *kwtuple = PyTuple_New(nkw); if (kwtuple == NULL) { - return 0; + return NULL; } - keywords = parser->keywords + parser->pos; - for (i = 0; i < nkw; i++) { + keywords += pos; + for (int i = 0; i < nkw; i++) { PyObject *str = PyUnicode_FromString(keywords[i]); if (str == NULL) { Py_DECREF(kwtuple); - return 0; + return NULL; } PyUnicode_InternInPlace(&str); PyTuple_SET_ITEM(kwtuple, i, str); } + return kwtuple; +} + +static int +parser_init(struct _PyArg_Parser *parser) +{ + const char * const *keywords = parser->keywords; + assert(keywords != NULL); + + if (parser->initialized) { + assert(parser->kwtuple != NULL); + return 1; + } + assert(parser->pos == 0 && + (parser->format == NULL || parser->fname == NULL) && + parser->custom_msg == NULL && + parser->min == 0 && + parser->max == 0); + + int len, pos; + if (scan_keywords(keywords, &len, &pos) < 0) { + return 0; + } + + const char *fname, *custommsg = NULL; + int min = 0, max = 0; + if (parser->format) { + assert(parser->fname == NULL); + if (parse_format(parser->format, len, pos, + &fname, &custommsg, &min, &max) < 0) { + return 0; + } + } + else { + assert(parser->fname != NULL); + fname = parser->fname; + } + + int owned; + PyObject *kwtuple = parser->kwtuple; + if (kwtuple == NULL) { + kwtuple = new_kwtuple(keywords, len, pos); + if (kwtuple == NULL) { + return 0; + } + owned = 1; + } + else { + owned = 0; + } + + parser->pos = pos; + parser->fname = fname; + parser->custom_msg = custommsg; + parser->min = min; + parser->max = max; parser->kwtuple = kwtuple; + parser->initialized = owned ? 1 : -1; assert(parser->next == NULL); parser->next = static_arg_parsers; @@ -1973,7 +2038,9 @@ parser_init(struct _PyArg_Parser *parser) static void parser_clear(struct _PyArg_Parser *parser) { - Py_CLEAR(parser->kwtuple); + if (parser->initialized == 1) { + Py_CLEAR(parser->kwtuple); + } } static PyObject* @@ -2100,6 +2167,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, } format = parser->format; + assert(format != NULL || len == 0); /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ for (i = 0; i < len; i++) { if (*format == '|') { diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 36bfc7050507..88f779e64a0d 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -535,6 +535,59 @@ def normalize_snippet(s, *, indent=0): return s +def declare_parser(*, hasformat=False): + """ + Generates the code template for a static local PyArg_Parser variable, + with an initializer. For core code (incl. builtin modules) the + kwtuple field is also statically initialized. Otherwise + it is initialized at runtime. + """ + if hasformat: + fname = '' + format_ = '.format = "{format_units}:{name}",' + else: + fname = '.fname = "{name}",' + format_ = '' + declarations = """ + #define NUM_KEYWORDS {num_keywords} + #if NUM_KEYWORDS == 0 + + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + # else + # define KWTUPLE NULL + # endif + + #else // NUM_KEYWORDS != 0 + # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + static struct {{ + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + }} _kwtuple = {{ + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = {{ {keywords_py} }}, + }}; + # define KWTUPLE (&_kwtuple.ob_base.ob_base) + + # else // !Py_BUILD_CORE + # define KWTUPLE NULL + # endif // !Py_BUILD_CORE + #endif // NUM_KEYWORDS != 0 + #undef NUM_KEYWORDS + + static const char * const _keywords[] = {{{keywords_c} NULL}}; + static _PyArg_Parser _parser = {{ + .keywords = _keywords, + %s + .kwtuple = KWTUPLE, + }}; + #undef KWTUPLE + """ % (format_ or fname) + return normalize_snippet(declarations) + + def wrap_declarations(text, length=78): """ A simple-minded text wrapper for C function declarations. @@ -967,11 +1020,8 @@ def parser_body(prototype, *fields, declarations=''): flags = "METH_FASTCALL|METH_KEYWORDS" parser_prototype = parser_prototype_fastcall_keywords argname_fmt = 'args[%d]' - declarations = normalize_snippet(""" - static const char * const _keywords[] = {{{keywords} NULL}}; - static _PyArg_Parser _parser = {{NULL, _keywords, "{name}", 0}}; - PyObject *argsbuf[%s]; - """ % len(converters)) + declarations = declare_parser() + declarations += "\nPyObject *argsbuf[%s];" % len(converters) if has_optional_kw: pre_buffer = "0" if vararg != NO_VARARG else "nargs" declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (pre_buffer, min_pos + min_kw_only) @@ -986,13 +1036,10 @@ def parser_body(prototype, *fields, declarations=''): flags = "METH_VARARGS|METH_KEYWORDS" parser_prototype = parser_prototype_keyword argname_fmt = 'fastargs[%d]' - declarations = normalize_snippet(""" - static const char * const _keywords[] = {{{keywords} NULL}}; - static _PyArg_Parser _parser = {{NULL, _keywords, "{name}", 0}}; - PyObject *argsbuf[%s]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - """ % len(converters)) + declarations = declare_parser() + declarations += "\nPyObject *argsbuf[%s];" % len(converters) + declarations += "\nPyObject * const *fastargs;" + declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" if has_optional_kw: declarations += "\nPy_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (min_pos + min_kw_only) parser_code = [normalize_snippet(""" @@ -1069,9 +1116,7 @@ def parser_body(prototype, *fields, declarations=''): if add_label: parser_code.append("%s:" % add_label) else: - declarations = ( - 'static const char * const _keywords[] = {{{keywords} NULL}};\n' - 'static _PyArg_Parser _parser = {{"{format_units}:{name}", _keywords, 0}};') + declarations = declare_parser(hasformat=True) if not new_or_init: parser_code = [normalize_snippet(""" if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma} @@ -1394,7 +1439,12 @@ def render_function(self, clinic, f): template_dict['declarations'] = format_escape("\n".join(data.declarations)) template_dict['initializers'] = "\n\n".join(data.initializers) template_dict['modifications'] = '\n\n'.join(data.modifications) - template_dict['keywords'] = ' '.join('"' + k + '",' for k in data.keywords) + template_dict['keywords_c'] = ' '.join('"' + k + '",' + for k in data.keywords) + keywords = [k for k in data.keywords if k] + template_dict['num_keywords'] = len(keywords) + template_dict['keywords_py'] = ' '.join('&_Py_ID(' + k + '),' + for k in keywords) template_dict['format_units'] = ''.join(data.format_units) template_dict['parse_arguments'] = ', '.join(data.parse_arguments) if data.parse_arguments: @@ -1712,7 +1762,7 @@ def __init__(self, language, f=None): self.language = language self.f = f or io.StringIO() - def print_block(self, block): + def print_block(self, block, *, core_includes=False): input = block.input output = block.output dsl_name = block.dsl_name @@ -1739,8 +1789,18 @@ def print_block(self, block): write(self.language.stop_line.format(dsl_name=dsl_name)) write("\n") + output = '' + if core_includes: + output += textwrap.dedent(""" + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # include "pycore_gc.h" // PyGC_Head + # include "pycore_runtime.h" // _Py_ID() + #endif + + """) + input = ''.join(block.input) - output = ''.join(block.output) + output += ''.join(block.output) if output: if not output.endswith('\n'): output += '\n' @@ -2073,7 +2133,7 @@ def parse(self, input): block.input = 'preserve\n' printer_2 = BlockPrinter(self.language) - printer_2.print_block(block) + printer_2.print_block(block, core_includes=True) write_file(destination.filename, printer_2.f.getvalue()) continue text = printer.f.getvalue() From webhook-mailer at python.org Thu Aug 11 17:35:48 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 21:35:48 -0000 Subject: [Python-checkins] gh-95841: IDLE - Revise Windows local doc url (GH-95845) Message-ID: <mailman.629.1660253749.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bfaa071e1c84517ab8fdabc15bf934a67882c09f commit: bfaa071e1c84517ab8fdabc15bf934a67882c09f branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T14:35:36-07:00 summary: gh-95841: IDLE - Revise Windows local doc url (GH-95845) GH-91242 replaced the Windows chm help file with a copy of the html docs. This PR replaces the IDLE code that fetches the Windows local help url passed to os.startfile. Co-authored-by: Steve Dower (cherry picked from commit bdb2cf8e913c041f26e8976abe58414819b3e8ff) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/editor.py diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 859a288b4bc..08d6aa2efde 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -86,10 +86,20 @@ def __init__(self, flist=None, filename=None, key=None, root=None): dochome = os.path.join(basepath, pyver, 'Doc', 'index.html') elif sys.platform[:3] == 'win': - chmfile = os.path.join(sys.base_prefix, 'Doc', - 'Python%s.chm' % _sphinx_version()) - if os.path.isfile(chmfile): - dochome = chmfile + import winreg # Windows only, block only executed once. + docfile = '' + KEY = (rf"Software\Python\PythonCore\{sys.winver}" + r"\Help\Main Python Documentation") + try: + docfile = winreg.QueryValue(winreg.HKEY_CURRENT_USER, KEY) + except FileNotFoundError: + try: + docfile = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, + KEY) + except FileNotFoundError: + pass + if os.path.isfile(docfile): + dochome = docfile elif sys.platform == 'darwin': # documentation may be stored inside a python framework dochome = os.path.join(sys.base_prefix, From webhook-mailer at python.org Thu Aug 11 19:05:20 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 11 Aug 2022 23:05:20 -0000 Subject: [Python-checkins] gh-95273: Improve sqlite3.complete_statement docs (#95840) Message-ID: <mailman.630.1660259122.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e6623e7083ce08a247e5df169bcc749f99327823 commit: e6623e7083ce08a247e5df169bcc749f99327823 branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-12T01:05:12+02:00 summary: gh-95273: Improve sqlite3.complete_statement docs (#95840) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> files: D Doc/includes/sqlite3/complete_statement.py M Doc/library/sqlite3.rst M Lib/sqlite3/__main__.py diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py deleted file mode 100644 index a5c947969910..000000000000 --- a/Doc/includes/sqlite3/complete_statement.py +++ /dev/null @@ -1,33 +0,0 @@ -# A minimal SQLite shell for experiments - -import sqlite3 - -con = sqlite3.connect(":memory:") -con.isolation_level = None -cur = con.cursor() - -buffer = "" - -print("Enter your SQL commands to execute in sqlite3.") -print("Enter a blank line to exit.") - -while True: - line = input() - if line == "": - break - buffer += line - if sqlite3.complete_statement(buffer): - try: - buffer = buffer.strip() - cur.execute(buffer) - - if buffer.lstrip().upper().startswith("SELECT"): - print(cur.fetchall()) - except sqlite3.Error as e: - err_msg = str(e) - err_code = e.sqlite_errorcode - err_name = e.sqlite_errorname - print(f"{err_name} ({err_code}): {err_msg}") - buffer = "" - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 06ed7af052f0..67f8b31f11f4 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -222,14 +222,25 @@ Module functions .. function:: complete_statement(statement) - Returns ``True`` if the string *statement* contains one or more complete SQL - statements terminated by semicolons. It does not verify that the SQL is - syntactically correct, only that there are no unclosed string literals and the - statement is terminated by a semicolon. + Return ``True`` if the string *statement* appears to contain + one or more complete SQL statements. + No syntactic verification or parsing of any kind is performed, + other than checking that there are no unclosed string literals + and the statement is terminated by a semicolon. - This can be used to build a shell for SQLite, as in the following example: + For example:: - .. literalinclude:: ../includes/sqlite3/complete_statement.py + >>> sqlite3.complete_statement("SELECT foo FROM bar;") + True + >>> sqlite3.complete_statement("SELECT foo") + False + + This function may be useful during command-line input + to determine if the entered text seems to form a complete SQL statement, + or if additional input is needed before calling :meth:`~Cursor.execute`. + + See :func:`!runsource` in :source:`Lib/sqlite3/__main__.py` + for real-world use. .. function:: enable_callback_tracebacks(flag, /) diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py index c62fad84e74b..f8a5cca24e56 100644 --- a/Lib/sqlite3/__main__.py +++ b/Lib/sqlite3/__main__.py @@ -1,3 +1,9 @@ +"""A simple SQLite CLI for the sqlite3 module. + +Apart from using 'argparse' for the command-line interface, +this module implements the REPL as a thin wrapper around +the InteractiveConsole class from the 'code' stdlib module. +""" import sqlite3 import sys @@ -7,6 +13,14 @@ def execute(c, sql, suppress_errors=True): + """Helper that wraps execution of SQL code. + + This is used both by the REPL and by direct execution from the CLI. + + 'c' may be a cursor or a connection. + 'sql' is the SQL string to execute. + """ + try: for row in c.execute(sql): print(row) @@ -21,6 +35,7 @@ def execute(c, sql, suppress_errors=True): class SqliteInteractiveConsole(InteractiveConsole): + """A simple SQLite REPL.""" def __init__(self, connection): super().__init__() @@ -28,6 +43,11 @@ def __init__(self, connection): self._cur = connection.cursor() def runsource(self, source, filename="<input>", symbol="single"): + """Override runsource, the core of the InteractiveConsole REPL. + + Return True if more input is needed; buffering is done automatically. + Return False is input is a complete statement ready for execution. + """ match source: case ".version": print(f"{sqlite3.sqlite_version}") @@ -73,6 +93,7 @@ def main(): else: db_name = repr(args.filename) + # Prepare REPL banner and prompts. banner = dedent(f""" sqlite3 shell, running on SQLite version {sqlite3.sqlite_version} Connected to {db_name} @@ -86,8 +107,10 @@ def main(): con = sqlite3.connect(args.filename, isolation_level=None) try: if args.sql: + # SQL statement provided on the command-line; execute it directly. execute(con, args.sql, suppress_errors=False) else: + # No SQL provided; start the REPL. console = SqliteInteractiveConsole(con) console.interact(banner, exitmsg="") finally: From webhook-mailer at python.org Thu Aug 11 19:12:12 2022 From: webhook-mailer at python.org (1st1) Date: Thu, 11 Aug 2022 23:12:12 -0000 Subject: [Python-checkins] gh-95724: Clarify taskgroups.py license. (#95847) Message-ID: <mailman.631.1660259533.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7da4937748eb588bb0e977839061ce76cab1b252 commit: 7da4937748eb588bb0e977839061ce76cab1b252 branch: main author: Yury Selivanov <yury at edgedb.com> committer: 1st1 <yury at edgedb.com> date: 2022-08-11T16:12:06-07:00 summary: gh-95724: Clarify taskgroups.py license. (#95847) files: M Lib/asyncio/taskgroups.py M Lib/test/test_asyncio/test_taskgroups.py diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 097b4864f7ab..9be4838e3c7a 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -1,4 +1,5 @@ -# Adapted with permission from the EdgeDB project. +# Adapted with permission from the EdgeDB project; +# license: PSFL. __all__ = ["TaskGroup"] diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 99498e7b36f0..74bae06af8e7 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -1,4 +1,5 @@ -# Adapted with permission from the EdgeDB project. +# Adapted with permission from the EdgeDB project; +# license: PSFL. import asyncio From webhook-mailer at python.org Thu Aug 11 19:45:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 11 Aug 2022 23:45:36 -0000 Subject: [Python-checkins] gh-95724: Clarify taskgroups.py license. (GH-95847) Message-ID: <mailman.632.1660261537.3313.python-checkins@python.org> https://github.com/python/cpython/commit/24dd1429e56594ab8b9aff8522305b4f38989711 commit: 24dd1429e56594ab8b9aff8522305b4f38989711 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-11T16:45:30-07:00 summary: gh-95724: Clarify taskgroups.py license. (GH-95847) (cherry picked from commit 7da4937748eb588bb0e977839061ce76cab1b252) Co-authored-by: Yury Selivanov <yury at edgedb.com> files: M Lib/asyncio/taskgroups.py M Lib/test/test_asyncio/test_taskgroups.py diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 097b4864f7ab..9be4838e3c7a 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -1,4 +1,5 @@ -# Adapted with permission from the EdgeDB project. +# Adapted with permission from the EdgeDB project; +# license: PSFL. __all__ = ["TaskGroup"] diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 99498e7b36f0..74bae06af8e7 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -1,4 +1,5 @@ -# Adapted with permission from the EdgeDB project. +# Adapted with permission from the EdgeDB project; +# license: PSFL. import asyncio From webhook-mailer at python.org Thu Aug 11 20:11:51 2022 From: webhook-mailer at python.org (terryjreedy) Date: Fri, 12 Aug 2022 00:11:51 -0000 Subject: [Python-checkins] gh-95841: IDLE - Revise Windows local doc url (GH-95845) (#95905) Message-ID: <mailman.633.1660263112.3313.python-checkins@python.org> https://github.com/python/cpython/commit/577dbc3c49615896d5b6fbf0cb25eebd4d28624a commit: 577dbc3c49615896d5b6fbf0cb25eebd4d28624a branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-11T20:11:17-04:00 summary: gh-95841: IDLE - Revise Windows local doc url (GH-95845) (#95905) GH-91242 replaced the Windows chm help file with a copy of the html docs. This PR replaces the IDLE code that fetches the Windows local help url passed to os.startfile. Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> Co-authored-by: Steve Dower Approved by Steve Dower, #95845 (review), 2nd subblock. (cherry picked from commit bdb2cf8e913c041f26e8976abe58414819b3e8ff) files: M Lib/idlelib/editor.py diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 859a288b4bc..08d6aa2efde 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -86,10 +86,20 @@ def __init__(self, flist=None, filename=None, key=None, root=None): dochome = os.path.join(basepath, pyver, 'Doc', 'index.html') elif sys.platform[:3] == 'win': - chmfile = os.path.join(sys.base_prefix, 'Doc', - 'Python%s.chm' % _sphinx_version()) - if os.path.isfile(chmfile): - dochome = chmfile + import winreg # Windows only, block only executed once. + docfile = '' + KEY = (rf"Software\Python\PythonCore\{sys.winver}" + r"\Help\Main Python Documentation") + try: + docfile = winreg.QueryValue(winreg.HKEY_CURRENT_USER, KEY) + except FileNotFoundError: + try: + docfile = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, + KEY) + except FileNotFoundError: + pass + if os.path.isfile(docfile): + dochome = docfile elif sys.platform == 'darwin': # documentation may be stored inside a python framework dochome = os.path.join(sys.base_prefix, From webhook-mailer at python.org Fri Aug 12 03:34:36 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 12 Aug 2022 07:34:36 -0000 Subject: [Python-checkins] [3.11] gh-95273: Improve sqlite3.complete_statement docs (GH-95840) (#95917) Message-ID: <mailman.634.1660289677.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bd86e09ab9f6f49e7c973de591187d82c5382682 commit: bd86e09ab9f6f49e7c973de591187d82c5382682 branch: 3.11 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-12T09:34:26+02:00 summary: [3.11] gh-95273: Improve sqlite3.complete_statement docs (GH-95840) (#95917) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM>. (cherry picked from commit e6623e7083ce08a247e5df169bcc749f99327823) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: D Doc/includes/sqlite3/complete_statement.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py deleted file mode 100644 index a5c947969910..000000000000 --- a/Doc/includes/sqlite3/complete_statement.py +++ /dev/null @@ -1,33 +0,0 @@ -# A minimal SQLite shell for experiments - -import sqlite3 - -con = sqlite3.connect(":memory:") -con.isolation_level = None -cur = con.cursor() - -buffer = "" - -print("Enter your SQL commands to execute in sqlite3.") -print("Enter a blank line to exit.") - -while True: - line = input() - if line == "": - break - buffer += line - if sqlite3.complete_statement(buffer): - try: - buffer = buffer.strip() - cur.execute(buffer) - - if buffer.lstrip().upper().startswith("SELECT"): - print(cur.fetchall()) - except sqlite3.Error as e: - err_msg = str(e) - err_code = e.sqlite_errorcode - err_name = e.sqlite_errorname - print(f"{err_name} ({err_code}): {err_msg}") - buffer = "" - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 1afb8c87b389..b4b98a50d8b7 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -222,14 +222,22 @@ Module functions .. function:: complete_statement(statement) - Returns ``True`` if the string *statement* contains one or more complete SQL - statements terminated by semicolons. It does not verify that the SQL is - syntactically correct, only that there are no unclosed string literals and the - statement is terminated by a semicolon. - - This can be used to build a shell for SQLite, as in the following example: - - .. literalinclude:: ../includes/sqlite3/complete_statement.py + Return ``True`` if the string *statement* appears to contain + one or more complete SQL statements. + No syntactic verification or parsing of any kind is performed, + other than checking that there are no unclosed string literals + and the statement is terminated by a semicolon. + + For example:: + + >>> sqlite3.complete_statement("SELECT foo FROM bar;") + True + >>> sqlite3.complete_statement("SELECT foo") + False + + This function may be useful during command-line input + to determine if the entered text seems to form a complete SQL statement, + or if additional input is needed before calling :meth:`~Cursor.execute`. .. function:: enable_callback_tracebacks(flag, /) From webhook-mailer at python.org Fri Aug 12 03:37:49 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 12 Aug 2022 07:37:49 -0000 Subject: [Python-checkins] [3.10] gh-95273: Improve sqlite3.complete_statement docs (GH-95840) (#95918) Message-ID: <mailman.635.1660289870.3313.python-checkins@python.org> https://github.com/python/cpython/commit/75299dcab541e4e98603ebfb3f95eb9315c4ac52 commit: 75299dcab541e4e98603ebfb3f95eb9315c4ac52 branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-12T09:37:45+02:00 summary: [3.10] gh-95273: Improve sqlite3.complete_statement docs (GH-95840) (#95918) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM>. (cherry picked from commit e6623e7083ce08a247e5df169bcc749f99327823) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: D Doc/includes/sqlite3/complete_statement.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py deleted file mode 100644 index cd38d7305bb6..000000000000 --- a/Doc/includes/sqlite3/complete_statement.py +++ /dev/null @@ -1,30 +0,0 @@ -# A minimal SQLite shell for experiments - -import sqlite3 - -con = sqlite3.connect(":memory:") -con.isolation_level = None -cur = con.cursor() - -buffer = "" - -print("Enter your SQL commands to execute in sqlite3.") -print("Enter a blank line to exit.") - -while True: - line = input() - if line == "": - break - buffer += line - if sqlite3.complete_statement(buffer): - try: - buffer = buffer.strip() - cur.execute(buffer) - - if buffer.lstrip().upper().startswith("SELECT"): - print(cur.fetchall()) - except sqlite3.Error as e: - print("An error occurred:", e.args[0]) - buffer = "" - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 219c41e2b197..ff90feb471c3 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -222,14 +222,22 @@ Module functions .. function:: complete_statement(statement) - Returns ``True`` if the string *statement* contains one or more complete SQL - statements terminated by semicolons. It does not verify that the SQL is - syntactically correct, only that there are no unclosed string literals and the - statement is terminated by a semicolon. - - This can be used to build a shell for SQLite, as in the following example: - - .. literalinclude:: ../includes/sqlite3/complete_statement.py + Return ``True`` if the string *statement* appears to contain + one or more complete SQL statements. + No syntactic verification or parsing of any kind is performed, + other than checking that there are no unclosed string literals + and the statement is terminated by a semicolon. + + For example:: + + >>> sqlite3.complete_statement("SELECT foo FROM bar;") + True + >>> sqlite3.complete_statement("SELECT foo") + False + + This function may be useful during command-line input + to determine if the entered text seems to form a complete SQL statement, + or if additional input is needed before calling :meth:`~Cursor.execute`. .. function:: enable_callback_tracebacks(flag, /) From webhook-mailer at python.org Fri Aug 12 11:35:18 2022 From: webhook-mailer at python.org (iritkatriel) Date: Fri, 12 Aug 2022 15:35:18 -0000 Subject: [Python-checkins] gh-95922: compiler's eliminate_empty_basic_blocks ignores the last block of the compilation unit (GH-95924) Message-ID: <mailman.636.1660318519.3313.python-checkins@python.org> https://github.com/python/cpython/commit/41757bfabd26ef1d01dcde1d2bbf90e1a8d9d62c commit: 41757bfabd26ef1d01dcde1d2bbf90e1a8d9d62c branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-12T16:35:09+01:00 summary: gh-95922: compiler's eliminate_empty_basic_blocks ignores the last block of the compilation unit (GH-95924) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-12-13-04-25.gh-issue-95922.YNCtyX.rst M Python/compile.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-12-13-04-25.gh-issue-95922.YNCtyX.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-12-13-04-25.gh-issue-95922.YNCtyX.rst new file mode 100644 index 00000000000..277d35deab3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-12-13-04-25.gh-issue-95922.YNCtyX.rst @@ -0,0 +1,2 @@ +Fixed bug where the compiler's ``eliminate_empty_basic_blocks`` function +ignores the last block of the code unit. diff --git a/Python/compile.c b/Python/compile.c index a971b09c530..3dec7b5edfb 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -9349,17 +9349,13 @@ eliminate_empty_basic_blocks(basicblock *entryblock) { /* Eliminate empty blocks */ for (basicblock *b = entryblock; b != NULL; b = b->b_next) { basicblock *next = b->b_next; - if (next) { - while (next->b_iused == 0 && next->b_next) { - next = next->b_next; - } - b->b_next = next; + while (next && next->b_iused == 0) { + next = next->b_next; } + b->b_next = next; } for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } + assert(b->b_iused > 0); for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; if (HAS_TARGET(instr->i_opcode)) { @@ -9368,6 +9364,7 @@ eliminate_empty_basic_blocks(basicblock *entryblock) { target = target->b_next; } instr->i_target = target; + assert(instr->i_target && instr->i_target->b_iused > 0); } } } From webhook-mailer at python.org Fri Aug 12 11:50:27 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 15:50:27 -0000 Subject: [Python-checkins] gh-95914: Add missing PEPs to the Summary section of 3.11 What's New (GH-95916) Message-ID: <mailman.637.1660319427.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6376433ac3c71a4742ec6577054c7edf5ab37134 commit: 6376433ac3c71a4742ec6577054c7edf5ab37134 branch: main author: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> committer: ambv <lukasz at langa.pl> date: 2022-08-12T17:50:01+02:00 summary: gh-95914: Add missing PEPs to the Summary section of 3.11 What's New (GH-95916) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 7e1130e8ea30..d5d7da292b21 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -49,13 +49,14 @@ This article explains the new features in Python 3.11, compared to 3.10. For full details, see the :ref:`changelog <changelog>`. + Summary -- Release highlights ============================= .. This section singles out the most important changes in Python 3.11. Brevity is key. -- Python 3.11 is up to 10-60% faster than Python 3.10. On average, we measured a +- Python 3.11 is between 10-60% faster than Python 3.10. On average, we measured a 1.25x speedup on the standard benchmark suite. See `Faster CPython`_ for details. .. PEP-sized items next. @@ -65,18 +66,35 @@ New syntax features: * :pep:`654`: Exception Groups and ``except*``. (Contributed by Irit Katriel in :issue:`45292`.) +New built-in features: + +* :pep:`678`: Enriching Exceptions with Notes. + +New standard library modules: + +* :pep:`680`: ``tomllib`` ? Support for Parsing TOML in the Standard Library. + +Interpreter improvements: + +* :pep:`657`: Include Fine Grained Error Locations in Tracebacks. +* New :option:`-P` command line option and :envvar:`PYTHONSAFEPATH` environment + variable to disable automatically prepending a potentially unsafe path + (the working dir or script directory, depending on invocation) + to :data:`sys.path`. + New typing features: * :pep:`646`: Variadic generics. * :pep:`655`: Marking individual TypedDict items as required or potentially missing. * :pep:`673`: ``Self`` type. * :pep:`675`: Arbitrary literal string type. +* :pep:`681`: Data Class Transforms. -Security improvements: +Important deprecations, removals or restrictions: -* New :option:`-P` command line option and :envvar:`PYTHONSAFEPATH` environment - variable to not prepend a potentially unsafe path to :data:`sys.path` such as - the current directory, the script's directory or an empty string. +* :pep:`594`: Removing dead batteries from the standard library. +* :pep:`624`: Remove ``Py_UNICODE`` encoder APIs. +* :pep:`670`: Convert macros to functions in the Python C API. New Features From webhook-mailer at python.org Fri Aug 12 12:07:17 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 16:07:17 -0000 Subject: [Python-checkins] [3.11] gh-90300: [docs] Add whatsnew entry for new --help output (GH-95856) Message-ID: <mailman.638.1660320438.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e3adb19df82c0f19086e6cfced531ef8d8fb6d5b commit: e3adb19df82c0f19086e6cfced531ef8d8fb6d5b branch: 3.11 author: ?ric <merwok at netwok.org> committer: ambv <lukasz at langa.pl> date: 2022-08-12T18:07:05+02:00 summary: [3.11] gh-90300: [docs] Add whatsnew entry for new --help output (GH-95856) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index f25bc549bf53..76aa6880ec06 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -417,6 +417,12 @@ Other CPython Implementation Changes :data:`sys.path`. Otherwise, initialization will recalculate the path and replace any values added to ``module_search_paths``. +* The output of the :option:`--help` option is changed to fit inside 50 lines and 80 + columns. Information about :ref:`Python environment variables <using-on-envvars>` + and :option:`-X options <-X>` is available with the new :option:`--help-env` or + :option:`--help-xoptions` flags, and with :option:`--help-all`. + (Contributed by ?ric Araujo in :issue:`46142`.) + New Modules =========== From webhook-mailer at python.org Fri Aug 12 12:13:45 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 16:13:45 -0000 Subject: [Python-checkins] gh-95914: Add missing PEPs to the Summary section of 3.11 What's New (GH-95916) (GH-95927) Message-ID: <mailman.639.1660320826.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5cc3964a32da4969397b8a14a1f5f8e6103f8c01 commit: 5cc3964a32da4969397b8a14a1f5f8e6103f8c01 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-12T18:13:38+02:00 summary: gh-95914: Add missing PEPs to the Summary section of 3.11 What's New (GH-95916) (GH-95927) (cherry picked from commit 6376433ac3c71a4742ec6577054c7edf5ab37134) Co-authored-by: CAM Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 76aa6880ec06..0c37cc451719 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -49,13 +49,14 @@ This article explains the new features in Python 3.11, compared to 3.10. For full details, see the :ref:`changelog <changelog>`. + Summary -- Release highlights ============================= .. This section singles out the most important changes in Python 3.11. Brevity is key. -- Python 3.11 is up to 10-60% faster than Python 3.10. On average, we measured a +- Python 3.11 is between 10-60% faster than Python 3.10. On average, we measured a 1.25x speedup on the standard benchmark suite. See `Faster CPython`_ for details. .. PEP-sized items next. @@ -65,18 +66,35 @@ New syntax features: * :pep:`654`: Exception Groups and ``except*``. (Contributed by Irit Katriel in :issue:`45292`.) +New built-in features: + +* :pep:`678`: Enriching Exceptions with Notes. + +New standard library modules: + +* :pep:`680`: ``tomllib`` ? Support for Parsing TOML in the Standard Library. + +Interpreter improvements: + +* :pep:`657`: Include Fine Grained Error Locations in Tracebacks. +* New :option:`-P` command line option and :envvar:`PYTHONSAFEPATH` environment + variable to disable automatically prepending a potentially unsafe path + (the working dir or script directory, depending on invocation) + to :data:`sys.path`. + New typing features: * :pep:`646`: Variadic generics. * :pep:`655`: Marking individual TypedDict items as required or potentially missing. * :pep:`673`: ``Self`` type. * :pep:`675`: Arbitrary literal string type. +* :pep:`681`: Data Class Transforms. -Security improvements: +Important deprecations, removals or restrictions: -* New :option:`-P` command line option and :envvar:`PYTHONSAFEPATH` environment - variable to not prepend a potentially unsafe path to :data:`sys.path` such as - the current directory, the script's directory or an empty string. +* :pep:`594`: Removing dead batteries from the standard library. +* :pep:`624`: Remove ``Py_UNICODE`` encoder APIs. +* :pep:`670`: Convert macros to functions in the Python C API. New Features From webhook-mailer at python.org Fri Aug 12 12:15:50 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 16:15:50 -0000 Subject: [Python-checkins] [3.10] gh-95789: update documentation RFC base URL (GH-95800) Message-ID: <mailman.640.1660320951.3313.python-checkins@python.org> https://github.com/python/cpython/commit/345daea0760339d55a9e6e34e1b190c5c081c1e6 commit: 345daea0760339d55a9e6e34e1b190c5c081c1e6 branch: 3.10 author: Julian Maurin <julian.maurin.perso at pm.me> committer: ambv <lukasz at langa.pl> date: 2022-08-12T18:15:45+02:00 summary: [3.10] gh-95789: update documentation RFC base URL (GH-95800) * pythongh-95789: update documentation RFC base URL * ?? Added by blurb_it. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Doc/docutils.conf A Misc/NEWS.d/next/Documentation/2022-08-09-16-11-36.gh-issue-95789.UO7fJL.rst diff --git a/Doc/docutils.conf b/Doc/docutils.conf new file mode 100644 index 000000000000..75995adfc2c7 --- /dev/null +++ b/Doc/docutils.conf @@ -0,0 +1,8 @@ +# +# Python documentation docutils configuration file +# +# https://docutils.sourceforge.io/docs/user/config.html + +[parsers] +# Override the default RFC base URL from sphinx +rfc_base_url=https://datatracker.ietf.org/doc/html/ diff --git a/Misc/NEWS.d/next/Documentation/2022-08-09-16-11-36.gh-issue-95789.UO7fJL.rst b/Misc/NEWS.d/next/Documentation/2022-08-09-16-11-36.gh-issue-95789.UO7fJL.rst new file mode 100644 index 000000000000..e034686e0ce7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-09-16-11-36.gh-issue-95789.UO7fJL.rst @@ -0,0 +1 @@ +Update the default RFC base URL from deprecated tools.ietf.org to datatracker.ietf.org From webhook-mailer at python.org Fri Aug 12 12:19:17 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 16:19:17 -0000 Subject: [Python-checkins] gh-92412: Clarify the documentation on library/syslog (GH-92587) (GH-95266) Message-ID: <mailman.641.1660321158.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e21574a823c4811172f29644b5294f22072a1e86 commit: e21574a823c4811172f29644b5294f22072a1e86 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-12T18:19:08+02:00 summary: gh-92412: Clarify the documentation on library/syslog (GH-92587) (GH-95266) (cherry picked from commit b7ce4625fe2a8a4d6c1db6b39b52c7f97d384caa) Co-authored-by: Nicolas Haller <nicolas at haller.im> files: M Doc/library/syslog.rst diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index d264a3340c9..ce51856ab7b 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -29,10 +29,15 @@ The module defines the following functions: value given in the :func:`openlog` call is used. If :func:`openlog` has not been called prior to the call to :func:`syslog`, - ``openlog()`` will be called with no arguments. + :func:`openlog` will be called with no arguments. .. audit-event:: syslog.syslog priority,message syslog.syslog + .. versionchanged:: 3.2 + In previous versions, :func:`openlog` would not be called automatically if + it wasn't called prior to the call to :func:`syslog`, deferring to the syslog + implementation to call ``openlog()``. + .. function:: openlog([ident[, logoption[, facility]]]) @@ -51,8 +56,7 @@ The module defines the following functions: .. versionchanged:: 3.2 In previous versions, keyword arguments were not allowed, and *ident* was - required. The default for *ident* was dependent on the system libraries, - and often was ``python`` instead of the name of the Python program file. + required. .. function:: closelog() From webhook-mailer at python.org Fri Aug 12 12:22:16 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 16:22:16 -0000 Subject: [Python-checkins] gh-82180: Document support for non-integer arg removed from grp.getgrgid in 3.10 (GH-95346) Message-ID: <mailman.642.1660321338.3313.python-checkins@python.org> https://github.com/python/cpython/commit/50bf5fafcceacf8d7460fd8f9fb4297ac74d3eac commit: 50bf5fafcceacf8d7460fd8f9fb4297ac74d3eac branch: main author: Hugo van Kemenade <hugovk at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-12T18:22:06+02:00 summary: gh-82180: Document support for non-integer arg removed from grp.getgrgid in 3.10 (GH-95346) files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index fabc22e4cf5..14af744e3ae 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -45,9 +45,8 @@ It defines the following items: Return the group database entry for the given numeric group ID. :exc:`KeyError` is raised if the entry asked for cannot be found. - .. deprecated:: 3.6 - Since Python 3.6 the support of non-integer arguments like floats or - strings in :func:`getgrgid` is deprecated. + .. versionchanged:: 3.10 + :exc:`TypeError` is raised for non-integer arguments like floats or strings. .. function:: getgrnam(name) From webhook-mailer at python.org Fri Aug 12 12:22:29 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 16:22:29 -0000 Subject: [Python-checkins] gh-90300: [docs] Add whatsnew entry for new --help output (GH-95856) (GH-95928) Message-ID: <mailman.643.1660321350.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d2373fcb498888e3faa47747a57791f0ed82c91e commit: d2373fcb498888e3faa47747a57791f0ed82c91e branch: main author: ?ukasz Langa <lukasz at langa.pl> committer: ambv <lukasz at langa.pl> date: 2022-08-12T18:22:25+02:00 summary: gh-90300: [docs] Add whatsnew entry for new --help output (GH-95856) (GH-95928) Co-authored-by: ?ric <merwok at netwok.org> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index d5d7da292b2..41aa6944395 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -435,6 +435,12 @@ Other CPython Implementation Changes :data:`sys.path`. Otherwise, initialization will recalculate the path and replace any values added to ``module_search_paths``. +* The output of the :option:`--help` option is changed to fit inside 50 lines and 80 + columns. Information about :ref:`Python environment variables <using-on-envvars>` + and :option:`-X options <-X>` is available with the new :option:`--help-env` or + :option:`--help-xoptions` flags, and with :option:`--help-all`. + (Contributed by ?ric Araujo in :issue:`46142`.) + New Modules =========== From webhook-mailer at python.org Fri Aug 12 13:03:14 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 17:03:14 -0000 Subject: [Python-checkins] gh-82180: Document support for non-integer arg removed from grp.getgrgid in 3.10 (GH-95346) (GH-95929) Message-ID: <mailman.644.1660323795.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7fdda1a47fe6f83a76248a9f142de67a347c137b commit: 7fdda1a47fe6f83a76248a9f142de67a347c137b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-12T19:03:04+02:00 summary: gh-82180: Document support for non-integer arg removed from grp.getgrgid in 3.10 (GH-95346) (GH-95929) (cherry picked from commit 50bf5fafcceacf8d7460fd8f9fb4297ac74d3eac) Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com> files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index fabc22e4cf5..14af744e3ae 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -45,9 +45,8 @@ It defines the following items: Return the group database entry for the given numeric group ID. :exc:`KeyError` is raised if the entry asked for cannot be found. - .. deprecated:: 3.6 - Since Python 3.6 the support of non-integer arguments like floats or - strings in :func:`getgrgid` is deprecated. + .. versionchanged:: 3.10 + :exc:`TypeError` is raised for non-integer arguments like floats or strings. .. function:: getgrnam(name) From webhook-mailer at python.org Fri Aug 12 13:03:42 2022 From: webhook-mailer at python.org (ambv) Date: Fri, 12 Aug 2022 17:03:42 -0000 Subject: [Python-checkins] gh-82180: Document support for non-integer arg removed from grp.getgrgid in 3.10 (GH-95346) (GH-95930) Message-ID: <mailman.645.1660323822.3313.python-checkins@python.org> https://github.com/python/cpython/commit/44bf05ed0cea7f9ddc0713daed38d9bb2f35c981 commit: 44bf05ed0cea7f9ddc0713daed38d9bb2f35c981 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv <lukasz at langa.pl> date: 2022-08-12T19:03:37+02:00 summary: gh-82180: Document support for non-integer arg removed from grp.getgrgid in 3.10 (GH-95346) (GH-95930) (cherry picked from commit 50bf5fafcceacf8d7460fd8f9fb4297ac74d3eac) Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com> files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index baa31752a2c..69598d43f99 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -43,9 +43,8 @@ It defines the following items: Return the group database entry for the given numeric group ID. :exc:`KeyError` is raised if the entry asked for cannot be found. - .. deprecated:: 3.6 - Since Python 3.6 the support of non-integer arguments like floats or - strings in :func:`getgrgid` is deprecated. + .. versionchanged:: 3.10 + :exc:`TypeError` is raised for non-integer arguments like floats or strings. .. function:: getgrnam(name) From webhook-mailer at python.org Fri Aug 12 13:27:54 2022 From: webhook-mailer at python.org (lysnikolaou) Date: Fri, 12 Aug 2022 17:27:54 -0000 Subject: [Python-checkins] gh-94996: Disallow parsing pos only params with feature_version < (3, 8) (GH-94997) Message-ID: <mailman.646.1660325275.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b5e3ea286289fcad12be78480daf3756e350f69f commit: b5e3ea286289fcad12be78480daf3756e350f69f branch: main author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: lysnikolaou <lisandrosnik at gmail.com> date: 2022-08-12T19:27:50+02:00 summary: gh-94996: Disallow parsing pos only params with feature_version < (3, 8) (GH-94997) files: A Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst M Grammar/python.gram M Lib/test/test_ast.py M Lib/test/test_type_comments.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index 6a81e14decbd..afae85d72339 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -287,9 +287,9 @@ params[arguments_ty]: parameters[arguments_ty]: | 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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | 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)} diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index de34ccff2ef0..2f3e9d501901 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -738,6 +738,14 @@ def test_ast_asdl_signature(self): expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}" self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions) + def test_positional_only_feature_version(self): + ast.parse('def foo(x, /): ...', feature_version=(3, 8)) + ast.parse('def bar(x=1, /): ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('def foo(x, /): ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) # While advertised as a feature in Python 3.10, this was allowed starting 3.9 @@ -746,7 +754,7 @@ def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8)) ast.parse('with CtxManager() as example: ...', feature_version=(3, 8)) - def test_issue40614_feature_version(self): + def test_debug_f_string_feature_version(self): ast.parse('f"{x=}"', feature_version=(3, 8)) with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 668c1787f64d..8db7394d1512 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -322,7 +322,7 @@ def test_ignores(self): self.assertEqual(tree.type_ignores, []) def test_longargs(self): - for tree in self.parse_all(longargs): + for tree in self.parse_all(longargs, minver=8): for t in tree.body: # The expected args are encoded in the function name todo = set(t.name[1:]) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst new file mode 100644 index 000000000000..90c9ada079e0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst @@ -0,0 +1 @@ +:func:`ast.parse` will no longer parse function definitions with positional-only params when passed ``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. diff --git a/Parser/parser.c b/Parser/parser.c index f4082aba56a2..15e833af4771 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -4637,7 +4637,7 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -4667,7 +4667,7 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; From webhook-mailer at python.org Fri Aug 12 13:53:22 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 12 Aug 2022 17:53:22 -0000 Subject: [Python-checkins] gh-94996: Disallow parsing pos only params with feature_version < (3, 8) (GH-94997) Message-ID: <mailman.647.1660326803.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4abf84602f81da6719f761140dc909828350b45c commit: 4abf84602f81da6719f761140dc909828350b45c branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T10:53:09-07:00 summary: gh-94996: Disallow parsing pos only params with feature_version < (3, 8) (GH-94997) (cherry picked from commit b5e3ea286289fcad12be78480daf3756e350f69f) Co-authored-by: Shantanu <12621235+hauntsaninja at users.noreply.github.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst M Grammar/python.gram M Lib/test/test_ast.py M Lib/test/test_type_comments.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index 6a81e14decbd..afae85d72339 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -287,9 +287,9 @@ params[arguments_ty]: parameters[arguments_ty]: | 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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | 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)} diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 9734218c21be..a52fad834a6f 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -738,6 +738,14 @@ def test_ast_asdl_signature(self): expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}" self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions) + def test_positional_only_feature_version(self): + ast.parse('def foo(x, /): ...', feature_version=(3, 8)) + ast.parse('def bar(x=1, /): ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('def foo(x, /): ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) # While advertised as a feature in Python 3.10, this was allowed starting 3.9 @@ -746,7 +754,7 @@ def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8)) ast.parse('with CtxManager() as example: ...', feature_version=(3, 8)) - def test_issue40614_feature_version(self): + def test_debug_f_string_feature_version(self): ast.parse('f"{x=}"', feature_version=(3, 8)) with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 71d1430dbc93..7a348be6d3f1 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -323,7 +323,7 @@ def test_ignores(self): self.assertEqual(tree.type_ignores, []) def test_longargs(self): - for tree in self.parse_all(longargs): + for tree in self.parse_all(longargs, minver=8): for t in tree.body: # The expected args are encoded in the function name todo = set(t.name[1:]) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst new file mode 100644 index 000000000000..90c9ada079e0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst @@ -0,0 +1 @@ +:func:`ast.parse` will no longer parse function definitions with positional-only params when passed ``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. diff --git a/Parser/parser.c b/Parser/parser.c index e578fd73ad9b..9f3862f0fc00 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -4637,7 +4637,7 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -4667,7 +4667,7 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; From webhook-mailer at python.org Fri Aug 12 14:40:54 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 12 Aug 2022 18:40:54 -0000 Subject: [Python-checkins] GH-95818: Skip incomplete frames in `PyThreadState_GetFrame` (GH-95886) (#95890) Message-ID: <mailman.648.1660329655.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6fc90c11835f1af869a47724ab9742535b73fe7b commit: 6fc90c11835f1af869a47724ab9742535b73fe7b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-12T19:40:49+01:00 summary: GH-95818: Skip incomplete frames in `PyThreadState_GetFrame` (GH-95886) (#95890) (cherry picked from commit 1b46d118e6e72daa64b98cafddb406c68b419efa) Co-authored-by: Mark Shannon <mark at hotpy.org> Co-authored-by: Mark Shannon <mark at hotpy.org> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst M Lib/test/test_frame.py M Python/pystate.c diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index a715e725a7e4..9fab17684eec 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -235,6 +235,28 @@ def inner(): r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code inner>$" % (file_repr, offset + 5)) +class TestIncompleteFrameAreInvisible(unittest.TestCase): + + def test_issue95818(self): + #See GH-95818 for details + import gc + self.addCleanup(gc.set_threshold, *gc.get_threshold()) + + gc.set_threshold(1,1,1) + class GCHello: + def __del__(self): + print("Destroyed from gc") + + def gen(): + yield + + fd = open(__file__) + l = [fd, GCHello()] + l.append(l) + del fd + del l + gen() + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst new file mode 100644 index 000000000000..1e243f5614f1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst @@ -0,0 +1 @@ +Skip over incomplete frames in :c:func:`PyThreadState_GetFrame`. diff --git a/Python/pystate.c b/Python/pystate.c index df56c0530f05..2e4585688ea8 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1255,10 +1255,14 @@ PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { assert(tstate != NULL); - if (tstate->cframe->current_frame == NULL) { + _PyInterpreterFrame *f = tstate->cframe->current_frame; + while (f && _PyFrame_IsIncomplete(f)) { + f = f->previous; + } + if (f == NULL) { return NULL; } - PyFrameObject *frame = _PyFrame_GetFrameObject(tstate->cframe->current_frame); + PyFrameObject *frame = _PyFrame_GetFrameObject(f); if (frame == NULL) { PyErr_Clear(); } From webhook-mailer at python.org Fri Aug 12 14:41:06 2022 From: webhook-mailer at python.org (lysnikolaou) Date: Fri, 12 Aug 2022 18:41:06 -0000 Subject: [Python-checkins] gh-94996: Disallow lambda pos only params with feature_version < (3, 8) (GH-95934) Message-ID: <mailman.649.1660329667.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a965db37f27ffb232312bc13d9a509f0d93fcd20 commit: a965db37f27ffb232312bc13d9a509f0d93fcd20 branch: main author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: lysnikolaou <lisandrosnik at gmail.com> date: 2022-08-12T20:41:02+02:00 summary: gh-94996: Disallow lambda pos only params with feature_version < (3, 8) (GH-95934) files: M Grammar/python.gram M Lib/test/test_ast.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index afae85d72339..d4df78b679a4 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -830,9 +830,9 @@ lambda_params[arguments_ty]: # lambda_parameters[arguments_ty]: | 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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | 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)} diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 2f3e9d501901..4cfefe4ac3dd 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -746,6 +746,13 @@ def test_positional_only_feature_version(self): with self.assertRaises(SyntaxError): ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + ast.parse('lambda x, /: ...', feature_version=(3, 8)) + ast.parse('lambda x=1, /: ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x, /: ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x=1, /: ...', feature_version=(3, 7)) + def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) # While advertised as a feature in Python 3.10, this was allowed starting 3.9 diff --git a/Parser/parser.c b/Parser/parser.c index 15e833af4771..c9366d59923b 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -14659,7 +14659,7 @@ lambda_parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -14689,7 +14689,7 @@ lambda_parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; From webhook-mailer at python.org Fri Aug 12 15:03:48 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 12 Aug 2022 19:03:48 -0000 Subject: [Python-checkins] [3.10] gh-94996: Disallow parsing pos only params with feature_version < (3, 8) (GH-95935) Message-ID: <mailman.650.1660331029.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a92c2d6eb55a64881b978cfc4b531dad3d14984b commit: a92c2d6eb55a64881b978cfc4b531dad3d14984b branch: 3.10 author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T12:03:44-07:00 summary: [3.10] gh-94996: Disallow parsing pos only params with feature_version < (3, 8) (GH-95935) (cherry picked from commit https://github.com/python/cpython/commit/b5e3ea286289fcad12be78480daf3756e350f69f) Co-authored-by: Shantanu <12621235+hauntsaninja at users.noreply.github.com> Automerge-Triggered-By: GH:lysnikolaou files: A Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst M Grammar/python.gram M Lib/test/test_ast.py M Lib/test/test_type_comments.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index 7570748c3f9b..dcba7ad61b55 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -427,9 +427,9 @@ params[arguments_ty]: parameters[arguments_ty]: | 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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | 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)} diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index eb861096f65c..5bbee8c4c485 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -686,6 +686,14 @@ def test_ast_asdl_signature(self): expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}" self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions) + def test_positional_only_feature_version(self): + ast.parse('def foo(x, /): ...', feature_version=(3, 8)) + ast.parse('def bar(x=1, /): ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('def foo(x, /): ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) # While advertised as a feature in Python 3.10, this was allowed starting 3.9 @@ -694,7 +702,7 @@ def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8)) ast.parse('with CtxManager() as example: ...', feature_version=(3, 8)) - def test_issue40614_feature_version(self): + def test_debug_f_string_feature_version(self): ast.parse('f"{x=}"', feature_version=(3, 8)) with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 71d1430dbc93..7a348be6d3f1 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -323,7 +323,7 @@ def test_ignores(self): self.assertEqual(tree.type_ignores, []) def test_longargs(self): - for tree in self.parse_all(longargs): + for tree in self.parse_all(longargs, minver=8): for t in tree.body: # The expected args are encoded in the function name todo = set(t.name[1:]) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst new file mode 100644 index 000000000000..90c9ada079e0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-19-04-34-56.gh-issue-94996.dV564A.rst @@ -0,0 +1 @@ +:func:`ast.parse` will no longer parse function definitions with positional-only params when passed ``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. diff --git a/Parser/parser.c b/Parser/parser.c index c0080e80b565..cadb295de696 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -8997,7 +8997,7 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -9027,7 +9027,7 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; From webhook-mailer at python.org Fri Aug 12 15:41:28 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 12 Aug 2022 19:41:28 -0000 Subject: [Python-checkins] [3.11] gh-94996: Disallow lambda pos only params with feature_version < (3, 8) (GH-95934) (GH-95936) Message-ID: <mailman.651.1660333290.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7fc82217944c094bc490a95cf6c07fbf59644a2d commit: 7fc82217944c094bc490a95cf6c07fbf59644a2d branch: 3.11 author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T12:41:09-07:00 summary: [3.11] gh-94996: Disallow lambda pos only params with feature_version < (3, 8) (GH-95934) (GH-95936) (cherry picked from commit a965db37f27ffb232312bc13d9a509f0d93fcd20) Co-authored-by: Shantanu <12621235+hauntsaninja at users.noreply.github.com> Automerge-Triggered-By: GH:lysnikolaou files: M Grammar/python.gram M Lib/test/test_ast.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index afae85d72339..d4df78b679a4 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -830,9 +830,9 @@ lambda_params[arguments_ty]: # lambda_parameters[arguments_ty]: | 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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | 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)} diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index a52fad834a6f..80f2262aced3 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -746,6 +746,13 @@ def test_positional_only_feature_version(self): with self.assertRaises(SyntaxError): ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + ast.parse('lambda x, /: ...', feature_version=(3, 8)) + ast.parse('lambda x=1, /: ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x, /: ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x=1, /: ...', feature_version=(3, 7)) + def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) # While advertised as a feature in Python 3.10, this was allowed starting 3.9 diff --git a/Parser/parser.c b/Parser/parser.c index 9f3862f0fc00..e13dbe04cf98 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -14659,7 +14659,7 @@ lambda_parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -14689,7 +14689,7 @@ lambda_parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; From webhook-mailer at python.org Fri Aug 12 15:47:17 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 12 Aug 2022 19:47:17 -0000 Subject: [Python-checkins] [3.10] gh-94996: Disallow lambda pos only params with feature_version < (3, 8) (GH-95934) (GH-95938) Message-ID: <mailman.652.1660333638.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9fbc81760e8765f7520929acc5af7874aeccb0c1 commit: 9fbc81760e8765f7520929acc5af7874aeccb0c1 branch: 3.10 author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T12:47:07-07:00 summary: [3.10] gh-94996: Disallow lambda pos only params with feature_version < (3, 8) (GH-95934) (GH-95938) (cherry picked from commit a965db37f27ffb232312bc13d9a509f0d93fcd20) Co-authored-by: Shantanu <12621235+hauntsaninja at users.noreply.github.com> Automerge-Triggered-By: GH:lysnikolaou files: M Grammar/python.gram M Lib/test/test_ast.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index dcba7ad61b5..de582d2b82a 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -552,9 +552,9 @@ lambda_params[arguments_ty]: # lambda_parameters[arguments_ty]: | 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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _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) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | 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)} diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 5bbee8c4c48..03e43f74ee2 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -694,6 +694,13 @@ def test_positional_only_feature_version(self): with self.assertRaises(SyntaxError): ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + ast.parse('lambda x, /: ...', feature_version=(3, 8)) + ast.parse('lambda x=1, /: ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x, /: ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x=1, /: ...', feature_version=(3, 7)) + def test_parenthesized_with_feature_version(self): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) # While advertised as a feature in Python 3.10, this was allowed starting 3.9 diff --git a/Parser/parser.c b/Parser/parser.c index cadb295de69..458ada0e52b 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -11194,7 +11194,7 @@ lambda_parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -11224,7 +11224,7 @@ lambda_parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; From webhook-mailer at python.org Fri Aug 12 17:23:56 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 12 Aug 2022 21:23:56 -0000 Subject: [Python-checkins] gh-94909: fix joining of absolute and relative Windows paths in pathlib (GH-95450) Message-ID: <mailman.653.1660339437.3313.python-checkins@python.org> https://github.com/python/cpython/commit/187949ebf2ae36fcf0817a06f4a7637d0a8b7fc5 commit: 187949ebf2ae36fcf0817a06f4a7637d0a8b7fc5 branch: main author: Barney Gale <barney.gale at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T14:23:41-07:00 summary: gh-94909: fix joining of absolute and relative Windows paths in pathlib (GH-95450) Have pathlib use `os.path.join()` to join arguments to the `PurePath` initialiser, which fixes a minor bug when handling relative paths with drives. Previously: ```python >>> from pathlib import PureWindowsPath >>> a = 'C:/a/b' >>> b = 'C:x/y' >>> PureWindowsPath(a, b) PureWindowsPath('C:x/y') ``` Now: ```python >>> PureWindowsPath(a, b) PureWindowsPath('C:/a/b/x/y') ``` files: A Misc/NEWS.d/next/Library/2022-07-29-20-58-37.gh-issue-94909.YjMusj.rst M Lib/pathlib.py M Lib/test/test_pathlib.py diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 54da1c8a6253..0ea621cc6010 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -61,41 +61,16 @@ def __init__(self): self.join = self.sep.join def parse_parts(self, parts): - parsed = [] + if not parts: + return '', '', [] sep = self.sep altsep = self.altsep - drv = root = '' - it = reversed(parts) - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv, root, rel = self.splitroot(part) - if sep in rel: - for x in reversed(rel.split(sep)): - if x and x != '.': - parsed.append(sys.intern(x)) - else: - if rel and rel != '.': - parsed.append(sys.intern(rel)) - if drv or root: - if not drv: - # If no drive is present, try to find one in the previous - # parts. This makes the result of parsing e.g. - # ("C:", "/", "a") reasonably intuitive. - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv = self.splitroot(part)[0] - if drv: - break - break - if drv or root: - parsed.append(drv + root) - parsed.reverse() + path = self.pathmod.join(*parts) + if altsep: + path = path.replace(altsep, sep) + drv, root, rel = self.splitroot(path) + unfiltered_parsed = [drv + root] + rel.split(sep) + parsed = [sys.intern(x) for x in unfiltered_parsed if x and x != '.'] return drv, root, parsed def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 668af8030c0c..f324177ff855 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -136,6 +136,10 @@ def test_parse_parts(self): check(['a', '/b', 'c'], ('', '\\', ['\\', 'b', 'c'])) check(['Z:/a', '/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) check(['//?/Z:/a', '/b', 'c'], ('\\\\?\\Z:', '\\', ['\\\\?\\Z:\\', 'b', 'c'])) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + check(['c:/a/b', 'c:x/y'], ('c:', '\\', ['c:\\', 'a', 'b', 'x', 'y'])) + check(['c:/a/b', 'c:/x/y'], ('c:', '\\', ['c:\\', 'x', 'y'])) def test_splitroot(self): f = self.flavour.splitroot diff --git a/Misc/NEWS.d/next/Library/2022-07-29-20-58-37.gh-issue-94909.YjMusj.rst b/Misc/NEWS.d/next/Library/2022-07-29-20-58-37.gh-issue-94909.YjMusj.rst new file mode 100644 index 000000000000..b6d853888101 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-29-20-58-37.gh-issue-94909.YjMusj.rst @@ -0,0 +1,2 @@ +Fix incorrect joining of relative Windows paths with drives in +:class:`pathlib.PurePath` initializer. From webhook-mailer at python.org Fri Aug 12 23:40:46 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Sat, 13 Aug 2022 03:40:46 -0000 Subject: [Python-checkins] Fix typo in internal/pycore_atomic.h (GH-95939) Message-ID: <mailman.654.1660362047.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8281cbddc6f0fbc94f0c21cacfac79a2d4057a4b commit: 8281cbddc6f0fbc94f0c21cacfac79a2d4057a4b branch: main author: fluesvamp <105884371+fluesvamp at users.noreply.github.com> committer: Fidget-Spinner <28750310+Fidget-Spinner at users.noreply.github.com> date: 2022-08-13T11:40:41+08:00 summary: Fix typo in internal/pycore_atomic.h (GH-95939) files: M Include/internal/pycore_atomic.h diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 3d42e54464c..425d69f868b 100644 --- a/Include/internal/pycore_atomic.h +++ b/Include/internal/pycore_atomic.h @@ -236,7 +236,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) in hardware they will fall back to a full memory barrier as well. This might affect performance but likely only in some very specific and - hard to meassure scenario. + hard to measure scenario. */ #if defined(_M_IX86) || defined(_M_X64) typedef enum _Py_memory_order { From webhook-mailer at python.org Sat Aug 13 00:04:17 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 13 Aug 2022 04:04:17 -0000 Subject: [Python-checkins] Fix typo in internal/pycore_atomic.h (GH-95939) Message-ID: <mailman.655.1660363459.3313.python-checkins@python.org> https://github.com/python/cpython/commit/df9c12e287398173fb01a501aa2c332f8cd2128b commit: df9c12e287398173fb01a501aa2c332f8cd2128b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T21:04:06-07:00 summary: Fix typo in internal/pycore_atomic.h (GH-95939) (cherry picked from commit 8281cbddc6f0fbc94f0c21cacfac79a2d4057a4b) Co-authored-by: fluesvamp <105884371+fluesvamp at users.noreply.github.com> files: M Include/internal/pycore_atomic.h diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 3d42e54464c..425d69f868b 100644 --- a/Include/internal/pycore_atomic.h +++ b/Include/internal/pycore_atomic.h @@ -236,7 +236,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) in hardware they will fall back to a full memory barrier as well. This might affect performance but likely only in some very specific and - hard to meassure scenario. + hard to measure scenario. */ #if defined(_M_IX86) || defined(_M_X64) typedef enum _Py_memory_order { From webhook-mailer at python.org Sat Aug 13 00:05:42 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 13 Aug 2022 04:05:42 -0000 Subject: [Python-checkins] Fix typo in internal/pycore_atomic.h (GH-95939) Message-ID: <mailman.656.1660363543.3313.python-checkins@python.org> https://github.com/python/cpython/commit/83bde57f6e549b017116d2c89ef427ea0fb8dad4 commit: 83bde57f6e549b017116d2c89ef427ea0fb8dad4 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T21:05:37-07:00 summary: Fix typo in internal/pycore_atomic.h (GH-95939) (cherry picked from commit 8281cbddc6f0fbc94f0c21cacfac79a2d4057a4b) Co-authored-by: fluesvamp <105884371+fluesvamp at users.noreply.github.com> files: M Include/internal/pycore_atomic.h diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 3d42e54464c..425d69f868b 100644 --- a/Include/internal/pycore_atomic.h +++ b/Include/internal/pycore_atomic.h @@ -236,7 +236,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) in hardware they will fall back to a full memory barrier as well. This might affect performance but likely only in some very specific and - hard to meassure scenario. + hard to measure scenario. */ #if defined(_M_IX86) || defined(_M_X64) typedef enum _Py_memory_order { From webhook-mailer at python.org Sat Aug 13 00:23:49 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 13 Aug 2022 04:23:49 -0000 Subject: [Python-checkins] gh-94439: typing docs: Add minimum version to `__required_keys__` and `__optional_keys__` (#95373) Message-ID: <mailman.657.1660364631.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f235178beccf5eb5b47e770240f32d9ba24b26fd commit: f235178beccf5eb5b47e770240f32d9ba24b26fd branch: main author: Howie Zhao <howiezhaohr at hotmail.com> committer: JelleZijlstra <jelle.zijlstra at gmail.com> date: 2022-08-12T21:23:33-07:00 summary: gh-94439: typing docs: Add minimum version to `__required_keys__` and `__optional_keys__` (#95373) files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 4d422f539ad..c6dd6976f23 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1825,6 +1825,9 @@ These are not used in annotations. They are building blocks for declaring types. True .. attribute:: __required_keys__ + + .. versionadded:: 3.9 + .. attribute:: __optional_keys__ ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return @@ -1852,6 +1855,8 @@ These are not used in annotations. They are building blocks for declaring types. >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) True + .. versionadded:: 3.9 + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 From webhook-mailer at python.org Sat Aug 13 00:31:55 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 13 Aug 2022 04:31:55 -0000 Subject: [Python-checkins] gh-94439: typing docs: Add minimum version to `__required_keys__` and `__optional_keys__` (GH-95373) Message-ID: <mailman.658.1660365116.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a372a7d65320396d44e8beb976e3a6c382963d4e commit: a372a7d65320396d44e8beb976e3a6c382963d4e branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-12T21:31:51-07:00 summary: gh-94439: typing docs: Add minimum version to `__required_keys__` and `__optional_keys__` (GH-95373) (cherry picked from commit f235178beccf5eb5b47e770240f32d9ba24b26fd) Co-authored-by: Howie Zhao <howiezhaohr at hotmail.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 1b7cf31d7cd..f0a85d6a365 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1544,6 +1544,9 @@ These are not used in annotations. They are building blocks for declaring types. True .. attribute:: __required_keys__ + + .. versionadded:: 3.9 + .. attribute:: __optional_keys__ ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return @@ -1566,6 +1569,8 @@ These are not used in annotations. They are building blocks for declaring types. >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) True + .. versionadded:: 3.9 + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 From webhook-mailer at python.org Sat Aug 13 06:10:18 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Sat, 13 Aug 2022 10:10:18 -0000 Subject: [Python-checkins] gh-90928: Improve static initialization of keywords tuple in AC (#95907) Message-ID: <mailman.659.1660385419.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f07adf82f338ebb7e69475537be050e63c2009fa commit: f07adf82f338ebb7e69475537be050e63c2009fa branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-13T12:09:40+02:00 summary: gh-90928: Improve static initialization of keywords tuple in AC (#95907) files: M Lib/test/clinic.test M Modules/_blake2/clinic/blake2b_impl.c.h M Modules/_blake2/clinic/blake2s_impl.c.h M Modules/_io/clinic/_iomodule.c.h M Modules/_io/clinic/bufferedio.c.h M Modules/_io/clinic/bytesio.c.h M Modules/_io/clinic/fileio.c.h M Modules/_io/clinic/stringio.c.h M Modules/_io/clinic/textio.c.h M Modules/_io/clinic/winconsoleio.c.h M Modules/_multiprocessing/clinic/posixshmem.c.h M Modules/_multiprocessing/clinic/semaphore.c.h M Modules/_sha3/clinic/sha3module.c.h M Modules/_sqlite/clinic/connection.c.h M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/clinic/module.c.h M Modules/_sre/clinic/sre.c.h M Modules/_ssl/clinic/cert.c.h M Modules/cjkcodecs/clinic/multibytecodec.c.h M Modules/clinic/_asynciomodule.c.h M Modules/clinic/_bisectmodule.c.h M Modules/clinic/_bz2module.c.h M Modules/clinic/_codecsmodule.c.h M Modules/clinic/_csv.c.h M Modules/clinic/_curses_panel.c.h M Modules/clinic/_cursesmodule.c.h M Modules/clinic/_datetimemodule.c.h M Modules/clinic/_dbmmodule.c.h M Modules/clinic/_elementtree.c.h M Modules/clinic/_gdbmmodule.c.h M Modules/clinic/_hashopenssl.c.h M Modules/clinic/_lzmamodule.c.h M Modules/clinic/_opcode.c.h M Modules/clinic/_pickle.c.h M Modules/clinic/_queuemodule.c.h M Modules/clinic/_ssl.c.h M Modules/clinic/_struct.c.h M Modules/clinic/_testmultiphase.c.h M Modules/clinic/_winapi.c.h M Modules/clinic/arraymodule.c.h M Modules/clinic/binascii.c.h M Modules/clinic/cmathmodule.c.h M Modules/clinic/gcmodule.c.h M Modules/clinic/grpmodule.c.h M Modules/clinic/itertoolsmodule.c.h M Modules/clinic/mathmodule.c.h M Modules/clinic/md5module.c.h M Modules/clinic/overlapped.c.h M Modules/clinic/posixmodule.c.h M Modules/clinic/pyexpat.c.h M Modules/clinic/selectmodule.c.h M Modules/clinic/sha1module.c.h M Modules/clinic/sha256module.c.h M Modules/clinic/sha512module.c.h M Modules/clinic/socketmodule.c.h M Modules/clinic/zlibmodule.c.h M Objects/clinic/bytearrayobject.c.h M Objects/clinic/bytesobject.c.h M Objects/clinic/codeobject.c.h M Objects/clinic/complexobject.c.h M Objects/clinic/descrobject.c.h M Objects/clinic/enumobject.c.h M Objects/clinic/funcobject.c.h M Objects/clinic/listobject.c.h M Objects/clinic/longobject.c.h M Objects/clinic/memoryobject.c.h M Objects/clinic/moduleobject.c.h M Objects/clinic/odictobject.c.h M Objects/clinic/structseq.c.h M Objects/clinic/unicodeobject.c.h M Objects/stringlib/clinic/transmogrify.h.h M PC/clinic/_testconsole.c.h M PC/clinic/winreg.c.h M PC/clinic/winsound.c.h M Python/clinic/Python-tokenize.c.h M Python/clinic/_warnings.c.h M Python/clinic/bltinmodule.c.h M Python/clinic/import.c.h M Python/clinic/sysmodule.c.h M Python/clinic/traceback.c.h M Tools/clinic/clinic.py diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index 7169a3b0d173..c73a75b163fa 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -1930,18 +1930,9 @@ static PyObject * test_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1950,13 +1941,12 @@ test_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", NULL}; static _PyArg_Parser _parser = { @@ -1983,7 +1973,7 @@ exit: static PyObject * test_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=81a23d66426e594e input=0d3484844749c05b]*/ +/*[clinic end generated code: output=73d46a9ae3320f96 input=0d3484844749c05b]*/ /*[clinic input] @@ -2010,18 +2000,9 @@ static PyObject * test_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2030,13 +2011,12 @@ test_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", NULL}; static _PyArg_Parser _parser = { @@ -2063,7 +2043,7 @@ exit: static PyObject * test_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=26470df56608cccd input=384adc78bfa0bff7]*/ +/*[clinic end generated code: output=c9f02a41f425897d input=384adc78bfa0bff7]*/ /*[clinic input] @@ -2091,18 +2071,9 @@ static PyObject * test_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2111,13 +2082,12 @@ test_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", "c", NULL}; static _PyArg_Parser _parser = { @@ -2157,7 +2127,7 @@ exit: static PyObject * test_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=3408978bedb2d3f9 input=eda7964f784f4607]*/ +/*[clinic end generated code: output=b35d4e66f7283e46 input=eda7964f784f4607]*/ /*[clinic input] @@ -2187,18 +2157,9 @@ static PyObject * test_keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2207,13 +2168,12 @@ test_keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; static _PyArg_Parser _parser = { @@ -2264,7 +2224,7 @@ exit: static PyObject * test_keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=becd35b9038b2a64 input=209387a4815e5082]*/ +/*[clinic end generated code: output=ede7e6e65106bf2b input=209387a4815e5082]*/ /*[clinic input] @@ -2293,18 +2253,9 @@ static PyObject * test_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2313,13 +2264,12 @@ test_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", "c", NULL}; static _PyArg_Parser _parser = { @@ -2359,7 +2309,7 @@ exit: static PyObject * test_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=f853e626095f43bc input=18393cc64fa000f4]*/ +/*[clinic end generated code: output=36d4df939a4c3eef input=18393cc64fa000f4]*/ /*[clinic input] @@ -2386,18 +2336,9 @@ static PyObject * test_posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2406,13 +2347,12 @@ test_posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", NULL}; static _PyArg_Parser _parser = { @@ -2439,7 +2379,7 @@ exit: static PyObject * test_posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=3b097475f4929159 input=1767b0ebdf06060e]*/ +/*[clinic end generated code: output=4835f4b6cf386c28 input=1767b0ebdf06060e]*/ /*[clinic input] @@ -2467,18 +2407,9 @@ static PyObject * test_posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2487,13 +2418,12 @@ test_posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "c", NULL}; static _PyArg_Parser _parser = { @@ -2520,7 +2450,7 @@ exit: static PyObject * test_posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *c) -/*[clinic end generated code: output=ef7fa0f9e58a0335 input=9042f2818f664839]*/ +/*[clinic end generated code: output=2570ea156a8d3cb5 input=9042f2818f664839]*/ /*[clinic input] @@ -2550,18 +2480,9 @@ static PyObject * test_posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2570,13 +2491,12 @@ test_posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", NULL}; static _PyArg_Parser _parser = { @@ -2606,7 +2526,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=0b6617a6d5a560c8 input=29546ebdca492fea]*/ +/*[clinic end generated code: output=aaa0e6b5ce02900d input=29546ebdca492fea]*/ /*[clinic input] @@ -2636,18 +2556,9 @@ static PyObject * test_posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2656,13 +2567,12 @@ test_posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", "d", NULL}; static _PyArg_Parser _parser = { @@ -2704,7 +2614,7 @@ exit: static PyObject * test_posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=ad36c238a8627f8d input=cdf5a9625e554e9b]*/ +/*[clinic end generated code: output=1d9f2d8420d0a85f input=cdf5a9625e554e9b]*/ /*[clinic input] @@ -2733,18 +2643,9 @@ static PyObject * test_posonly_keywords_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2753,13 +2654,12 @@ test_posonly_keywords_opt2(PyObject *module, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", NULL}; static _PyArg_Parser _parser = { @@ -2799,7 +2699,7 @@ exit: static PyObject * test_posonly_keywords_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=7abd948bad976638 input=1581299d21d16f14]*/ +/*[clinic end generated code: output=a83caa0505b296cf input=1581299d21d16f14]*/ /*[clinic input] @@ -2829,18 +2729,9 @@ static PyObject * test_posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2849,13 +2740,12 @@ test_posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(c), &_Py_ID(d), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "c", "d", NULL}; static _PyArg_Parser _parser = { @@ -2902,7 +2792,7 @@ exit: static PyObject * test_posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=e702747150ad367d input=408798ec3d42949f]*/ +/*[clinic end generated code: output=0b24fba3dc04d26b input=408798ec3d42949f]*/ /*[clinic input] @@ -2933,18 +2823,9 @@ static PyObject * test_posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2953,13 +2834,12 @@ test_posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", "d", NULL}; static _PyArg_Parser _parser = { @@ -3001,7 +2881,7 @@ exit: static PyObject * test_posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=79deca12adfac6a3 input=8d8e5643bbbc2309]*/ +/*[clinic end generated code: output=592b217bca2f7bcc input=8d8e5643bbbc2309]*/ /*[clinic input] @@ -3031,18 +2911,9 @@ static PyObject * test_posonly_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3051,13 +2922,12 @@ test_posonly_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", NULL}; static _PyArg_Parser _parser = { @@ -3097,7 +2967,7 @@ exit: static PyObject * test_posonly_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=997d180f3d1c69c5 input=f7e5eed94f75fff0]*/ +/*[clinic end generated code: output=b8b00420826bc11f input=f7e5eed94f75fff0]*/ /*[clinic input] @@ -3128,18 +2998,9 @@ static PyObject * test_posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3148,13 +3009,12 @@ test_posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(c), &_Py_ID(d), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "c", "d", NULL}; static _PyArg_Parser _parser = { @@ -3201,7 +3061,7 @@ exit: static PyObject * test_posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=0c9000c9f87ab430 input=1e557dc979d120fd]*/ +/*[clinic end generated code: output=3b9ee879ebee285a input=1e557dc979d120fd]*/ /*[clinic input] @@ -3234,18 +3094,9 @@ static PyObject * test_posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3254,13 +3105,12 @@ test_posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssi .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; static _PyArg_Parser _parser = { @@ -3305,7 +3155,7 @@ static PyObject * test_posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=6a5eaed3c057fda5 input=c3884a4f956fdc89]*/ +/*[clinic end generated code: output=d380f84f81cc0e45 input=c3884a4f956fdc89]*/ /*[clinic input] @@ -3336,18 +3186,9 @@ static PyObject * test_posonly_keywords_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3356,13 +3197,12 @@ test_posonly_keywords_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ss .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", "d", NULL}; static _PyArg_Parser _parser = { @@ -3404,7 +3244,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=033e6cfc772d4fc2 input=68d01d7c0f6dafb0]*/ +/*[clinic end generated code: output=ee629e962cb06992 input=68d01d7c0f6dafb0]*/ /*[clinic input] @@ -3438,18 +3278,9 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3458,13 +3289,12 @@ test_posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; static _PyArg_Parser _parser = { @@ -3518,7 +3348,7 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=5d3e7607d3d814e7 input=d0883d45876f186c]*/ +/*[clinic end generated code: output=a2721babb42ecfd1 input=d0883d45876f186c]*/ /*[clinic input] @@ -3552,18 +3382,9 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3572,13 +3393,12 @@ test_posonly_keywords_opt2_kwonly_opt(PyObject *module, PyObject *const *args, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; static _PyArg_Parser _parser = { @@ -3637,7 +3457,7 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=ed0301cc659624fe input=c95e2e1ec93035ad]*/ +/*[clinic end generated code: output=0626203eedb6e7e8 input=c95e2e1ec93035ad]*/ /*[clinic input] @@ -3673,18 +3493,9 @@ static PyObject * test_posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3693,13 +3504,12 @@ test_posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "c", "d", "e", "f", NULL}; static _PyArg_Parser _parser = { @@ -3766,7 +3576,7 @@ test_posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e, PyObject *f) -/*[clinic end generated code: output=352bbf976ebdd729 input=9914857713c5bbf8]*/ +/*[clinic end generated code: output=07d8acc04558a5a0 input=9914857713c5bbf8]*/ /*[clinic input] test_keyword_only_parameter @@ -3792,18 +3602,9 @@ static PyObject * test_keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3812,13 +3613,12 @@ test_keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(co_lnotab), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"co_lnotab", NULL}; static _PyArg_Parser _parser = { @@ -3852,7 +3652,7 @@ exit: static PyObject * test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab) -/*[clinic end generated code: output=a1c32e78f625dce1 input=303df5046c7e37a3]*/ +/*[clinic end generated code: output=b12fe2e515a62603 input=303df5046c7e37a3]*/ /*[clinic input] @@ -4030,18 +3830,9 @@ static PyObject * test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4050,13 +3841,12 @@ test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", NULL}; static _PyArg_Parser _parser = { @@ -4085,7 +3875,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=ac4d536e5b76c9fa input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=6661f3ca97d85e8c input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -4113,18 +3903,9 @@ static PyObject * test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4133,13 +3914,12 @@ test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", NULL}; static _PyArg_Parser _parser = { @@ -4178,7 +3958,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=f0c70f7e2e1c0523 input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=5fe3cfccb1bef781 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults @@ -4206,18 +3986,9 @@ static PyObject * test_vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4226,13 +3997,12 @@ test_vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(b), &_Py_ID(c), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"b", "c", NULL}; static _PyArg_Parser _parser = { @@ -4276,7 +4046,7 @@ exit: static PyObject * test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b, PyObject *c) -/*[clinic end generated code: output=0a918b65f7b076f9 input=fa56a709a035666e]*/ +/*[clinic end generated code: output=dd21b28f0db26a4b input=fa56a709a035666e]*/ /*[clinic input] test_paramname_module @@ -4299,18 +4069,9 @@ static PyObject * test_paramname_module(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4319,13 +4080,12 @@ test_paramname_module(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(module), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"module", NULL}; static _PyArg_Parser _parser = { @@ -4350,4 +4110,4 @@ exit: static PyObject * test_paramname_module_impl(PyObject *module, PyObject *mod) -/*[clinic end generated code: output=28b032fb28df75cd input=afefe259667f13ba]*/ +/*[clinic end generated code: output=4a2a849ecbcc8b53 input=afefe259667f13ba]*/ diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 7e07f60036b7..99b0f098cc2b 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -28,18 +28,9 @@ static PyObject * py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 12 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 12 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -48,13 +39,12 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -286,4 +276,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=6daedbc1dba8c284 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=996b4fe396824797 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index ee746d417d48..9b821fbcd62c 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -28,18 +28,9 @@ static PyObject * py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 12 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 12 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -48,13 +39,12 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -286,4 +276,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=1b0381231f840d4d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bd0fb7639e450618 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 470b0cb08e9c..b38738486f68 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -139,18 +139,9 @@ static PyObject * _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 8 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 8 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -159,13 +150,12 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(buffering), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(closefd), &_Py_ID(opener), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; static _PyArg_Parser _parser = { @@ -372,18 +362,9 @@ static PyObject * _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -392,13 +373,12 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -427,4 +407,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=ea13625ef5c1c5ef input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1f8001287a423470 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index bfd07e49b733..8a8f86b2eea3 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -408,18 +408,9 @@ static int _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -428,13 +419,12 @@ _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"raw", "buffer_size", NULL}; static _PyArg_Parser _parser = { @@ -495,18 +485,9 @@ static int _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -515,13 +496,12 @@ _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"raw", "buffer_size", NULL}; static _PyArg_Parser _parser = { @@ -675,18 +655,9 @@ static int _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -695,13 +666,12 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"raw", "buffer_size", NULL}; static _PyArg_Parser _parser = { @@ -743,4 +713,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=40ab0d3319282df2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ca87adcfff6a810b input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 27e0f313682b..84b58db6c7a7 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -489,18 +489,9 @@ static int _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -509,13 +500,12 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(initial_bytes), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"initial_bytes", NULL}; static _PyArg_Parser _parser = { @@ -544,4 +534,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a43adab5280d645c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a44770efbaeb80dd input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index 1695385c86e4..a925b94fe075 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -55,18 +55,9 @@ static int _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -75,13 +66,12 @@ _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; static _PyArg_Parser _parser = { @@ -476,4 +466,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ -/*[clinic end generated code: output=fa61bf880de0de90 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ff479a26cab0d479 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index d853cf4312a5..d495dd10c163 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -261,18 +261,9 @@ static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -281,13 +272,12 @@ _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(initial_value), &_Py_ID(newline), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"initial_value", "newline", NULL}; static _PyArg_Parser _parser = { @@ -377,4 +367,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=b1bde306e2928b19 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=533f20ae9b773126 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index c9b25124dcb4..038f0a5c209d 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -30,18 +30,9 @@ static int _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -50,13 +41,12 @@ _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(decoder), &_Py_ID(translate), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; static _PyArg_Parser _parser = { @@ -109,18 +99,9 @@ static PyObject * _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -129,13 +110,12 @@ _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *ar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(input), &_Py_ID(final), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"input", "final", NULL}; static _PyArg_Parser _parser = { @@ -254,18 +234,9 @@ static int _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 6 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 6 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -274,13 +245,12 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(buffer), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; static _PyArg_Parser _parser = { @@ -402,18 +372,9 @@ static PyObject * _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -422,13 +383,12 @@ _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"encoding", "errors", "newline", "line_buffering", "write_through", NULL}; static _PyArg_Parser _parser = { @@ -809,4 +769,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=29563d0807382d7a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aecd376eca3cb148 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index 5808a60b6a8e..65820a8f2ea0 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -54,18 +54,9 @@ static int _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -74,13 +65,12 @@ _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; static _PyArg_Parser _parser = { @@ -417,4 +407,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ -/*[clinic end generated code: output=440125d1e2745fff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=08ae244e9a44da55 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index 9894af4c561a..df2aa29cfe62 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -27,18 +27,9 @@ static PyObject * _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -47,13 +38,12 @@ _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "flags", "mode", NULL}; static _PyArg_Parser _parser = { @@ -127,18 +117,9 @@ static PyObject * _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -147,13 +128,12 @@ _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -192,4 +172,4 @@ _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs #ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF #define _POSIXSHMEM_SHM_UNLINK_METHODDEF #endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ -/*[clinic end generated code: output=4c889c75d55353a6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3f6fee283d5fd0e9 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h index 28c9d4a8fb2f..dce0366c266f 100644 --- a/Modules/_multiprocessing/clinic/semaphore.c.h +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -27,18 +27,9 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -47,13 +38,12 @@ _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"block", "timeout", NULL}; static _PyArg_Parser _parser = { @@ -134,18 +124,9 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -154,13 +135,12 @@ _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"block", "timeout", NULL}; static _PyArg_Parser _parser = { @@ -232,18 +212,9 @@ static PyObject * _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -252,13 +223,12 @@ _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(kind), &_Py_ID(value), &_Py_ID(maxvalue), &_Py_ID(name), &_Py_ID(unlink), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; static _PyArg_Parser _parser = { @@ -572,4 +542,4 @@ _multiprocessing_SemLock___exit__(SemLockObject *self, PyObject *const *args, Py #ifndef _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #endif /* !defined(_MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF) */ -/*[clinic end generated code: output=7eaf752dcfef6204 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=720d7d0066dc0954 input=a9049054013a1b77]*/ diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/_sha3/clinic/sha3module.c.h index b53a244a230c..a0c7c1c043e5 100644 --- a/Modules/_sha3/clinic/sha3module.c.h +++ b/Modules/_sha3/clinic/sha3module.c.h @@ -21,18 +21,9 @@ static PyObject * py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -41,13 +32,12 @@ py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -203,4 +193,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=f601d854411f9bea input=a9049054013a1b77]*/ +/*[clinic end generated code: output=747c3f34ddd14063 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 066675d49630..e7e78707ee8d 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -19,18 +19,9 @@ static int pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 8 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 8 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -39,13 +30,12 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(database), &_Py_ID(timeout), &_Py_ID(detect_types), &_Py_ID(isolation_level), &_Py_ID(check_same_thread), &_Py_ID(factory), &_Py_ID(cached_statements), &_Py_ID(uri), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; static _PyArg_Parser _parser = { @@ -158,18 +148,9 @@ static PyObject * pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -178,13 +159,12 @@ pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(factory), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"factory", NULL}; static _PyArg_Parser _parser = { @@ -240,18 +220,9 @@ static PyObject * blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -260,13 +231,12 @@ blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(readonly), &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "", "readonly", "name", NULL}; static _PyArg_Parser _parser = { @@ -428,18 +398,9 @@ static PyObject * pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -448,13 +409,12 @@ pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), &_Py_ID(narg), &_Py_ID(func), &_Py_ID(deterministic), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", "narg", "func", "deterministic", NULL}; static _PyArg_Parser _parser = { @@ -535,33 +495,11 @@ static PyObject * create_window_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", "", NULL}; static _PyArg_Parser _parser = { @@ -624,18 +562,9 @@ static PyObject * pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -644,13 +573,12 @@ pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cl .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), &_Py_ID(n_arg), &_Py_ID(aggregate_class), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", "n_arg", "aggregate_class", NULL}; static _PyArg_Parser _parser = { @@ -710,18 +638,9 @@ static PyObject * pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -730,13 +649,12 @@ pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(authorizer_callback), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"authorizer_callback", NULL}; static _PyArg_Parser _parser = { @@ -777,18 +695,9 @@ static PyObject * pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -797,13 +706,12 @@ pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(progress_handler), &_Py_ID(n), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"progress_handler", "n", NULL}; static _PyArg_Parser _parser = { @@ -849,18 +757,9 @@ static PyObject * pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -869,13 +768,12 @@ pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(trace_callback), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"trace_callback", NULL}; static _PyArg_Parser _parser = { @@ -1118,18 +1016,9 @@ static PyObject * pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1138,13 +1027,12 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(target), &_Py_ID(pages), &_Py_ID(progress), &_Py_ID(name), &_Py_ID(sleep), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; static _PyArg_Parser _parser = { @@ -1242,33 +1130,11 @@ static PyObject * pysqlite_connection_create_collation(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -1331,18 +1197,9 @@ static PyObject * serialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1351,13 +1208,12 @@ serialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", NULL}; static _PyArg_Parser _parser = { @@ -1430,18 +1286,9 @@ static PyObject * deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1450,13 +1297,12 @@ deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "name", NULL}; static _PyArg_Parser _parser = { @@ -1672,4 +1518,4 @@ getlimit(pysqlite_Connection *self, PyObject *arg) #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=e6873a956553d806 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=beef3eac690a1f88 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index d01abb856794..36b8d0051a29 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -192,18 +192,9 @@ static PyObject * pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -212,13 +203,12 @@ pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(size), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"size", NULL}; static _PyArg_Parser _parser = { @@ -328,4 +318,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=13c24313ce3a0fec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e53e75a32a9d92bd input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index 0137918a48ad..12f60835880b 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -24,18 +24,9 @@ static PyObject * pysqlite_complete_statement(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -44,13 +35,12 @@ pysqlite_complete_statement(PyObject *module, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(statement), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"statement", NULL}; static _PyArg_Parser _parser = { @@ -221,4 +211,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=4b5c237e3cf49908 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39d38c6cfc455042 input=a9049054013a1b77]*/ diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index dc5c6c132151..711e16a1190d 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -181,18 +181,9 @@ static PyObject * _sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -201,13 +192,12 @@ _sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { @@ -284,18 +274,9 @@ static PyObject * _sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -304,13 +285,12 @@ _sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *con .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { @@ -389,18 +369,9 @@ static PyObject * _sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -409,13 +380,12 @@ _sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { @@ -491,18 +461,9 @@ static PyObject * _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -511,13 +472,12 @@ _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { @@ -596,18 +556,9 @@ static PyObject * _sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -616,13 +567,12 @@ _sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *cons .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { @@ -698,18 +648,9 @@ static PyObject * _sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -718,13 +659,12 @@ _sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { @@ -800,18 +740,9 @@ static PyObject * _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -820,13 +751,12 @@ _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -884,18 +814,9 @@ static PyObject * _sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -904,13 +825,12 @@ _sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *ar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"repl", "string", "count", NULL}; static _PyArg_Parser _parser = { @@ -971,18 +891,9 @@ static PyObject * _sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -991,13 +902,12 @@ _sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *a .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"repl", "string", "count", NULL}; static _PyArg_Parser _parser = { @@ -1083,18 +993,9 @@ static PyObject * _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 6 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 6 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1103,13 +1004,12 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(pattern), &_Py_ID(flags), &_Py_ID(code), &_Py_ID(groups), &_Py_ID(groupindex), &_Py_ID(indexgroup), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; static _PyArg_Parser _parser = { @@ -1184,18 +1084,9 @@ static PyObject * _sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1204,13 +1095,12 @@ _sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(template), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"template", NULL}; static _PyArg_Parser _parser = { @@ -1252,18 +1142,9 @@ static PyObject * _sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1272,13 +1153,12 @@ _sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(default), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"default", NULL}; static _PyArg_Parser _parser = { @@ -1325,18 +1205,9 @@ static PyObject * _sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1345,13 +1216,12 @@ _sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(default), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"default", NULL}; static _PyArg_Parser _parser = { @@ -1551,4 +1421,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const } return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=d686111c67a7d0aa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=14ea86f85c130a7b input=a9049054013a1b77]*/ diff --git a/Modules/_ssl/clinic/cert.c.h b/Modules/_ssl/clinic/cert.c.h index e90aa137503a..a052ab2086fd 100644 --- a/Modules/_ssl/clinic/cert.c.h +++ b/Modules/_ssl/clinic/cert.c.h @@ -23,18 +23,9 @@ static PyObject * _ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -43,13 +34,12 @@ _ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(format), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"format", NULL}; static _PyArg_Parser _parser = { @@ -96,4 +86,4 @@ _ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) { return _ssl_Certificate_get_info_impl(self); } -/*[clinic end generated code: output=39d0c03e76b5f361 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=82efada014f9b7fe input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index d251bdba1d5d..b7e340e68796 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -31,18 +31,9 @@ static PyObject * _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -51,13 +42,12 @@ _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *cons .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"input", "errors", NULL}; static _PyArg_Parser _parser = { @@ -127,18 +117,9 @@ static PyObject * _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -147,13 +128,12 @@ _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *cons .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"input", "errors", NULL}; static _PyArg_Parser _parser = { @@ -228,18 +208,9 @@ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -248,13 +219,12 @@ _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(input), &_Py_ID(final), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"input", "final", NULL}; static _PyArg_Parser _parser = { @@ -367,18 +337,9 @@ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -387,13 +348,12 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(input), &_Py_ID(final), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"input", "final", NULL}; static _PyArg_Parser _parser = { @@ -630,33 +590,11 @@ static PyObject * _multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -696,33 +634,11 @@ static PyObject * _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -774,4 +690,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=1e596a9dfd1c97cd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b034ec7126c11bde input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 7428fc20dc27..daf524c3456c 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -32,18 +32,9 @@ static int _asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -52,13 +43,12 @@ _asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(loop), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"loop", NULL}; static _PyArg_Parser _parser = { @@ -178,18 +168,9 @@ static PyObject * _asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -198,13 +179,12 @@ _asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssi .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(context), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "context", NULL}; static _PyArg_Parser _parser = { @@ -265,18 +245,9 @@ static PyObject * _asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -285,13 +256,12 @@ _asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(msg), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"msg", NULL}; static _PyArg_Parser _parser = { @@ -411,18 +381,9 @@ static int _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -431,13 +392,12 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(coro), &_Py_ID(loop), &_Py_ID(name), &_Py_ID(context), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"coro", "loop", "name", "context", NULL}; static _PyArg_Parser _parser = { @@ -539,18 +499,9 @@ static PyObject * _asyncio_Task_cancel(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -559,13 +510,12 @@ _asyncio_Task_cancel(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(msg), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"msg", NULL}; static _PyArg_Parser _parser = { @@ -671,18 +621,9 @@ static PyObject * _asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -691,13 +632,12 @@ _asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(limit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"limit", NULL}; static _PyArg_Parser _parser = { @@ -748,18 +688,9 @@ static PyObject * _asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -768,13 +699,12 @@ _asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(limit), &_Py_ID(file), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"limit", "file", NULL}; static _PyArg_Parser _parser = { @@ -940,18 +870,9 @@ static PyObject * _asyncio__get_event_loop(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -960,13 +881,12 @@ _asyncio__get_event_loop(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(stacklevel), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"stacklevel", NULL}; static _PyArg_Parser _parser = { @@ -1035,18 +955,9 @@ static PyObject * _asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1055,13 +966,12 @@ _asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(task), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"task", NULL}; static _PyArg_Parser _parser = { @@ -1102,18 +1012,9 @@ static PyObject * _asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1122,13 +1023,12 @@ _asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(task), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"task", NULL}; static _PyArg_Parser _parser = { @@ -1171,18 +1071,9 @@ static PyObject * _asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1191,13 +1082,12 @@ _asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"loop", "task", NULL}; static _PyArg_Parser _parser = { @@ -1242,18 +1132,9 @@ static PyObject * _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1262,13 +1143,12 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"loop", "task", NULL}; static _PyArg_Parser _parser = { @@ -1292,4 +1172,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=f923801842642bd9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=459a7c7f21bbc290 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h index 667ed478eea4..bbf456e4b0f4 100644 --- a/Modules/clinic/_bisectmodule.c.h +++ b/Modules/clinic/_bisectmodule.c.h @@ -32,18 +32,9 @@ static PyObject * _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -52,13 +43,12 @@ _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = { @@ -148,18 +138,9 @@ static PyObject * _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -168,13 +149,12 @@ _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = { @@ -261,18 +241,9 @@ static PyObject * _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -281,13 +252,12 @@ _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = { @@ -377,18 +347,9 @@ static PyObject * _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -397,13 +358,12 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; static _PyArg_Parser _parser = { @@ -465,4 +425,4 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=8028ae01b2fd14b6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7dc87f7af75275a1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 178cae88f38e..50a48b0bf2b8 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -101,18 +101,9 @@ static PyObject * _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -121,13 +112,12 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "max_length", NULL}; static _PyArg_Parser _parser = { @@ -178,4 +168,4 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py return return_value; } -/*[clinic end generated code: output=fe780ceebc3d3826 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=829bed4097cf2e63 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index be8b11a47c53..25db060cd900 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -92,18 +92,9 @@ static PyObject * _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -112,13 +103,12 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -202,18 +192,9 @@ static PyObject * _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -222,13 +203,12 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -2889,4 +2869,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=58003a0c706e89c2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e885abad241bc54d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_csv.c.h b/Modules/clinic/_csv.c.h index c035c44ebdee..8900946350a5 100644 --- a/Modules/clinic/_csv.c.h +++ b/Modules/clinic/_csv.c.h @@ -46,18 +46,9 @@ static PyObject * _csv_unregister_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -66,13 +57,12 @@ _csv_unregister_dialect(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", NULL}; static _PyArg_Parser _parser = { @@ -113,18 +103,9 @@ static PyObject * _csv_get_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -133,13 +114,12 @@ _csv_get_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", NULL}; static _PyArg_Parser _parser = { @@ -183,18 +163,9 @@ static PyObject * _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -203,13 +174,12 @@ _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(new_limit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"new_limit", NULL}; static _PyArg_Parser _parser = { @@ -236,4 +206,4 @@ _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=46fe87be9980e02e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=94374e41eb2806ee input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index c5e9c2e5675d..bb6cc90f0438 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -169,33 +169,11 @@ static PyObject * _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -262,33 +240,11 @@ static PyObject * _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -332,33 +288,11 @@ static PyObject * _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -488,4 +422,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=b4bbea7cfaaf3982 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8d0533681891523c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 715b9c35d2d4..67fadace8639 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2684,18 +2684,9 @@ static PyObject * _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2704,13 +2695,12 @@ _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(term), &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"term", "fd", NULL}; static _PyArg_Parser _parser = { @@ -4323,4 +4313,4 @@ _curses_has_extended_color_support(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=048542c478241231 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b2e71e2012f16197 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 955e5fe8eafe..51e51e3791cc 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -28,18 +28,9 @@ static PyObject * iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -48,13 +39,12 @@ iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(year), &_Py_ID(week), &_Py_ID(weekday), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"year", "week", "weekday", NULL}; static _PyArg_Parser _parser = { @@ -113,18 +103,9 @@ static PyObject * datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -133,13 +114,12 @@ datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(tz), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"tz", NULL}; static _PyArg_Parser _parser = { @@ -166,4 +146,4 @@ datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=faf7b2ab25ab94b9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=42654669940e0e3a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index e368378e6b87..172dc4b9d579 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -65,33 +65,11 @@ static PyObject * _dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -133,33 +111,11 @@ static PyObject * _dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -244,4 +200,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a2232bc0c1994f03 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=28dcf736654137c2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 9afe2af7593a..0a2a74e220c2 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -174,18 +174,9 @@ static PyObject * _elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -194,13 +185,12 @@ _elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "namespaces", NULL}; static _PyArg_Parser _parser = { @@ -247,18 +237,9 @@ static PyObject * _elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -267,13 +248,12 @@ _elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssi .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(default), &_Py_ID(namespaces), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; static _PyArg_Parser _parser = { @@ -326,18 +306,9 @@ static PyObject * _elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -346,13 +317,12 @@ _elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssiz .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "namespaces", NULL}; static _PyArg_Parser _parser = { @@ -398,18 +368,9 @@ static PyObject * _elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -418,13 +379,12 @@ _elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssi .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "namespaces", NULL}; static _PyArg_Parser _parser = { @@ -470,18 +430,9 @@ static PyObject * _elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -490,13 +441,12 @@ _elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(default), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "default", NULL}; static _PyArg_Parser _parser = { @@ -541,18 +491,9 @@ static PyObject * _elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -561,13 +502,12 @@ _elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(tag), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"tag", NULL}; static _PyArg_Parser _parser = { @@ -794,18 +734,9 @@ static int _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -814,13 +745,12 @@ _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(element_factory), &_Py_ID(comment_factory), &_Py_ID(pi_factory), &_Py_ID(insert_comments), &_Py_ID(insert_pis), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"element_factory", "comment_factory", "pi_factory", "insert_comments", "insert_pis", NULL}; static _PyArg_Parser _parser = { @@ -1038,18 +968,9 @@ static int _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1058,13 +979,12 @@ _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(target), &_Py_ID(encoding), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"target", "encoding", NULL}; static _PyArg_Parser _parser = { @@ -1185,4 +1105,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=62ed1bab17b4297a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=67a80531eaf43815 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index ca1bfde1d2d6..5c6aeeee7789 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -168,33 +168,11 @@ static PyObject * _gdbm_gdbm_nextkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -344,4 +322,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=72d3e46432e2d324 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c6e721d82335adb3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index 67532787e996..fb61a444018d 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -89,18 +89,9 @@ static PyObject * EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -109,13 +100,12 @@ EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(length), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"length", NULL}; static _PyArg_Parser _parser = { @@ -169,18 +159,9 @@ static PyObject * EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -189,13 +170,12 @@ EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(length), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"length", NULL}; static _PyArg_Parser _parser = { @@ -253,18 +233,9 @@ static PyObject * EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -273,13 +244,12 @@ EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", "string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -340,18 +310,9 @@ static PyObject * _hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -360,13 +321,12 @@ _hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -425,18 +385,9 @@ static PyObject * _hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -445,13 +396,12 @@ _hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -510,18 +460,9 @@ static PyObject * _hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -530,13 +471,12 @@ _hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -595,18 +535,9 @@ static PyObject * _hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -615,13 +546,12 @@ _hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -680,18 +610,9 @@ static PyObject * _hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -700,13 +621,12 @@ _hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -765,18 +685,9 @@ static PyObject * _hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -785,13 +696,12 @@ _hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -852,18 +762,9 @@ static PyObject * _hashlib_openssl_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -872,13 +773,12 @@ _hashlib_openssl_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -941,18 +841,9 @@ static PyObject * _hashlib_openssl_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -961,13 +852,12 @@ _hashlib_openssl_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -1030,18 +920,9 @@ static PyObject * _hashlib_openssl_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1050,13 +931,12 @@ _hashlib_openssl_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -1119,18 +999,9 @@ static PyObject * _hashlib_openssl_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1139,13 +1010,12 @@ _hashlib_openssl_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -1208,18 +1078,9 @@ static PyObject * _hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1228,13 +1089,12 @@ _hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -1297,18 +1157,9 @@ static PyObject * _hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1317,13 +1168,12 @@ _hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -1386,18 +1236,9 @@ static PyObject * pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1406,13 +1247,12 @@ pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(hash_name), &_Py_ID(password), &_Py_ID(salt), &_Py_ID(iterations), &_Py_ID(dklen), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"hash_name", "password", "salt", "iterations", "dklen", NULL}; static _PyArg_Parser _parser = { @@ -1505,18 +1345,9 @@ static PyObject * _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 7 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 7 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1525,13 +1356,12 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(password), &_Py_ID(salt), &_Py_ID(n), &_Py_ID(r), &_Py_ID(p), &_Py_ID(maxmem), &_Py_ID(dklen), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; static _PyArg_Parser _parser = { @@ -1654,18 +1484,9 @@ static PyObject * _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1674,13 +1495,12 @@ _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digest), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "msg", "digest", NULL}; static _PyArg_Parser _parser = { @@ -1745,18 +1565,9 @@ static PyObject * _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1765,13 +1576,12 @@ _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digestmod), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "msg", "digestmod", NULL}; static _PyArg_Parser _parser = { @@ -1853,18 +1663,9 @@ static PyObject * _hashlib_HMAC_update(HMACobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1873,13 +1674,12 @@ _hashlib_HMAC_update(HMACobject *self, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(msg), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"msg", NULL}; static _PyArg_Parser _parser = { @@ -2051,4 +1851,4 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=8c1bb9faad2b6b57 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b339e255db698147 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index 8fce25686afd..286d2b007065 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -101,18 +101,9 @@ static PyObject * _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -121,13 +112,12 @@ _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "max_length", NULL}; static _PyArg_Parser _parser = { @@ -210,18 +200,9 @@ static int _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -230,13 +211,12 @@ _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(format), &_Py_ID(memlimit), &_Py_ID(filters), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; static _PyArg_Parser _parser = { @@ -358,4 +338,4 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz return return_value; } -/*[clinic end generated code: output=2713a1ba282060d3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=da3e83ba97244044 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index 1844d7000529..3bd3ba023874 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -25,18 +25,9 @@ static PyObject * _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -45,13 +36,12 @@ _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(jump), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "jump", NULL}; static _PyArg_Parser _parser = { @@ -113,4 +103,4 @@ _opcode_get_specialization_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _opcode_get_specialization_stats_impl(module); } -/*[clinic end generated code: output=99bf9024ab436fa3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=21e3d53a659c651a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index a9bb84377df8..e9ff2604719a 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -112,18 +112,9 @@ static int _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -132,13 +123,12 @@ _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = { @@ -365,18 +355,9 @@ static int _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -385,13 +366,12 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = { @@ -569,18 +549,9 @@ static PyObject * _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -589,13 +560,12 @@ _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(obj), &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = { @@ -683,18 +653,9 @@ static PyObject * _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -703,13 +664,12 @@ _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(obj), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"obj", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = { @@ -801,18 +761,9 @@ static PyObject * _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -821,13 +772,12 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = { @@ -937,18 +887,9 @@ static PyObject * _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -957,13 +898,12 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = { @@ -1040,4 +980,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=fecab7d905b02139 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3321309c2157ee74 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index c2f0d6ed86bd..f86dac3c497d 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -58,18 +58,9 @@ static PyObject * _queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -78,13 +69,12 @@ _queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(item), &_Py_ID(block), &_Py_ID(timeout), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"item", "block", "timeout", NULL}; static _PyArg_Parser _parser = { @@ -143,18 +133,9 @@ static PyObject * _queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -163,13 +144,12 @@ _queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(item), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"item", NULL}; static _PyArg_Parser _parser = { @@ -217,18 +197,9 @@ static PyObject * _queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -237,13 +208,12 @@ _queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *con .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"block", "timeout", NULL}; static _PyArg_Parser _parser = { @@ -362,4 +332,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=def30d57235bc720 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=628e992d38f50aac input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 819c7ee878ff..622e321fa1d8 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -354,18 +354,9 @@ static PyObject * _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -374,13 +365,12 @@ _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(cb_type), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"cb_type", NULL}; static _PyArg_Parser _parser = { @@ -570,18 +560,9 @@ static PyObject * _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -590,13 +571,12 @@ _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_s .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(certfile), &_Py_ID(keyfile), &_Py_ID(password), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; static _PyArg_Parser _parser = { @@ -651,18 +631,9 @@ static PyObject * _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -671,13 +642,12 @@ _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(cafile), &_Py_ID(capath), &_Py_ID(cadata), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; static _PyArg_Parser _parser = { @@ -745,18 +715,9 @@ static PyObject * _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -765,13 +726,12 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sock), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL}; static _PyArg_Parser _parser = { @@ -847,18 +807,9 @@ static PyObject * _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 6 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 6 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -867,13 +818,12 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(incoming), &_Py_ID(outgoing), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL}; static _PyArg_Parser _parser = { @@ -1024,18 +974,9 @@ static PyObject * _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1044,13 +985,12 @@ _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssiz .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(binary_form), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"binary_form", NULL}; static _PyArg_Parser _parser = { @@ -1354,18 +1294,9 @@ static PyObject * _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1374,13 +1305,12 @@ _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(txt), &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"txt", "name", NULL}; static _PyArg_Parser _parser = { @@ -1477,18 +1407,9 @@ static PyObject * _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1497,13 +1418,12 @@ _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(store_name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"store_name", NULL}; static _PyArg_Parser _parser = { @@ -1563,18 +1483,9 @@ static PyObject * _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1583,13 +1494,12 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(store_name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"store_name", NULL}; static _PyArg_Parser _parser = { @@ -1633,4 +1543,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=243724694a274b72 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9f477b0c709acb28 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index c7fa663f7861..b21d9ff29243 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -26,18 +26,9 @@ static int Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -46,13 +37,12 @@ Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(format), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"format", NULL}; static _PyArg_Parser _parser = { @@ -142,18 +132,9 @@ static PyObject * Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -162,13 +143,12 @@ Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"buffer", "offset", NULL}; static _PyArg_Parser _parser = { @@ -357,18 +337,9 @@ static PyObject * unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -377,13 +348,12 @@ unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "buffer", "offset", NULL}; static _PyArg_Parser _parser = { @@ -481,4 +451,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=f968221cff7bc5b3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eca7df0e75f8919d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index 2add29fe8a6d..42ec7475e5e4 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -79,18 +79,9 @@ static PyObject * _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -99,13 +90,12 @@ _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *se .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(n), &_Py_ID(twice), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"n", "twice", NULL}; static _PyArg_Parser _parser = { @@ -172,4 +162,4 @@ _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObj } return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=34ad05704fd7f815 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52ea97ab2f03bb6d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 07cd442a96d5..53d5cccdd7db 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -112,18 +112,9 @@ static PyObject * _winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -132,13 +123,12 @@ _winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(handle), &_Py_ID(overlapped), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"handle", "overlapped", NULL}; static _PyArg_Parser _parser = { @@ -875,18 +865,9 @@ static PyObject * _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -895,13 +876,12 @@ _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(locale), &_Py_ID(flags), &_Py_ID(src), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"locale", "flags", "src", NULL}; static _PyArg_Parser _parser = { @@ -945,18 +925,9 @@ static PyObject * _winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -965,13 +936,12 @@ _winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(handle), &_Py_ID(size), &_Py_ID(overlapped), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; static _PyArg_Parser _parser = { @@ -1203,18 +1173,9 @@ static PyObject * _winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1223,13 +1184,12 @@ _winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(handle), &_Py_ID(buffer), &_Py_ID(overlapped), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; static _PyArg_Parser _parser = { @@ -1285,18 +1245,9 @@ static PyObject * _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1305,13 +1256,12 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(handle), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"handle", NULL}; static _PyArg_Parser _parser = { @@ -1357,18 +1307,9 @@ static PyObject * _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1377,13 +1318,12 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(on_type_read), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"on_type_read", NULL}; static _PyArg_Parser _parser = { @@ -1405,4 +1345,4 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=5febc912fc8ff4ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3e51e0b2ea3fea5a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index b9ce96f3f7e9..e68c3920072d 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -160,33 +160,11 @@ static PyObject * array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -336,33 +314,11 @@ static PyObject * array_array_fromfile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -414,33 +370,11 @@ static PyObject * array_array_tofile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -689,33 +623,11 @@ static PyObject * array_array___reduce_ex__(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -768,4 +680,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=6cdb18b06fc993e0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=69bc1451f7bda234 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index 5afae34e8a2d..23ebdff21082 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -55,18 +55,9 @@ static PyObject * binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -75,13 +66,12 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(backtick), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "backtick", NULL}; static _PyArg_Parser _parser = { @@ -145,18 +135,9 @@ static PyObject * binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -165,13 +146,12 @@ binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(strict_mode), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "strict_mode", NULL}; static _PyArg_Parser _parser = { @@ -226,18 +206,9 @@ static PyObject * binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -246,13 +217,12 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(newline), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "newline", NULL}; static _PyArg_Parser _parser = { @@ -427,18 +397,9 @@ static PyObject * binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -447,13 +408,12 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = { @@ -530,18 +490,9 @@ static PyObject * binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -550,13 +501,12 @@ binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = { @@ -690,18 +640,9 @@ static PyObject * binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -710,13 +651,12 @@ binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(header), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "header", NULL}; static _PyArg_Parser _parser = { @@ -776,18 +716,9 @@ static PyObject * binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -796,13 +727,12 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(quotetabs), &_Py_ID(istext), &_Py_ID(header), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; static _PyArg_Parser _parser = { @@ -865,4 +795,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=83eb1173ff9f6393 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a266ba13c374aefa input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index 6aa3d571711e..b1da9452c61d 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -899,18 +899,9 @@ static PyObject * cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -919,13 +910,12 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; static _PyArg_Parser _parser = { @@ -992,4 +982,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=d87babbf69f095b8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0146c656e67f5d5f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index af04398ac7a0..2d18e2ee0978 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -94,18 +94,9 @@ static PyObject * gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -114,13 +105,12 @@ gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(generation), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"generation", NULL}; static _PyArg_Parser _parser = { @@ -281,18 +271,9 @@ static PyObject * gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -301,13 +282,12 @@ gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(generation), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"generation", NULL}; static _PyArg_Parser _parser = { @@ -444,4 +424,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=8c73502d349c8726 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=66432ac0e17fd04f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index 58dd2e22512a..4914bc9abd67 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -26,18 +26,9 @@ static PyObject * grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -46,13 +37,12 @@ grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(id), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"id", NULL}; static _PyArg_Parser _parser = { @@ -93,18 +83,9 @@ static PyObject * grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -113,13 +94,12 @@ grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", NULL}; static _PyArg_Parser _parser = { @@ -169,4 +149,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=82d55ad1c7c612d2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0916fdbcdeaf5d7d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index b62c04acd6a7..8806606d85be 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -60,18 +60,9 @@ static PyObject * itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -80,13 +71,12 @@ itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(key), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "key", NULL}; static _PyArg_Parser _parser = { @@ -416,18 +406,9 @@ static PyObject * itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -436,13 +417,12 @@ itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "r", NULL}; static _PyArg_Parser _parser = { @@ -497,18 +477,9 @@ static PyObject * itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -517,13 +488,12 @@ itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "r", NULL}; static _PyArg_Parser _parser = { @@ -577,18 +547,9 @@ static PyObject * itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -597,13 +558,12 @@ itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "r", NULL}; static _PyArg_Parser _parser = { @@ -649,18 +609,9 @@ static PyObject * itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -669,13 +620,12 @@ itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(func), &_Py_ID(initial), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "func", "initial", NULL}; static _PyArg_Parser _parser = { @@ -734,18 +684,9 @@ static PyObject * itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -754,13 +695,12 @@ itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(data), &_Py_ID(selectors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"data", "selectors", NULL}; static _PyArg_Parser _parser = { @@ -842,18 +782,9 @@ static PyObject * itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -862,13 +793,12 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(start), &_Py_ID(step), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"start", "step", NULL}; static _PyArg_Parser _parser = { @@ -904,4 +834,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=66bc6a70f05e9bc7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b1056d63f68a9059 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 3b4e0cc54b0c..9fac1037e525 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -584,18 +584,9 @@ static PyObject * math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -604,13 +595,12 @@ math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; static _PyArg_Parser _parser = { @@ -712,18 +702,9 @@ static PyObject * math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -732,13 +713,12 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(start), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "start", NULL}; static _PyArg_Parser _parser = { @@ -937,4 +917,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9f9605edaac98c6c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c2c2f42452d63734 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 9dd8fd50eb27..b4602104f180 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -91,18 +91,9 @@ static PyObject * _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -111,13 +102,12 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -158,4 +148,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=4e0701fc285576d9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4924c9905cc9f34 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 71ad7a6f0858..cc0c74cc1d29 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -452,18 +452,9 @@ static PyObject * _overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -472,13 +463,12 @@ _overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(event), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"event", NULL}; static _PyArg_Parser _parser = { @@ -1264,4 +1254,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=8a85a2b9616bf8f1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ed7ca699b5cf6260 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index da5beb5ab05c..a26cb8261083 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -43,18 +43,9 @@ static PyObject * os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -63,13 +54,12 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -135,18 +125,9 @@ static PyObject * os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -155,13 +136,12 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -241,18 +221,9 @@ static PyObject * os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -261,13 +232,12 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(effective_ids), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -411,18 +381,9 @@ static PyObject * os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -431,13 +392,12 @@ os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -486,18 +446,9 @@ static PyObject * os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -506,13 +457,12 @@ os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -576,18 +526,9 @@ static PyObject * os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -596,13 +537,12 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -674,18 +614,9 @@ static PyObject * os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -694,13 +625,12 @@ os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), &_Py_ID(mode), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", "mode", NULL}; static _PyArg_Parser _parser = { @@ -754,18 +684,9 @@ static PyObject * os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -774,13 +695,12 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(mode), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "mode", NULL}; static _PyArg_Parser _parser = { @@ -840,18 +760,9 @@ static PyObject * os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -860,13 +771,12 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -933,18 +843,9 @@ static PyObject * os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -953,13 +854,12 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "flags", NULL}; static _PyArg_Parser _parser = { @@ -1013,18 +913,9 @@ static PyObject * os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1033,13 +924,12 @@ os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -1087,18 +977,9 @@ static PyObject * os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1107,13 +988,12 @@ os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -1180,18 +1060,9 @@ static PyObject * os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1200,13 +1071,12 @@ os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -1276,18 +1146,9 @@ static PyObject * os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1296,13 +1157,12 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -1379,18 +1239,9 @@ static PyObject * os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1399,13 +1250,12 @@ os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), &_Py_ID(uid), &_Py_ID(gid), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; static _PyArg_Parser _parser = { @@ -1462,18 +1312,9 @@ static PyObject * os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1482,13 +1323,12 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "uid", "gid", NULL}; static _PyArg_Parser _parser = { @@ -1592,18 +1432,9 @@ static PyObject * os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1612,13 +1443,12 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -1709,18 +1539,9 @@ static PyObject * os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1729,13 +1550,12 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -1853,18 +1673,9 @@ static PyObject * os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1873,13 +1684,12 @@ os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -1927,18 +1737,9 @@ static PyObject * os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1947,13 +1748,12 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -1999,18 +1799,9 @@ static PyObject * os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2019,13 +1810,12 @@ os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -2071,18 +1861,9 @@ static PyObject * os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2091,13 +1872,12 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -2198,18 +1978,9 @@ static PyObject * os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2218,13 +1989,12 @@ os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(which), &_Py_ID(who), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"which", "who", NULL}; static _PyArg_Parser _parser = { @@ -2275,18 +2045,9 @@ static PyObject * os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2295,13 +2056,12 @@ os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(which), &_Py_ID(who), &_Py_ID(priority), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"which", "who", "priority", NULL}; static _PyArg_Parser _parser = { @@ -2362,18 +2122,9 @@ static PyObject * os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2382,13 +2133,12 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -2463,18 +2213,9 @@ static PyObject * os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2483,13 +2224,12 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -2562,18 +2302,9 @@ static PyObject * os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2582,13 +2313,12 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -2643,18 +2373,9 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2663,13 +2384,12 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(command), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"command", NULL}; static _PyArg_Parser _parser = { @@ -2727,18 +2447,9 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2747,13 +2458,12 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(command), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"command", NULL}; static _PyArg_Parser _parser = { @@ -2841,18 +2551,9 @@ static PyObject * os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2861,13 +2562,12 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -2925,18 +2625,9 @@ static PyObject * os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -2945,13 +2636,12 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -3053,18 +2743,9 @@ static PyObject * os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3073,13 +2754,12 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(times), &_Py_ID(ns), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -3160,18 +2840,9 @@ static PyObject * os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3180,13 +2851,12 @@ os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -3281,18 +2951,9 @@ static PyObject * os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3301,13 +2962,12 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(argv), &_Py_ID(env), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "argv", "env", NULL}; static _PyArg_Parser _parser = { @@ -3386,18 +3046,9 @@ static PyObject * os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 7 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 7 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3406,13 +3057,12 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; static _PyArg_Parser _parser = { @@ -3546,18 +3196,9 @@ static PyObject * os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 7 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 7 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3566,13 +3207,12 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; static _PyArg_Parser _parser = { @@ -3799,18 +3439,9 @@ static PyObject * os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3819,13 +3450,12 @@ os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(before), &_Py_ID(after_in_child), &_Py_ID(after_in_parent), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"before", "after_in_child", "after_in_parent", NULL}; static _PyArg_Parser _parser = { @@ -3935,18 +3565,9 @@ static PyObject * os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -3955,13 +3576,12 @@ os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(policy), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"policy", NULL}; static _PyArg_Parser _parser = { @@ -4007,18 +3627,9 @@ static PyObject * os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4027,13 +3638,12 @@ os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(policy), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"policy", NULL}; static _PyArg_Parser _parser = { @@ -4112,18 +3722,9 @@ static PyObject * os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4132,13 +3733,12 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sched_priority), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sched_priority", NULL}; static _PyArg_Parser _parser = { @@ -4814,18 +4414,9 @@ static PyObject * os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -4834,13 +4425,12 @@ os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(pid), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"pid", NULL}; static _PyArg_Parser _parser = { @@ -5308,18 +4898,9 @@ static PyObject * os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -5328,13 +4909,12 @@ os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(options), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"options", NULL}; static _PyArg_Parser _parser = { @@ -5383,18 +4963,9 @@ static PyObject * os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -5403,13 +4974,12 @@ os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(pid), &_Py_ID(options), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"pid", "options", NULL}; static _PyArg_Parser _parser = { @@ -5600,18 +5170,9 @@ static PyObject * os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -5620,13 +5181,12 @@ os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(pid), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"pid", "flags", NULL}; static _PyArg_Parser _parser = { @@ -5673,19 +5233,10 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd); static PyObject * os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -5694,13 +5245,12 @@ os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -5768,18 +5318,9 @@ static PyObject * os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -5788,13 +5329,12 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(target_is_directory), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -6051,18 +5591,9 @@ static PyObject * os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -6071,13 +5602,12 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -6154,18 +5684,9 @@ static PyObject * os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -6174,13 +5695,12 @@ os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -6293,18 +5813,9 @@ static PyObject * os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -6313,13 +5824,12 @@ os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), &_Py_ID(fd2), &_Py_ID(inheritable), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; static _PyArg_Parser _parser = { @@ -6755,18 +6265,9 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 7 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 7 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -6775,13 +6276,12 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; static _PyArg_Parser _parser = { @@ -6867,18 +6367,9 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 7 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 7 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -6887,13 +6378,12 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; static _PyArg_Parser _parser = { @@ -6986,18 +6476,9 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -7006,13 +6487,12 @@ os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", NULL}; static _PyArg_Parser _parser = { @@ -7124,18 +6604,9 @@ static PyObject * os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -7144,13 +6615,12 @@ os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -7486,18 +6956,9 @@ static PyObject * os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -7506,13 +6967,12 @@ os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; static _PyArg_Parser _parser = { @@ -7610,18 +7070,9 @@ static PyObject * os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 6 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 6 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -7630,13 +7081,12 @@ os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", "flags", NULL}; static _PyArg_Parser _parser = { @@ -7728,18 +7178,9 @@ static PyObject * os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -7748,13 +7189,12 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -7838,18 +7278,9 @@ static PyObject * os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -7858,13 +7289,12 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(device), &_Py_ID(dir_fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; static _PyArg_Parser _parser = { @@ -8103,18 +7533,9 @@ static PyObject * os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8123,13 +7544,12 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(length), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "length", NULL}; static _PyArg_Parser _parser = { @@ -8514,18 +7934,9 @@ static PyObject * os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8534,13 +7945,12 @@ os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -8591,18 +8001,9 @@ static PyObject * os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8611,13 +8012,12 @@ os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -8668,18 +8068,9 @@ static PyObject * os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8688,13 +8079,12 @@ os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -8745,18 +8135,9 @@ static PyObject * os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8765,13 +8146,12 @@ os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -8822,18 +8202,9 @@ static PyObject * os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8842,13 +8213,12 @@ os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -8899,18 +8269,9 @@ static PyObject * os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8919,13 +8280,12 @@ os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -8976,18 +8336,9 @@ static PyObject * os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -8996,13 +8347,12 @@ os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -9091,18 +8441,9 @@ static PyObject * os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9111,13 +8452,12 @@ os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -9165,18 +8505,9 @@ static PyObject * os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9185,13 +8516,12 @@ os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -9288,18 +8618,9 @@ static PyObject * os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9308,13 +8629,12 @@ os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(name), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "name", NULL}; static _PyArg_Parser _parser = { @@ -9487,18 +8807,9 @@ static PyObject * os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9507,13 +8818,12 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(filepath), &_Py_ID(operation), &_Py_ID(arguments), &_Py_ID(cwd), &_Py_ID(show_cmd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"filepath", "operation", "arguments", "cwd", "show_cmd", NULL}; static _PyArg_Parser _parser = { @@ -9641,18 +8951,9 @@ static PyObject * os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9661,13 +8962,12 @@ os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -9845,18 +9145,9 @@ static PyObject * os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9865,13 +9156,12 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -9942,18 +9232,9 @@ static PyObject * os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -9962,13 +9243,12 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(value), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -10064,18 +9344,9 @@ static PyObject * os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10084,13 +9355,12 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -10160,18 +9430,9 @@ static PyObject * os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10180,13 +9441,12 @@ os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -10288,18 +9548,9 @@ static PyObject * os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10308,13 +9559,12 @@ os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", "flags", NULL}; static _PyArg_Parser _parser = { @@ -10372,18 +9622,9 @@ static PyObject * os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10392,13 +9633,12 @@ os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(initval), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"initval", "flags", NULL}; static _PyArg_Parser _parser = { @@ -10453,18 +9693,9 @@ static PyObject * os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10473,13 +9704,12 @@ os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -10524,18 +9754,9 @@ static PyObject * os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10544,13 +9765,12 @@ os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), &_Py_ID(value), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", "value", NULL}; static _PyArg_Parser _parser = { @@ -10924,18 +10144,9 @@ static PyObject * os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -10944,13 +10155,12 @@ os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -10998,18 +10208,9 @@ static PyObject * os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11018,13 +10219,12 @@ os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -11077,18 +10277,9 @@ static PyObject * os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11097,13 +10288,12 @@ os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *cons .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(follow_symlinks), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"follow_symlinks", NULL}; static _PyArg_Parser _parser = { @@ -11197,18 +10387,9 @@ static PyObject * os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11217,13 +10398,12 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -11276,18 +10456,9 @@ static PyObject * os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11296,13 +10467,12 @@ os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -11343,18 +10513,9 @@ static PyObject * os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11363,13 +10524,12 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(size), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"size", "flags", NULL}; static _PyArg_Parser _parser = { @@ -11440,18 +10600,9 @@ static PyObject * os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11460,13 +10611,12 @@ os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(path), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = { @@ -11518,18 +10668,9 @@ static PyObject * os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11538,13 +10679,12 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(cookie), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"cookie", NULL}; static _PyArg_Parser _parser = { @@ -11599,18 +10739,9 @@ static PyObject * os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -11619,13 +10750,12 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(status), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = { @@ -12237,4 +11367,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=de9700c5cedd6f55 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dc71eece3fc988a7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index e8947aad7969..0454fbc99945 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -27,33 +27,11 @@ static PyObject * pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -102,33 +80,11 @@ static PyObject * pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -247,33 +203,11 @@ static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { @@ -387,33 +321,11 @@ static PyObject * pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -463,18 +375,9 @@ static PyObject * pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -483,13 +386,12 @@ pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(encoding), &_Py_ID(namespace_separator), &_Py_ID(intern), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; static _PyArg_Parser _parser = { @@ -596,4 +498,4 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg) #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=94c16fdc27f36fae input=a9049054013a1b77]*/ +/*[clinic end generated code: output=de5f664ef05ef34a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 14c4d13c2152..fda9aaab4755 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -528,18 +528,9 @@ static PyObject * select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -548,13 +539,12 @@ select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sizehint), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sizehint", "flags", NULL}; static _PyArg_Parser _parser = { @@ -704,18 +694,9 @@ static PyObject * select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -724,13 +705,12 @@ select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", "eventmask", NULL}; static _PyArg_Parser _parser = { @@ -791,18 +771,9 @@ static PyObject * select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -811,13 +782,12 @@ select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", "eventmask", NULL}; static _PyArg_Parser _parser = { @@ -870,18 +840,9 @@ static PyObject * select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -890,13 +851,12 @@ select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fd), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = { @@ -951,18 +911,9 @@ static PyObject * select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -971,13 +922,12 @@ select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(timeout), &_Py_ID(maxevents), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"timeout", "maxevents", NULL}; static _PyArg_Parser _parser = { @@ -1360,4 +1310,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=54df930a8e55d87e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9556c7d6cd5192d1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index cb1354ad2a06..ad15ddaadfc8 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -91,18 +91,9 @@ static PyObject * _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -111,13 +102,12 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -158,4 +148,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=cefc4e5d2d92698a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4d1293ca3472acdb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h index a55008d2a9a5..10d09fac695f 100644 --- a/Modules/clinic/sha256module.c.h +++ b/Modules/clinic/sha256module.c.h @@ -91,18 +91,9 @@ static PyObject * _sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -111,13 +102,12 @@ _sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -175,18 +165,9 @@ static PyObject * _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -195,13 +176,12 @@ _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -242,4 +222,4 @@ _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=15651dcd37e35962 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ae926f7ec85e7c97 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index 958de317dee6..f8d326363c39 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -91,18 +91,9 @@ static PyObject * _sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -111,13 +102,12 @@ _sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -175,18 +165,9 @@ static PyObject * _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -195,13 +176,12 @@ _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = { @@ -242,4 +222,4 @@ _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: return return_value; } -/*[clinic end generated code: output=dff35c49c5d07fae input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd168f3f21097afe input=a9049054013a1b77]*/ diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h index 9c5a96477138..8ff1044d013b 100644 --- a/Modules/clinic/socketmodule.c.h +++ b/Modules/clinic/socketmodule.c.h @@ -16,18 +16,9 @@ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -36,13 +27,12 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(family), &_Py_ID(type), &_Py_ID(proto), &_Py_ID(fileno), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"family", "type", "proto", "fileno", NULL}; static _PyArg_Parser _parser = { @@ -101,4 +91,4 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a2c5f7be40570213 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=987155ac4b48a198 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 8ceaf28073b3..a04b954a57f3 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -31,18 +31,9 @@ static PyObject * zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -51,13 +42,12 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(level), &_Py_ID(wbits), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "level", "wbits", NULL}; static _PyArg_Parser _parser = { @@ -135,18 +125,9 @@ static PyObject * zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -155,13 +136,12 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(wbits), &_Py_ID(bufsize), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; static _PyArg_Parser _parser = { @@ -264,18 +244,9 @@ static PyObject * zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 6 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 6 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -284,13 +255,12 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(level), &_Py_ID(method), &_Py_ID(wbits), &_Py_ID(memLevel), &_Py_ID(strategy), &_Py_ID(zdict), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; static _PyArg_Parser _parser = { @@ -401,18 +371,9 @@ static PyObject * zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -421,13 +382,12 @@ zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(wbits), &_Py_ID(zdict), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"wbits", "zdict", NULL}; static _PyArg_Parser _parser = { @@ -489,33 +449,11 @@ static PyObject * zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -577,18 +515,9 @@ static PyObject * zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -597,13 +526,12 @@ zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(max_length), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "max_length", NULL}; static _PyArg_Parser _parser = { @@ -677,33 +605,11 @@ static PyObject * zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -802,33 +708,11 @@ static PyObject * zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -922,33 +806,11 @@ static PyObject * zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -993,33 +855,11 @@ static PyObject * zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 0 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { }, - }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { @@ -1191,4 +1031,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=ea8865903fb98344 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9e5f9911d0c273e1 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index a2b8108b1b7d..142f29981607 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -16,18 +16,9 @@ static int bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -36,13 +27,12 @@ bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -249,18 +239,9 @@ static PyObject * bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -269,13 +250,12 @@ bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(delete), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "delete", NULL}; static _PyArg_Parser _parser = { @@ -462,18 +442,9 @@ static PyObject * bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -482,13 +453,12 @@ bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -594,18 +564,9 @@ static PyObject * bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -614,13 +575,12 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -981,18 +941,9 @@ static PyObject * bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1001,13 +952,12 @@ bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -1098,18 +1048,9 @@ static PyObject * bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1118,13 +1059,12 @@ bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(keepends), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"keepends", NULL}; static _PyArg_Parser _parser = { @@ -1223,18 +1163,9 @@ static PyObject * bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1243,13 +1174,12 @@ bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = { @@ -1357,4 +1287,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=d3a4d0ae9fb8c738 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=72bfa6cac2fd6832 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index 595566b124a5..904124ec479a 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -50,18 +50,9 @@ static PyObject * bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -70,13 +61,12 @@ bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -234,18 +224,9 @@ static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -254,13 +235,12 @@ bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -446,18 +426,9 @@ static PyObject * bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -466,13 +437,12 @@ bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(delete), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "delete", NULL}; static _PyArg_Parser _parser = { @@ -739,18 +709,9 @@ static PyObject * bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -759,13 +720,12 @@ bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -843,18 +803,9 @@ static PyObject * bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -863,13 +814,12 @@ bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, P .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(keepends), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"keepends", NULL}; static _PyArg_Parser _parser = { @@ -968,18 +918,9 @@ static PyObject * bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -988,13 +929,12 @@ bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = { @@ -1040,18 +980,9 @@ static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1060,13 +991,12 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -1133,4 +1063,4 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=2e2262ea3fb16bd3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5e0a25b7ba749a04 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index 34a6fe950e9d..da33f4a6a20c 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -192,18 +192,9 @@ static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 18 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 18 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -212,13 +203,12 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(co_argcount), &_Py_ID(co_posonlyargcount), &_Py_ID(co_kwonlyargcount), &_Py_ID(co_nlocals), &_Py_ID(co_stacksize), &_Py_ID(co_flags), &_Py_ID(co_firstlineno), &_Py_ID(co_code), &_Py_ID(co_consts), &_Py_ID(co_names), &_Py_ID(co_varnames), &_Py_ID(co_freevars), &_Py_ID(co_cellvars), &_Py_ID(co_filename), &_Py_ID(co_name), &_Py_ID(co_qualname), &_Py_ID(co_linetable), &_Py_ID(co_exceptiontable), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_exceptiontable", NULL}; static _PyArg_Parser _parser = { @@ -457,18 +447,9 @@ static PyObject * code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -477,13 +458,12 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(oparg), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"oparg", NULL}; static _PyArg_Parser _parser = { @@ -508,4 +488,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=5dec2deb4a909b1b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b6c98f17c60ace53 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h index 6c5ca3b4db59..e92c6e985852 100644 --- a/Objects/clinic/complexobject.c.h +++ b/Objects/clinic/complexobject.c.h @@ -108,18 +108,9 @@ static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -128,13 +119,12 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(real), &_Py_ID(imag), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"real", "imag", NULL}; static _PyArg_Parser _parser = { @@ -170,4 +160,4 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=cbd44b1d2428d4d8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52e85a1e258425d6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/descrobject.c.h b/Objects/clinic/descrobject.c.h index 145eba5ef33c..75706437df83 100644 --- a/Objects/clinic/descrobject.c.h +++ b/Objects/clinic/descrobject.c.h @@ -15,18 +15,9 @@ static PyObject * mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -35,13 +26,12 @@ mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(mapping), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"mapping", NULL}; static _PyArg_Parser _parser = { @@ -111,18 +101,9 @@ static int property_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -131,13 +112,12 @@ property_init(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(fget), &_Py_ID(fset), &_Py_ID(fdel), &_Py_ID(doc), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL}; static _PyArg_Parser _parser = { @@ -187,4 +167,4 @@ property_init(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=8079991d1579d46d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8dc1ddfcf764ac8e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/enumobject.c.h b/Objects/clinic/enumobject.c.h index 62b1c901caa5..208a9e8be1a1 100644 --- a/Objects/clinic/enumobject.c.h +++ b/Objects/clinic/enumobject.c.h @@ -30,18 +30,9 @@ static PyObject * enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -50,13 +41,12 @@ enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(start), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "start", NULL}; static _PyArg_Parser _parser = { @@ -117,4 +107,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=ee3984d523ead60e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=683261097bfd794a input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index 4580b3b3f959..c3a3a8edc392 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -33,18 +33,9 @@ static PyObject * func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -53,13 +44,12 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(code), &_Py_ID(globals), &_Py_ID(name), &_Py_ID(argdefs), &_Py_ID(closure), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"code", "globals", "name", "argdefs", "closure", NULL}; static _PyArg_Parser _parser = { @@ -114,4 +104,4 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=d1e30fc268fadb6f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=777cead7b1f6fad3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index 13922f0ff09c..926eaa5d3698 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -172,18 +172,9 @@ static PyObject * list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -192,13 +183,12 @@ list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(reverse), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "reverse", NULL}; static _PyArg_Parser _parser = { @@ -392,4 +382,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=45d61f54b3ab33ff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=782ed6c68b1c9f83 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 08138c85f102..1cf5b4318859 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -15,18 +15,9 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -35,13 +26,12 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(base), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "base", NULL}; static _PyArg_Parser _parser = { @@ -296,18 +286,9 @@ static PyObject * int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -316,13 +297,12 @@ int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject * .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(length), &_Py_ID(byteorder), &_Py_ID(signed), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"length", "byteorder", "signed", NULL}; static _PyArg_Parser _parser = { @@ -420,18 +400,9 @@ static PyObject * int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -440,13 +411,12 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(bytes), &_Py_ID(byteorder), &_Py_ID(signed), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL}; static _PyArg_Parser _parser = { @@ -496,4 +466,4 @@ int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyOb exit: return return_value; } -/*[clinic end generated code: output=8c99dba22fab5787 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b29b4afc65e3290e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index dd21cf6f1cef..ff7b50bb114b 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -21,18 +21,9 @@ static PyObject * memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -41,13 +32,12 @@ memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(object), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"object", NULL}; static _PyArg_Parser _parser = { @@ -107,18 +97,9 @@ static PyObject * memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -127,13 +108,12 @@ memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t narg .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(format), &_Py_ID(shape), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"format", "shape", NULL}; static _PyArg_Parser _parser = { @@ -228,18 +208,9 @@ static PyObject * memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -248,13 +219,12 @@ memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(order), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"order", NULL}; static _PyArg_Parser _parser = { @@ -333,18 +303,9 @@ static PyObject * memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -353,13 +314,12 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = { @@ -396,4 +356,4 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=9617628ea080c887 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a832f2fc44e4794c input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index 1208d6cf2943..861bcea62159 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -23,18 +23,9 @@ static int module___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -43,13 +34,12 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), &_Py_ID(doc), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", "doc", NULL}; static _PyArg_Parser _parser = { @@ -87,4 +77,4 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=44f58e856e7f3821 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f897c9e4721f03f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h index 3485ca72e530..115a134e3f7f 100644 --- a/Objects/clinic/odictobject.c.h +++ b/Objects/clinic/odictobject.c.h @@ -24,18 +24,9 @@ static PyObject * OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -44,13 +35,12 @@ OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(iterable), &_Py_ID(value), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"iterable", "value", NULL}; static _PyArg_Parser _parser = { @@ -99,18 +89,9 @@ static PyObject * OrderedDict_setdefault(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -119,13 +100,12 @@ OrderedDict_setdefault(PyODictObject *self, PyObject *const *args, Py_ssize_t na .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(default), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "default", NULL}; static _PyArg_Parser _parser = { @@ -175,18 +155,9 @@ static PyObject * OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -195,13 +166,12 @@ OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(default), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "default", NULL}; static _PyArg_Parser _parser = { @@ -249,18 +219,9 @@ static PyObject * OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -269,13 +230,12 @@ OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(last), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"last", NULL}; static _PyArg_Parser _parser = { @@ -324,18 +284,9 @@ static PyObject * OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -344,13 +295,12 @@ OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(last), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "last", NULL}; static _PyArg_Parser _parser = { @@ -382,4 +332,4 @@ OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=39e6c9c21a594053 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=76d85a9162d62ca8 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/structseq.c.h b/Objects/clinic/structseq.c.h index b35afa6e069d..40ba18a544f4 100644 --- a/Objects/clinic/structseq.c.h +++ b/Objects/clinic/structseq.c.h @@ -15,18 +15,9 @@ static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -35,13 +26,12 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sequence), &_Py_ID(dict), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sequence", "dict", NULL}; static _PyArg_Parser _parser = { @@ -72,4 +62,4 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=04b155379fef0f60 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=802d5663c7d01024 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 959e3bbc988f..d803a2733bd6 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -160,18 +160,9 @@ static PyObject * unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -180,13 +171,12 @@ unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -263,18 +253,9 @@ static PyObject * unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -283,13 +264,12 @@ unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(tabsize), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"tabsize", NULL}; static _PyArg_Parser _parser = { @@ -974,18 +954,9 @@ static PyObject * unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -994,13 +965,12 @@ unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -1106,18 +1076,9 @@ static PyObject * unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1126,13 +1087,12 @@ unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "maxsplit", NULL}; static _PyArg_Parser _parser = { @@ -1197,18 +1157,9 @@ static PyObject * unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1217,13 +1168,12 @@ unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(keepends), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"keepends", NULL}; static _PyArg_Parser _parser = { @@ -1464,18 +1414,9 @@ static PyObject * unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1484,13 +1425,12 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(object), &_Py_ID(encoding), &_Py_ID(errors), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"object", "encoding", "errors", NULL}; static _PyArg_Parser _parser = { @@ -1557,4 +1497,4 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=7688af9eecfc6bfd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e775ff4154f1c935 input=a9049054013a1b77]*/ diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index 7de659a70b03..49388cf043ce 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -26,18 +26,9 @@ static PyObject * stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -46,13 +37,12 @@ stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(tabsize), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"tabsize", NULL}; static _PyArg_Parser _parser = { @@ -288,4 +278,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a4fa1e513dd6a2f3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d44a269805f6739e input=a9049054013a1b77]*/ diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index 7250150232b9..b2f3b4ce8b08 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -27,18 +27,9 @@ static PyObject * _testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -47,13 +38,12 @@ _testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), &_Py_ID(s), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", "s", NULL}; static _PyArg_Parser _parser = { @@ -102,18 +92,9 @@ static PyObject * _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -122,13 +103,12 @@ _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nar .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(file), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"file", NULL}; static _PyArg_Parser _parser = { @@ -160,4 +140,4 @@ _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF #define _TESTCONSOLE_READ_OUTPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ -/*[clinic end generated code: output=73b7768a87e295a9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=208c72e2c873555b input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 2cf50ef5ce34..dc78274e062b 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -93,18 +93,9 @@ static PyObject * winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -113,13 +104,12 @@ winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t n .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(exc_type), &_Py_ID(exc_value), &_Py_ID(traceback), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"exc_type", "exc_value", "traceback", NULL}; static _PyArg_Parser _parser = { @@ -325,18 +315,9 @@ static PyObject * winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -345,13 +326,12 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; static _PyArg_Parser _parser = { @@ -512,18 +492,9 @@ static PyObject * winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -532,13 +503,12 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(access), &_Py_ID(reserved), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL}; static _PyArg_Parser _parser = { @@ -926,18 +896,9 @@ static PyObject * winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -946,13 +907,12 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; static _PyArg_Parser _parser = { @@ -1049,18 +1009,9 @@ static PyObject * winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1069,13 +1020,12 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; static _PyArg_Parser _parser = { @@ -1629,4 +1579,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=dc148c077a03843e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5dfd7dbce8ccb392 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index c4814104fd30..241d547c267a 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -29,18 +29,9 @@ static PyObject * winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -49,13 +40,12 @@ winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sound), &_Py_ID(flags), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sound", "flags", NULL}; static _PyArg_Parser _parser = { @@ -105,18 +95,9 @@ static PyObject * winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -125,13 +106,12 @@ winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(frequency), &_Py_ID(duration), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"frequency", "duration", NULL}; static _PyArg_Parser _parser = { @@ -180,18 +160,9 @@ static PyObject * winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -200,13 +171,12 @@ winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(type), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"type", NULL}; static _PyArg_Parser _parser = { @@ -236,4 +206,4 @@ winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=bdca8518ca517fd8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f70b7730127208d8 input=a9049054013a1b77]*/ diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h index 61bf29155153..6af93743f40d 100644 --- a/Python/clinic/Python-tokenize.c.h +++ b/Python/clinic/Python-tokenize.c.h @@ -15,18 +15,9 @@ static PyObject * tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -35,13 +26,12 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(source), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"source", NULL}; static _PyArg_Parser _parser = { @@ -77,4 +67,4 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=5664c98597aec79e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c2c09f651961986 input=a9049054013a1b77]*/ diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h index 7944412dfdb0..13ebbf45b8e1 100644 --- a/Python/clinic/_warnings.c.h +++ b/Python/clinic/_warnings.c.h @@ -25,18 +25,9 @@ static PyObject * warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -45,13 +36,12 @@ warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(stacklevel), &_Py_ID(source), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL}; static _PyArg_Parser _parser = { @@ -127,18 +117,9 @@ static PyObject * warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 8 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 8 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -147,13 +128,12 @@ warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(filename), &_Py_ID(lineno), &_Py_ID(module), &_Py_ID(registry), &_Py_ID(module_globals), &_Py_ID(source), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"message", "category", "filename", "lineno", "module", "registry", "module_globals", "source", NULL}; static _PyArg_Parser _parser = { @@ -219,4 +199,4 @@ warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=264258fa6b1b0c36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2eac4fabc87a4d56 input=a9049054013a1b77]*/ diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 76f9fcab80c3..abe5476b283b 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -40,18 +40,9 @@ static PyObject * builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 5 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 5 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -60,13 +51,12 @@ builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(name), &_Py_ID(globals), &_Py_ID(locals), &_Py_ID(fromlist), &_Py_ID(level), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL}; static _PyArg_Parser _parser = { @@ -292,18 +282,9 @@ static PyObject * builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 7 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 7 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -312,13 +293,12 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(source), &_Py_ID(filename), &_Py_ID(mode), &_Py_ID(flags), &_Py_ID(dont_inherit), &_Py_ID(optimize), &_Py_ID(_feature_version), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; static _PyArg_Parser _parser = { @@ -504,18 +484,9 @@ static PyObject * builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -524,13 +495,12 @@ builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(closure), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "", "", "closure", NULL}; static _PyArg_Parser _parser = { @@ -848,18 +818,9 @@ static PyObject * builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 3 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -868,13 +829,12 @@ builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(base), &_Py_ID(exp), &_Py_ID(mod), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"base", "exp", "mod", NULL}; static _PyArg_Parser _parser = { @@ -932,18 +892,9 @@ static PyObject * builtin_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -952,13 +903,12 @@ builtin_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(sep), &_Py_ID(end), &_Py_ID(file), &_Py_ID(flush), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"sep", "end", "file", "flush", NULL}; static _PyArg_Parser _parser = { @@ -1081,18 +1031,9 @@ static PyObject * builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1101,13 +1042,12 @@ builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(number), &_Py_ID(ndigits), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"number", "ndigits", NULL}; static _PyArg_Parser _parser = { @@ -1157,18 +1097,9 @@ static PyObject * builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -1177,13 +1108,12 @@ builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(start), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "start", NULL}; static _PyArg_Parser _parser = { @@ -1282,4 +1212,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=4590e66a40312a9f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=919725bf5d400acf input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 69eebde6d6b3..819fb1c75c15 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -199,18 +199,9 @@ static PyObject * _imp_find_frozen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -219,13 +210,12 @@ _imp_find_frozen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(withdata), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"", "withdata", NULL}; static _PyArg_Parser _parser = { @@ -565,18 +555,9 @@ static PyObject * _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 2 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 2 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -585,13 +566,12 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(key), &_Py_ID(source), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"key", "source", NULL}; static _PyArg_Parser _parser = { @@ -637,4 +617,4 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=7d75c10a93f2f26c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=806352838c3f7008 input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index e1021bbbd788..beaf21c85bcf 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -24,18 +24,9 @@ static PyObject * sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -44,13 +35,12 @@ sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(hook), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"hook", NULL}; static _PyArg_Parser _parser = { @@ -464,18 +454,9 @@ static PyObject * sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 1 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -484,13 +465,12 @@ sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(depth), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"depth", NULL}; static _PyArg_Parser _parser = { @@ -1190,4 +1170,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=b8b125686bc745a6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=38446a4c76e2f3b6 input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index 5de11021b497..3c3449349716 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -22,18 +22,9 @@ static PyObject * tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #define NUM_KEYWORDS 4 - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -42,13 +33,12 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_item = { &_Py_ID(tb_next), &_Py_ID(tb_frame), &_Py_ID(tb_lasti), &_Py_ID(tb_lineno), }, }; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; static _PyArg_Parser _parser = { @@ -88,4 +78,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=130ba2a638849c70 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7bc9927e362fdfb7 input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 88f779e64a0d..805bdcb43654 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -535,7 +535,7 @@ def normalize_snippet(s, *, indent=0): return s -def declare_parser(*, hasformat=False): +def declare_parser(f, *, hasformat=False): """ Generates the code template for a static local PyArg_Parser variable, with an initializer. For core code (incl. builtin modules) the @@ -548,43 +548,49 @@ def declare_parser(*, hasformat=False): else: fname = '.fname = "{name}",' format_ = '' - declarations = """ - #define NUM_KEYWORDS {num_keywords} - #if NUM_KEYWORDS == 0 - - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) - # else - # define KWTUPLE NULL - # endif - - #else // NUM_KEYWORDS != 0 - # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - static struct {{ - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - }} _kwtuple = {{ - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = {{ {keywords_py} }}, - }}; - # define KWTUPLE (&_kwtuple.ob_base.ob_base) - - # else // !Py_BUILD_CORE - # define KWTUPLE NULL - # endif // !Py_BUILD_CORE - #endif // NUM_KEYWORDS != 0 - #undef NUM_KEYWORDS - - static const char * const _keywords[] = {{{keywords_c} NULL}}; - static _PyArg_Parser _parser = {{ - .keywords = _keywords, - %s - .kwtuple = KWTUPLE, - }}; - #undef KWTUPLE - """ % (format_ or fname) + + num_keywords = len([ + p for p in f.parameters.values() + if not p.is_positional_only() and not p.is_vararg() + ]) + if num_keywords == 0: + declarations = """ + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + """ + else: + declarations = """ + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS %d + static struct {{ + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + }} _kwtuple = {{ + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = {{ {keywords_py} }}, + }}; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + """ % num_keywords + + declarations += """ + static const char * const _keywords[] = {{{keywords_c} NULL}}; + static _PyArg_Parser _parser = {{ + .keywords = _keywords, + %s + .kwtuple = KWTUPLE, + }}; + #undef KWTUPLE + """ % (format_ or fname) return normalize_snippet(declarations) @@ -1020,7 +1026,7 @@ def parser_body(prototype, *fields, declarations=''): flags = "METH_FASTCALL|METH_KEYWORDS" parser_prototype = parser_prototype_fastcall_keywords argname_fmt = 'args[%d]' - declarations = declare_parser() + declarations = declare_parser(f) declarations += "\nPyObject *argsbuf[%s];" % len(converters) if has_optional_kw: pre_buffer = "0" if vararg != NO_VARARG else "nargs" @@ -1036,7 +1042,7 @@ def parser_body(prototype, *fields, declarations=''): flags = "METH_VARARGS|METH_KEYWORDS" parser_prototype = parser_prototype_keyword argname_fmt = 'fastargs[%d]' - declarations = declare_parser() + declarations = declare_parser(f) declarations += "\nPyObject *argsbuf[%s];" % len(converters) declarations += "\nPyObject * const *fastargs;" declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" @@ -1116,7 +1122,7 @@ def parser_body(prototype, *fields, declarations=''): if add_label: parser_code.append("%s:" % add_label) else: - declarations = declare_parser(hasformat=True) + declarations = declare_parser(f, hasformat=True) if not new_or_init: parser_code = [normalize_snippet(""" if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma} @@ -1442,7 +1448,6 @@ def render_function(self, clinic, f): template_dict['keywords_c'] = ' '.join('"' + k + '",' for k in data.keywords) keywords = [k for k in data.keywords if k] - template_dict['num_keywords'] = len(keywords) template_dict['keywords_py'] = ' '.join('&_Py_ID(' + k + '),' for k in keywords) template_dict['format_units'] = ''.join(data.format_units) From webhook-mailer at python.org Sat Aug 13 07:49:09 2022 From: webhook-mailer at python.org (iritkatriel) Date: Sat, 13 Aug 2022 11:49:09 -0000 Subject: [Python-checkins] gh-95914: Add paragraph about PEP 654 in main body of 'What's New in 3.11' (GH-95937) Message-ID: <mailman.660.1660391350.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1402d2ceca8ccef8c3538906b3f547365891d391 commit: 1402d2ceca8ccef8c3538906b3f547365891d391 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-13T12:49:04+01:00 summary: gh-95914: Add paragraph about PEP 654 in main body of 'What's New in 3.11' (GH-95937) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 41aa6944395f..637d12b61e7f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -176,8 +176,25 @@ The :option:`-X` ``no_debug_ranges`` option and the environment variable See :pep:`657` for more details. (Contributed by Pablo Galindo, Batuhan Taskaya and Ammar Askar in :issue:`43950`.) -Exceptions can be enriched with notes (PEP 678) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PEP 654: Exception Groups and ``except*`` +----------------------------------------- + +:pep:`654` introduces language features that enable a program +to raise and handle multiple unrelated exceptions simultaneously. +The builtin types :exc:`ExceptionGroup` and :exc:`BaseExceptionGroup` +make it possible to group exceptions and raise them together, +and the new :keyword:`except* <except_star>` syntax generalizes +:keyword:`except` to match subgroups of exception groups. + +See :pep:`654` for more details. + +(Contributed by Irit Katriel in :issue:`45292`. PEP written by +Irit Katriel, Yury Selivanov and Guido van Rossum.) + + +PEP 678: Exceptions can be enriched with notes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`add_note` method was added to :exc:`BaseException`. It can be used to enrich exceptions with context information which is not available From webhook-mailer at python.org Sat Aug 13 14:27:50 2022 From: webhook-mailer at python.org (pablogsal) Date: Sat, 13 Aug 2022 18:27:50 -0000 Subject: [Python-checkins] bpo-25625: Document contextlib.chdir in the 3.11 what's new (#95962) Message-ID: <mailman.661.1660415271.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7552f237a262b9b593df012fdf2ddaa0d914a1e9 commit: 7552f237a262b9b593df012fdf2ddaa0d914a1e9 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-13T19:27:44+01:00 summary: bpo-25625: Document contextlib.chdir in the 3.11 what's new (#95962) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 637d12b61e7..7be9a501f53 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -495,6 +495,13 @@ asyncio holding a group of tasks that will wait for all of them upon exit. (Contributed by Yury Seliganov and others.) +contextlib +---------- + +Added non parallel-safe :func:`~contextlib.chdir` context manager to change +the current working directory and then restore it on exit. Simple wrapper +around :func:`~os.chdir`. (Contributed by Filipe La?ns in :issue:`25625`) + datetime -------- From webhook-mailer at python.org Sat Aug 13 14:34:23 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 13 Aug 2022 18:34:23 -0000 Subject: [Python-checkins] bpo-25625: Document contextlib.chdir in the 3.11 what's new (GH-95962) Message-ID: <mailman.662.1660415663.3313.python-checkins@python.org> https://github.com/python/cpython/commit/63690996e8e8435b7cb9f77db82761316eefef85 commit: 63690996e8e8435b7cb9f77db82761316eefef85 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-13T11:34:17-07:00 summary: bpo-25625: Document contextlib.chdir in the 3.11 what's new (GH-95962) (cherry picked from commit 7552f237a262b9b593df012fdf2ddaa0d914a1e9) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 0c37cc451719..6c8f7913a346 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -478,6 +478,13 @@ asyncio holding a group of tasks that will wait for all of them upon exit. (Contributed by Yury Seliganov and others.) +contextlib +---------- + +Added non parallel-safe :func:`~contextlib.chdir` context manager to change +the current working directory and then restore it on exit. Simple wrapper +around :func:`~os.chdir`. (Contributed by Filipe La?ns in :issue:`25625`) + datetime -------- From webhook-mailer at python.org Sat Aug 13 14:42:34 2022 From: webhook-mailer at python.org (pablogsal) Date: Sat, 13 Aug 2022 18:42:34 -0000 Subject: [Python-checkins] [3.11] gh-94439: typing docs: Add minimum version to `__required_keys__` and `__optional_keys__` (GH-95373) (#95944) Message-ID: <mailman.663.1660416155.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1fccb1d49334804f19cc809c968afee2aabb9b3a commit: 1fccb1d49334804f19cc809c968afee2aabb9b3a branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-13T19:42:27+01:00 summary: [3.11] gh-94439: typing docs: Add minimum version to `__required_keys__` and `__optional_keys__` (GH-95373) (#95944) Co-authored-by: Howie Zhao <howiezhaohr at hotmail.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index ba73d69e8794..0951916f080a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1825,6 +1825,9 @@ These are not used in annotations. They are building blocks for declaring types. True .. attribute:: __required_keys__ + + .. versionadded:: 3.9 + .. attribute:: __optional_keys__ ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return @@ -1852,6 +1855,8 @@ These are not used in annotations. They are building blocks for declaring types. >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) True + .. versionadded:: 3.9 + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 From webhook-mailer at python.org Sat Aug 13 15:01:07 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 13 Aug 2022 19:01:07 -0000 Subject: [Python-checkins] gh-89313: Add hashlib.file_digest to whatsnew 3.11 (GH-95965) Message-ID: <mailman.664.1660417268.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0b329f4f03b3e2d603cf81c39e7c9d83da123717 commit: 0b329f4f03b3e2d603cf81c39e7c9d83da123717 branch: main author: Christian Heimes <christian at python.org> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-13T12:00:58-07:00 summary: gh-89313: Add hashlib.file_digest to whatsnew 3.11 (GH-95965) Automerge-Triggered-By: GH:pablogsal files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 7be9a501f53..f1f023038ab 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -609,6 +609,10 @@ hashlib OpenSSL support. (Contributed by Christian Heimes in :issue:`47098`.) +* Add :func:`hashlib.file_digest`, a helper function for efficient hashing + of files or file-like objects. + (Contributed by Christian Heimes in :gh:`89313`.) + IDLE and idlelib ---------------- From webhook-mailer at python.org Sat Aug 13 15:55:24 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 13 Aug 2022 19:55:24 -0000 Subject: [Python-checkins] gh-89313: Add hashlib.file_digest to whatsnew 3.11 (GH-95965) Message-ID: <mailman.665.1660420525.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d89f5fe1f4ee630a83196a7a7bf5a03a81036bb5 commit: d89f5fe1f4ee630a83196a7a7bf5a03a81036bb5 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-13T12:55:15-07:00 summary: gh-89313: Add hashlib.file_digest to whatsnew 3.11 (GH-95965) Automerge-Triggered-By: GH:pablogsal (cherry picked from commit 0b329f4f03b3e2d603cf81c39e7c9d83da123717) Co-authored-by: Christian Heimes <christian at python.org> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 6c8f7913a34..99cf77dadb5 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -592,6 +592,10 @@ hashlib OpenSSL support. (Contributed by Christian Heimes in :issue:`47098`.) +* Add :func:`hashlib.file_digest`, a helper function for efficient hashing + of files or file-like objects. + (Contributed by Christian Heimes in :gh:`89313`.) + IDLE and idlelib ---------------- From webhook-mailer at python.org Sat Aug 13 15:56:12 2022 From: webhook-mailer at python.org (tiran) Date: Sat, 13 Aug 2022 19:56:12 -0000 Subject: [Python-checkins] gh-95853: Add script to automate WASM build (GH-95828) Message-ID: <mailman.666.1660420573.3313.python-checkins@python.org> https://github.com/python/cpython/commit/32ac98e8992caa47ff31e3021444949df058e413 commit: 32ac98e8992caa47ff31e3021444949df058e413 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-13T21:56:08+02:00 summary: gh-95853: Add script to automate WASM build (GH-95828) Automate WASM build with a new Python script. The script provides several build profiles with configure flags for Emscripten flavors and WASI. The script can detect and use Emscripten SDK and WASI SDK from default locations or env vars. ``configure`` now detects Node arguments and creates HOSTRUNNER arguments for Node 16. It also sets correct arguments for ``wasm64-emscripten``. Co-authored-by: Brett Cannon <brett at python.org> files: A Misc/NEWS.d/next/Tools-Demos/2022-08-10-17-08-43.gh-issue-95853.HCjC2m.rst A Tools/wasm/wasm_build.py M Lib/test/test_unicode_file_functions.py M Lib/test/test_warnings/__init__.py M Python/sysmodule.c M Tools/wasm/README.md M Tools/wasm/wasi-env M configure M configure.ac diff --git a/Lib/test/test_unicode_file_functions.py b/Lib/test/test_unicode_file_functions.py index 54916dec4eaf..47619c8807ba 100644 --- a/Lib/test/test_unicode_file_functions.py +++ b/Lib/test/test_unicode_file_functions.py @@ -6,6 +6,7 @@ import warnings from unicodedata import normalize from test.support import os_helper +from test import support filenames = [ @@ -123,6 +124,10 @@ def test_open(self): # NFKD in Python is useless, because darwin will normalize it later and so # open(), os.stat(), etc. don't raise any exception. @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X') + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "test fails on Emscripten/WASI when host platform is macOS." + ) def test_normalize(self): files = set(self.files) others = set() diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index b00ddd5df2f2..9e473e923cad 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -487,7 +487,14 @@ def test_warn_explicit_non_ascii_filename(self): module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("always", category=UserWarning) - for filename in ("nonascii\xe9\u20ac", "surrogate\udc80"): + filenames = ["nonascii\xe9\u20ac"] + if not support.is_emscripten: + # JavaScript does not like surrogates. + # Invalid UTF-8 leading byte 0x80 encountered when + # deserializing a UTF-8 string in wasm memory to a JS + # string! + filenames.append("surrogate\udc80") + for filename in filenames: try: os.fsencode(filename) except UnicodeEncodeError: diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-10-17-08-43.gh-issue-95853.HCjC2m.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-10-17-08-43.gh-issue-95853.HCjC2m.rst new file mode 100644 index 000000000000..c38db3af425e --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-10-17-08-43.gh-issue-95853.HCjC2m.rst @@ -0,0 +1,2 @@ +The new tool ``Tools/wasm/wasm_builder.py`` automates configure, compile, and +test steps for building CPython on WebAssembly platforms. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index e861d9cbce41..b8009b2db45f 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2789,14 +2789,18 @@ EM_JS(char *, _Py_emscripten_runtime, (void), { if (typeof navigator == 'object') { info = navigator.userAgent; } else if (typeof process == 'object') { - info = "Node.js ".concat(process.version) + info = "Node.js ".concat(process.version); } else { - info = "UNKNOWN" + info = "UNKNOWN"; } var len = lengthBytesUTF8(info) + 1; var res = _malloc(len); - stringToUTF8(info, res, len); + if (res) stringToUTF8(info, res, len); +#if __wasm64__ + return BigInt(res); +#else return res; +#endif }); static PyObject * diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index 6496a29e6ff8..c4c21b4f09dd 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -35,7 +35,13 @@ docker run --rm -ti -v $(pwd):/python-wasm/cpython -w /python-wasm/cpython quay. ### Compile a build Python interpreter -From within the container, run the following commands: +From within the container, run the following command: + +```shell +./Tools/wasm/wasm_build.py build +``` + +The command is roughly equivalent to: ```shell mkdir -p builddir/build @@ -45,13 +51,13 @@ make -j$(nproc) popd ``` -### Fetch and build additional emscripten ports +### Cross-compile to wasm32-emscripten for browser ```shell -embuilder build zlib bzip2 +./Tools/wasm/wasm_build.py emscripten-browser ``` -### Cross compile to wasm32-emscripten for browser +The command is roughly equivalent to: ```shell mkdir -p builddir/emscripten-browser @@ -85,14 +91,21 @@ and header files with debug builds. ### Cross compile to wasm32-emscripten for node ```shell -mkdir -p builddir/emscripten-node -pushd builddir/emscripten-node +./Tools/wasm/wasm_build.py emscripten-browser-dl +``` + +The command is roughly equivalent to: + +```shell +mkdir -p builddir/emscripten-node-dl +pushd builddir/emscripten-node-dl CONFIG_SITE=../../Tools/wasm/config.site-wasm32-emscripten \ emconfigure ../../configure -C \ --host=wasm32-unknown-emscripten \ --build=$(../../config.guess) \ --with-emscripten-target=node \ + --enable-wasm-dynamic-linking \ --with-build-python=$(pwd)/../build/python emmake make -j$(nproc) @@ -100,7 +113,7 @@ popd ``` ```shell -node --experimental-wasm-threads --experimental-wasm-bulk-memory --experimental-wasm-bigint builddir/emscripten-node/python.js +node --experimental-wasm-threads --experimental-wasm-bulk-memory --experimental-wasm-bigint builddir/emscripten-node-dl/python.js ``` (``--experimental-wasm-bigint`` is not needed with recent NodeJS versions) @@ -199,6 +212,15 @@ Node builds use ``NODERAWFS``. - Node RawFS allows direct access to the host file system without need to perform ``FS.mount()`` call. +## wasm64-emscripten + +- wasm64 requires recent NodeJS and ``--experimental-wasm-memory64``. +- ``EM_JS`` functions must return ``BigInt()``. +- ``Py_BuildValue()`` format strings must match size of types. Confusing 32 + and 64 bits types leads to memory corruption, see + [gh-95876](https://github.com/python/cpython/issues/95876) and + [gh-95878](https://github.com/python/cpython/issues/95878). + # Hosting Python WASM builds The simple REPL terminal uses SharedArrayBuffer. For security reasons @@ -234,6 +256,12 @@ The script ``wasi-env`` sets necessary compiler and linker flags as well as ``pkg-config`` overrides. The script assumes that WASI-SDK is installed in ``/opt/wasi-sdk`` or ``$WASI_SDK_PATH``. +```shell +./Tools/wasm/wasm_build.py wasi +``` + +The command is roughly equivalent to: + ```shell mkdir -p builddir/wasi pushd builddir/wasi diff --git a/Tools/wasm/wasi-env b/Tools/wasm/wasi-env index 6c2d56e0e5e3..48908b02e60b 100755 --- a/Tools/wasm/wasi-env +++ b/Tools/wasm/wasi-env @@ -72,4 +72,5 @@ export CFLAGS LDFLAGS export PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR export PATH -exec "$@" +# no exec, it makes arvg[0] path absolute. +"$@" diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py new file mode 100755 index 000000000000..e7a1f4a60071 --- /dev/null +++ b/Tools/wasm/wasm_build.py @@ -0,0 +1,567 @@ +#!/usr/bin/env python3 +"""Build script for Python on WebAssembly platforms. + + $ ./Tools/wasm/wasm_builder.py emscripten-browser compile + $ ./Tools/wasm/wasm_builder.py emscripten-node-dl test + $ ./Tools/wasm/wasm_builder.py wasi test + +Primary build targets are "emscripten-node-dl" (NodeJS, dynamic linking), +"emscripten-browser", and "wasi". + +Emscripten builds require a recent Emscripten SDK. The tools looks for an +activated EMSDK environment (". /path/to/emsdk_env.sh"). System packages +(Debian, Homebrew) are not supported. + +WASI builds require WASI SDK and wasmtime. The tool looks for 'WASI_SDK_PATH' +and falls back to /opt/wasi-sdk. +""" +import argparse +import enum +import dataclasses +import os +import pathlib +import shlex +import shutil +import subprocess +import sysconfig + +# for Python 3.8 +from typing import Any, Dict, Callable, Iterable, List, Optional, Union + +SRCDIR = pathlib.Path(__file__).parent.parent.parent.absolute() +WASMTOOLS = SRCDIR / "Tools" / "wasm" +BUILDDIR = SRCDIR / "builddir" +CONFIGURE = SRCDIR / "configure" +SETUP_LOCAL = SRCDIR / "Modules" / "Setup.local" + +HAS_CCACHE = shutil.which("ccache") is not None + +# path to WASI-SDK root +WASI_SDK_PATH = pathlib.Path(os.environ.get("WASI_SDK_PATH", "/opt/wasi-sdk")) + +# path to Emscripten SDK config file. +# auto-detect's EMSDK in /opt/emsdk without ". emsdk_env.sh". +EM_CONFIG = pathlib.Path(os.environ.setdefault("EM_CONFIG", "/opt/emsdk/.emscripten")) +# 3.1.16 has broken utime() +EMSDK_MIN_VERSION = (3, 1, 17) +_MISSING = pathlib.PurePath("MISSING") + +# WASM_WEBSERVER = WASMTOOLS / "wasmwebserver.py" + +CLEAN_SRCDIR = f""" +Builds require a clean source directory. Please use a clean checkout or +run "make clean -C '{SRCDIR}'". +""" + +INSTALL_EMSDK = """ +wasm32-emscripten builds need Emscripten SDK. Please follow instructions at +https://emscripten.org/docs/getting_started/downloads.html how to install +Emscripten and how to activate the SDK with ". /path/to/emsdk/emsdk_env.sh". + + git clone https://github.com/emscripten-core/emsdk.git /path/to/emsdk + cd /path/to/emsdk + ./emsdk install latest + ./emsdk activate latest + source /path/to/emsdk_env.sh +""" + +INSTALL_WASI_SDK = """ +wasm32-wasi builds need WASI SDK. Please fetch the latest SDK from +https://github.com/WebAssembly/wasi-sdk/releases and install it to +"/opt/wasi-sdk". Alternatively you can install the SDK in a different location +and point the environment variable WASI_SDK_PATH to the root directory +of the SDK. The SDK is available for Linux x86_64, macOS x86_64, and MinGW. +""" + +INSTALL_WASMTIME = """ +wasm32-wasi tests require wasmtime on PATH. Please follow instructions at +https://wasmtime.dev/ to install wasmtime. +""" + + +def get_emscripten_root(emconfig: pathlib.Path = EM_CONFIG) -> pathlib.PurePath: + """Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT + + The ".emscripten" config file is a Python snippet that uses "EM_CONFIG" + environment variable. EMSCRIPTEN_ROOT is the "upstream/emscripten" + subdirectory with tools like "emconfigure". + """ + if not emconfig.exists(): + return _MISSING + with open(emconfig, encoding="utf-8") as f: + code = f.read() + # EM_CONFIG file is a Python snippet + local: Dict[str, Any] = {} + exec(code, globals(), local) + return pathlib.Path(local["EMSCRIPTEN_ROOT"]) + + +EMSCRIPTEN_ROOT = get_emscripten_root() + + +class ConditionError(ValueError): + def __init__(self, info: str, text: str): + self.info = info + self.text = text + + def __str__(self): + return f"{type(self).__name__}: '{self.info}'\n{self.text}" + + +class MissingDependency(ConditionError): + pass + + +class DirtySourceDirectory(ConditionError): + pass + + + at dataclasses.dataclass +class Platform: + """Platform-specific settings + + - CONFIG_SITE override + - configure wrapper (e.g. emconfigure) + - make wrapper (e.g. emmake) + - additional environment variables + - check function to verify SDK + """ + + name: str + pythonexe: str + config_site: Optional[pathlib.PurePath] + configure_wrapper: Optional[pathlib.PurePath] + make_wrapper: Optional[pathlib.PurePath] + environ: dict + check: Callable[[], None] + + def getenv(self, profile: "BuildProfile") -> dict: + return self.environ.copy() + + +def _check_clean_src(): + candidates = [ + SRCDIR / "Programs" / "python.o", + SRCDIR / "Python" / "frozen_modules" / "importlib._bootstrap.h", + ] + for candidate in candidates: + if candidate.exists(): + raise DirtySourceDirectory(os.fspath(candidate), CLEAN_SRCDIR) + + +NATIVE = Platform( + "native", + # macOS has python.exe + pythonexe=sysconfig.get_config_var("BUILDPYTHON") or "python", + config_site=None, + configure_wrapper=None, + make_wrapper=None, + environ={}, + check=_check_clean_src, +) + + +def _check_emscripten(): + if EMSCRIPTEN_ROOT is _MISSING: + raise MissingDependency("Emscripten SDK EM_CONFIG", INSTALL_EMSDK) + # sanity check + emconfigure = EMSCRIPTEN.configure_wrapper + if not emconfigure.exists(): + raise MissingDependency(os.fspath(emconfigure), INSTALL_EMSDK) + # version check + version_txt = EMSCRIPTEN_ROOT / "emscripten-version.txt" + if not version_txt.exists(): + raise MissingDependency(os.fspath(version_txt), INSTALL_EMSDK) + with open(version_txt) as f: + version = f.read().strip().strip('"') + version_tuple = tuple(int(v) for v in version.split(".")) + if version_tuple < EMSDK_MIN_VERSION: + raise MissingDependency( + os.fspath(version_txt), + f"Emscripten SDK {version} in '{EMSCRIPTEN_ROOT}' is older than " + "minimum required version " + f"{'.'.join(str(v) for v in EMSDK_MIN_VERSION)}.", + ) + _check_clean_src() + + +EMSCRIPTEN = Platform( + "emscripten", + pythonexe="python.js", + config_site=WASMTOOLS / "config.site-wasm32-emscripten", + configure_wrapper=EMSCRIPTEN_ROOT / "emconfigure", + make_wrapper=EMSCRIPTEN_ROOT / "emmake", + environ={"EM_COMPILER_WRAPPER": "ccache"} if HAS_CCACHE else {}, + check=_check_emscripten, +) + + +def _check_wasi(): + wasm_ld = WASI_SDK_PATH / "bin" / "wasm-ld" + if not wasm_ld.exists(): + raise MissingDependency(os.fspath(wasm_ld), INSTALL_WASI_SDK) + wasmtime = shutil.which("wasmtime") + if wasmtime is None: + raise MissingDependency("wasmtime", INSTALL_WASMTIME) + _check_clean_src() + + +WASI = Platform( + "wasi", + pythonexe="python.wasm", + config_site=WASMTOOLS / "config.site-wasm32-wasi", + configure_wrapper=WASMTOOLS / "wasi-env", + make_wrapper=None, + environ={ + "WASI_SDK_PATH": WASI_SDK_PATH, + # workaround for https://github.com/python/cpython/issues/95952 + "HOSTRUNNER": ( + "wasmtime run " + "--env PYTHONPATH=/{relbuilddir}/build/lib.wasi-wasm32-$(VERSION):/Lib " + "--mapdir /::{srcdir} --" + ), + }, + check=_check_wasi, +) + + +class Host(enum.Enum): + """Target host triplet""" + + wasm32_emscripten = "wasm32-unknown-emscripten" + wasm64_emscripten = "wasm64-unknown-emscripten" + wasm32_wasi = "wasm32-unknown-wasi" + wasm64_wasi = "wasm64-unknown-wasi" + # current platform + build = sysconfig.get_config_var("BUILD_GNU_TYPE") + + @property + def platform(self) -> Platform: + if self.is_emscripten: + return EMSCRIPTEN + elif self.is_wasi: + return WASI + else: + return NATIVE + + @property + def is_emscripten(self) -> bool: + cls = type(self) + return self in {cls.wasm32_emscripten, cls.wasm64_emscripten} + + @property + def is_wasi(self) -> bool: + cls = type(self) + return self in {cls.wasm32_wasi, cls.wasm64_wasi} + + +class EmscriptenTarget(enum.Enum): + """Emscripten-specific targets (--with-emscripten-target)""" + + browser = "browser" + browser_debug = "browser-debug" + node = "node" + node_debug = "node-debug" + + @property + def can_execute(self) -> bool: + cls = type(self) + return self not in {cls.browser, cls.browser_debug} + + + at dataclasses.dataclass +class BuildProfile: + name: str + host: Host + target: Union[EmscriptenTarget, None] = None + dynamic_linking: Union[bool, None] = None + pthreads: Union[bool, None] = None + testopts: str = "-j2" + + @property + def can_execute(self) -> bool: + """Can target run pythoninfo and tests? + + Disabled for browser, enabled for all other targets + """ + return self.target is None or self.target.can_execute + + @property + def builddir(self) -> pathlib.Path: + """Path to build directory""" + return BUILDDIR / self.name + + @property + def python_cmd(self) -> pathlib.Path: + """Path to python executable""" + return self.builddir / self.host.platform.pythonexe + + @property + def makefile(self) -> pathlib.Path: + """Path to Makefile""" + return self.builddir / "Makefile" + + @property + def configure_cmd(self) -> List[str]: + """Generate configure command""" + # use relative path, so WASI tests can find lib prefix. + # pathlib.Path.relative_to() does not work here. + configure = os.path.relpath(CONFIGURE, self.builddir) + cmd = [configure, "-C"] + platform = self.host.platform + if platform.configure_wrapper: + cmd.insert(0, os.fspath(platform.configure_wrapper)) + + cmd.append(f"--host={self.host.value}") + cmd.append(f"--build={Host.build.value}") + + if self.target is not None: + assert self.host.is_emscripten + cmd.append(f"--with-emscripten-target={self.target.value}") + + if self.dynamic_linking is not None: + assert self.host.is_emscripten + opt = "enable" if self.dynamic_linking else "disable" + cmd.append(f"--{opt}-wasm-dynamic-linking") + + if self.pthreads is not None: + assert self.host.is_emscripten + opt = "enable" if self.pthreads else "disable" + cmd.append(f"--{opt}-wasm-pthreads") + + if self.host != Host.build: + cmd.append(f"--with-build-python={BUILD.python_cmd}") + + if platform.config_site is not None: + cmd.append(f"CONFIG_SITE={platform.config_site}") + + return cmd + + @property + def make_cmd(self) -> List[str]: + """Generate make command""" + cmd = ["make"] + platform = self.host.platform + if platform.make_wrapper: + cmd.insert(0, os.fspath(platform.make_wrapper)) + return cmd + + def getenv(self) -> dict: + """Generate environ dict for platform""" + env = os.environ.copy() + env.setdefault("MAKEFLAGS", f"-j{os.cpu_count()}") + platenv = self.host.platform.getenv(self) + for key, value in platenv.items(): + if isinstance(value, str): + value = value.format( + relbuilddir=self.builddir.relative_to(SRCDIR), + srcdir=SRCDIR, + ) + env[key] = value + return env + + def _run_cmd(self, cmd: Iterable[str], args: Iterable[str]): + cmd = list(cmd) + cmd.extend(args) + return subprocess.check_call( + cmd, + cwd=os.fspath(self.builddir), + env=self.getenv(), + ) + + def _check_execute(self): + if not self.can_execute: + raise ValueError(f"Cannot execute on {self.target}") + + def run_build(self, force_configure: bool = False): + """Run configure (if necessary) and make""" + if force_configure or not self.makefile.exists(): + self.run_configure() + self.run_make() + + def run_configure(self, *args): + """Run configure script to generate Makefile""" + os.makedirs(self.builddir, exist_ok=True) + return self._run_cmd(self.configure_cmd, args) + + def run_make(self, *args): + """Run make (defaults to build all)""" + return self._run_cmd(self.make_cmd, args) + + def run_pythoninfo(self): + """Run 'make pythoninfo'""" + self._check_execute() + return self.run_make("pythoninfo") + + def run_test(self): + """Run buildbottests""" + self._check_execute() + return self.run_make("buildbottest", f"TESTOPTS={self.testopts}") + + def run_py(self, *args): + """Run Python with hostrunner""" + self._check_execute() + self.run_make( + "--eval", f"run: all; $(HOSTRUNNER) ./$(PYTHON) {shlex.join(args)}", "run" + ) + + def clean(self, all: bool = False): + """Clean build directory""" + if all: + if self.builddir.exists(): + shutil.rmtree(self.builddir) + elif self.makefile.exists(): + self.run_make("clean") + + +# native build (build Python) +BUILD = BuildProfile( + "build", + host=Host.build, +) + +_profiles = [ + BUILD, + # wasm32-emscripten + BuildProfile( + "emscripten-browser", + host=Host.wasm32_emscripten, + target=EmscriptenTarget.browser, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-browser-debug", + host=Host.wasm32_emscripten, + target=EmscriptenTarget.browser_debug, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-node-dl", + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-node-dl-debug", + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node_debug, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-node-pthreads", + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node, + pthreads=True, + ), + BuildProfile( + "emscripten-node-pthreads-debug", + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node_debug, + pthreads=True, + ), + # wasm64-emscripten (currently not working) + BuildProfile( + "wasm64-emscripten-node-debug", + host=Host.wasm64_emscripten, + target=EmscriptenTarget.node_debug, + # MEMORY64 is not compatible with dynamic linking + dynamic_linking=False, + pthreads=False, + ), + # wasm32-wasi + BuildProfile( + "wasi", + host=Host.wasm32_wasi, + # skip sysconfig test_srcdir + testopts="-i '*.test_srcdir' -j2", + ), + # no SDK available yet + # BuildProfile( + # "wasm64-wasi", + # host=Host.wasm64_wasi, + # ), +] + +PROFILES = {p.name: p for p in _profiles} + +parser = argparse.ArgumentParser( + "wasm_build.py", + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, +) +parser.add_argument( + "--clean", "-c", help="Clean build directories first", action="store_true" +) + +platforms = list(PROFILES) + ["cleanall"] +parser.add_argument( + "platform", + metavar="PLATFORM", + help=f"Build platform: {', '.join(platforms)}", + choices=platforms, +) + +ops = ["compile", "pythoninfo", "test", "repl", "clean", "cleanall"] +parser.add_argument( + "op", + metavar="OP", + help=f"operation: {', '.join(ops)}", + choices=ops, + default="compile", + nargs="?", +) + + +def main(): + args = parser.parse_args() + if args.platform == "cleanall": + for builder in PROFILES.values(): + builder.clean(all=True) + parser.exit(0) + + builder = PROFILES[args.platform] + try: + builder.host.platform.check() + except ConditionError as e: + parser.error(str(e)) + + # hack for WASI + if builder.host.is_wasi and not SETUP_LOCAL.exists(): + SETUP_LOCAL.touch() + + if args.op in {"compile", "pythoninfo", "repl", "test"}: + # all targets need a build Python + if builder is not BUILD: + if args.clean: + BUILD.clean(all=False) + BUILD.run_build() + elif not BUILD.python_cmd.exists(): + BUILD.run_build() + + if args.clean: + builder.clean(all=False) + + if args.op == "compile": + builder.run_build(force_configure=True) + else: + if not builder.makefile.exists(): + builder.run_configure() + if args.op == "pythoninfo": + builder.run_pythoninfo() + elif args.op == "repl": + builder.run_py() + elif args.op == "test": + builder.run_test() + elif args.op == "clean": + builder.clean(all=False) + elif args.op == "cleanall": + builder.clean(all=True) + else: + raise ValueError(args.op) + + print(builder.builddir) + parser.exit(0) + + +if __name__ == "__main__": + main() diff --git a/configure b/configure index 3f25d43dde6f..82b55a3745d5 100755 --- a/configure +++ b/configure @@ -906,6 +906,7 @@ AR LINK_PYTHON_OBJS LINK_PYTHON_DEPS LIBRARY_DEPS +NODE HOSTRUNNER STATIC_LIBPYTHON GNULD @@ -4079,6 +4080,16 @@ if test -z "$CFLAGS"; then CFLAGS= fi +case $host in #( + wasm64-*-emscripten) : + + as_fn_append CFLAGS " -sMEMORY64=1" + as_fn_append LDFLAGS " -sMEMORY64=1" + ;; #( + *) : + ;; +esac + if test "$ac_sys_system" = "Darwin" then # Extract the first word of "xcrun", so it can be a program name with args. @@ -6220,7 +6231,7 @@ cat > conftest.c <<EOF # error unknown wasm32 platform # endif #elif defined(__wasm64__) -# if defined(__EMSCRIPTEN) +# if defined(__EMSCRIPTEN__) wasm64-emscripten # elif defined(__wasi__) wasm64-wasi @@ -6840,19 +6851,162 @@ if test "$cross_compiling" = yes; then fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking HOSTRUNNER" >&5 -$as_echo_n "checking HOSTRUNNER... " >&6; } if test -z "$HOSTRUNNER" then case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/node*) : + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}node", so it can be a program name with args. +set dummy ${ac_tool_prefix}node; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_NODE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $NODE in + [\\/]* | ?:[\\/]*) + ac_cv_path_NODE="$NODE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_NODE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +NODE=$ac_cv_path_NODE +if test -n "$NODE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NODE" >&5 +$as_echo "$NODE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_NODE"; then + ac_pt_NODE=$NODE + # Extract the first word of "node", so it can be a program name with args. +set dummy node; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_NODE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_NODE in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_NODE="$ac_pt_NODE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_NODE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_NODE=$ac_cv_path_ac_pt_NODE +if test -n "$ac_pt_NODE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_NODE" >&5 +$as_echo "$ac_pt_NODE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_NODE" = x; then + NODE="node" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NODE=$ac_pt_NODE + fi +else + NODE="$ac_cv_path_NODE" +fi + + HOSTRUNNER="$NODE" # bigint for ctypes c_longlong, c_longdouble - HOSTRUNNER="node --experimental-wasm-bigint" + # no longer available in Node 16 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bigint" >&5 +$as_echo_n "checking for node --experimental-wasm-bigint... " >&6; } +if ${ac_cv_tool_node_wasm_bigint+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if $NODE -v --experimental-wasm-bigint > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bigint=yes + else + ac_cv_tool_node_wasm_bigint=no + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bigint" >&5 +$as_echo "$ac_cv_tool_node_wasm_bigint" >&6; } + if test "x$ac_cv_tool_node_wasm_bigint" = xyes; then : + + as_fn_append HOSTRUNNER " --experimental-wasm-bigint" + +fi + if test "x$enable_wasm_pthreads" = xyes; then : - HOSTRUNNER="$HOSTRUNNER --experimental-wasm-threads --experimental-wasm-bulk-memory" + as_fn_append HOSTRUNNER " --experimental-wasm-threads" + # no longer available in Node 16 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bulk-memory" >&5 +$as_echo_n "checking for node --experimental-wasm-bulk-memory... " >&6; } +if ${ac_cv_tool_node_wasm_bulk_memory+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if $NODE -v --experimental-wasm-bulk-memory > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bulk_memory=yes + else + ac_cv_tool_node_wasm_bulk_memory=no + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bulk_memory" >&5 +$as_echo "$ac_cv_tool_node_wasm_bulk_memory" >&6; } + if test "x$ac_cv_tool_node_wasm_bulk_memory" = xyes; then : + + as_fn_append HOSTRUNNER " --experimental-wasm-bulk-memory" +fi + +fi + + if test "x$host_cpu" = xwasm64; then : + as_fn_append HOSTRUNNER " --experimental-wasm-memory64" fi ;; #( WASI/*) : @@ -6863,6 +7017,8 @@ fi esac fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking HOSTRUNNER" >&5 +$as_echo_n "checking HOSTRUNNER... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOSTRUNNER" >&5 $as_echo "$HOSTRUNNER" >&6; } diff --git a/configure.ac b/configure.ac index 8decd9ebae84..85d9e8011835 100644 --- a/configure.ac +++ b/configure.ac @@ -753,6 +753,16 @@ if test -z "$CFLAGS"; then CFLAGS= fi +dnl Emscripten SDK and WASI SDK default to wasm32. +dnl On Emscripten use MEMORY64 setting to build target wasm64-emscripten. +dnl for wasm64. +AS_CASE([$host], + [wasm64-*-emscripten], [ + AS_VAR_APPEND([CFLAGS], [" -sMEMORY64=1"]) + AS_VAR_APPEND([LDFLAGS], [" -sMEMORY64=1"]) + ], +) + if test "$ac_sys_system" = "Darwin" then dnl look for SDKROOT @@ -1048,7 +1058,7 @@ cat > conftest.c <<EOF # error unknown wasm32 platform # endif #elif defined(__wasm64__) -# if defined(__EMSCRIPTEN) +# if defined(__EMSCRIPTEN__) wasm64-emscripten # elif defined(__wasi__) wasm64-wasi @@ -1515,16 +1525,41 @@ if test "$cross_compiling" = yes; then fi AC_ARG_VAR([HOSTRUNNER], [Program to run CPython for the host platform]) -AC_MSG_CHECKING([HOSTRUNNER]) if test -z "$HOSTRUNNER" then AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], [Emscripten/node*], [ + AC_PATH_TOOL([NODE], [node], [node]) + HOSTRUNNER="$NODE" # bigint for ctypes c_longlong, c_longdouble - HOSTRUNNER="node --experimental-wasm-bigint" + # no longer available in Node 16 + AC_CACHE_CHECK([for node --experimental-wasm-bigint], [ac_cv_tool_node_wasm_bigint], [ + if $NODE -v --experimental-wasm-bigint > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bigint=yes + else + ac_cv_tool_node_wasm_bigint=no + fi + ]) + AS_VAR_IF([ac_cv_tool_node_wasm_bigint], [yes], [ + AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-bigint"]) + ]) + AS_VAR_IF([enable_wasm_pthreads], [yes], [ - HOSTRUNNER="$HOSTRUNNER --experimental-wasm-threads --experimental-wasm-bulk-memory" + AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-threads"]) + # no longer available in Node 16 + AC_CACHE_CHECK([for node --experimental-wasm-bulk-memory], [ac_cv_tool_node_wasm_bulk_memory], [ + if $NODE -v --experimental-wasm-bulk-memory > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bulk_memory=yes + else + ac_cv_tool_node_wasm_bulk_memory=no + fi + ]) + AS_VAR_IF([ac_cv_tool_node_wasm_bulk_memory], [yes], [ + AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-bulk-memory"]) + ]) ]) + + AS_VAR_IF([host_cpu], [wasm64], [AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-memory64"])]) ], dnl TODO: support other WASI runtimes dnl wasmtime starts the proces with "/" as CWD. For OOT builds add the @@ -1534,6 +1569,7 @@ then ) fi AC_SUBST([HOSTRUNNER]) +AC_MSG_CHECKING([HOSTRUNNER]) AC_MSG_RESULT([$HOSTRUNNER]) if test -n "$HOSTRUNNER"; then From webhook-mailer at python.org Sun Aug 14 10:43:09 2022 From: webhook-mailer at python.org (pablogsal) Date: Sun, 14 Aug 2022 14:43:09 -0000 Subject: [Python-checkins] bpo-40222: Mark exception table function in the dis module as private (#95961) Message-ID: <mailman.667.1660488190.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c26500224fe80559d1aa4973f22453c9ce2130ab commit: c26500224fe80559d1aa4973f22453c9ce2130ab branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-14T15:42:31+01:00 summary: bpo-40222: Mark exception table function in the dis module as private (#95961) files: M Lib/dis.py diff --git a/Lib/dis.py b/Lib/dis.py index d63f35a42b2..a045d18241b 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -394,7 +394,7 @@ def _get_name_info(name_index, get_name, **extrainfo): else: return UNKNOWN, '' -def parse_varint(iterator): +def _parse_varint(iterator): b = next(iterator) val = b & 63 while b&64: @@ -403,16 +403,16 @@ def parse_varint(iterator): val |= b&63 return val -def parse_exception_table(code): +def _parse_exception_table(code): iterator = iter(code.co_exceptiontable) entries = [] try: while True: - start = parse_varint(iterator)*2 - length = parse_varint(iterator)*2 + start = _parse_varint(iterator)*2 + length = _parse_varint(iterator)*2 end = start + length - target = parse_varint(iterator)*2 - dl = parse_varint(iterator) + target = _parse_varint(iterator)*2 + dl = _parse_varint(iterator) depth = dl >> 1 lasti = bool(dl&1) entries.append(_ExceptionTableEntry(start, end, target, depth, lasti)) @@ -527,7 +527,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False): """Disassemble a code object.""" linestarts = dict(findlinestarts(co)) - exception_entries = parse_exception_table(co) + exception_entries = _parse_exception_table(co) _disassemble_bytes(_get_code_array(co, adaptive), lasti, co._varname_from_oparg, co.co_names, co.co_consts, linestarts, file=file, @@ -717,7 +717,7 @@ def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False self._linestarts = dict(findlinestarts(co)) self._original_object = x self.current_offset = current_offset - self.exception_entries = parse_exception_table(co) + self.exception_entries = _parse_exception_table(co) self.show_caches = show_caches self.adaptive = adaptive From webhook-mailer at python.org Sun Aug 14 11:08:12 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 14 Aug 2022 15:08:12 -0000 Subject: [Python-checkins] bpo-40222: Mark exception table function in the dis module as private (GH-95961) Message-ID: <mailman.668.1660489694.3313.python-checkins@python.org> https://github.com/python/cpython/commit/38882d97b35c667ac3d937d82b3d024698e4396a commit: 38882d97b35c667ac3d937d82b3d024698e4396a branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-14T08:08:04-07:00 summary: bpo-40222: Mark exception table function in the dis module as private (GH-95961) (cherry picked from commit c26500224fe80559d1aa4973f22453c9ce2130ab) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: M Lib/dis.py diff --git a/Lib/dis.py b/Lib/dis.py index 5ab830af54c6..5bf52c3e6d3a 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -392,7 +392,7 @@ def _get_name_info(name_index, get_name, **extrainfo): else: return UNKNOWN, '' -def parse_varint(iterator): +def _parse_varint(iterator): b = next(iterator) val = b & 63 while b&64: @@ -401,16 +401,16 @@ def parse_varint(iterator): val |= b&63 return val -def parse_exception_table(code): +def _parse_exception_table(code): iterator = iter(code.co_exceptiontable) entries = [] try: while True: - start = parse_varint(iterator)*2 - length = parse_varint(iterator)*2 + start = _parse_varint(iterator)*2 + length = _parse_varint(iterator)*2 end = start + length - target = parse_varint(iterator)*2 - dl = parse_varint(iterator) + target = _parse_varint(iterator)*2 + dl = _parse_varint(iterator) depth = dl >> 1 lasti = bool(dl&1) entries.append(_ExceptionTableEntry(start, end, target, depth, lasti)) @@ -519,7 +519,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, def disassemble(co, lasti=-1, *, file=None, show_caches=False, adaptive=False): """Disassemble a code object.""" linestarts = dict(findlinestarts(co)) - exception_entries = parse_exception_table(co) + exception_entries = _parse_exception_table(co) _disassemble_bytes(_get_code_array(co, adaptive), lasti, co._varname_from_oparg, co.co_names, co.co_consts, linestarts, file=file, @@ -706,7 +706,7 @@ def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False self._linestarts = dict(findlinestarts(co)) self._original_object = x self.current_offset = current_offset - self.exception_entries = parse_exception_table(co) + self.exception_entries = _parse_exception_table(co) self.show_caches = show_caches self.adaptive = adaptive From webhook-mailer at python.org Sun Aug 14 11:13:47 2022 From: webhook-mailer at python.org (corona10) Date: Sun, 14 Aug 2022 15:13:47 -0000 Subject: [Python-checkins] GH-95977: Speed up calling pure python descriptor __get__ with vectorcall (gh-95978) Message-ID: <mailman.669.1660490027.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f2afdf33523162d5911de3263b4a9785d7c49a20 commit: f2afdf33523162d5911de3263b4a9785d7c49a20 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-15T00:13:42+09:00 summary: GH-95977: Speed up calling pure python descriptor __get__ with vectorcall (gh-95978) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-14-10-04-44.gh-issue-95977.gCTZb9.rst M Objects/typeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-14-10-04-44.gh-issue-95977.gCTZb9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-14-10-04-44.gh-issue-95977.gCTZb9.rst new file mode 100644 index 000000000000..b265c770233a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-14-10-04-44.gh-issue-95977.gCTZb9.rst @@ -0,0 +1 @@ +Optimized calling :meth:`~object.__get__` with vectorcall. Patch by Kumar Aditya. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index da02e86f94ed..27b12a00d77f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -8242,7 +8242,8 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) obj = Py_None; if (type == NULL) type = Py_None; - return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL); + PyObject *stack[3] = {self, obj, type}; + return PyObject_Vectorcall(get, stack, 3, NULL); } static int From webhook-mailer at python.org Sun Aug 14 11:53:43 2022 From: webhook-mailer at python.org (gvanrossum) Date: Sun, 14 Aug 2022 15:53:43 -0000 Subject: [Python-checkins] Clarify asyncio.Runner docs re: loop_factory (#95979) Message-ID: <mailman.670.1660492424.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e8259e047c42976427b08f100b9d8ba52db7ee69 commit: e8259e047c42976427b08f100b9d8ba52db7ee69 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-14T08:53:34-07:00 summary: Clarify asyncio.Runner docs re: loop_factory (#95979) files: M Doc/library/asyncio-runner.rst diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index d0df1db892f..4abe7b6e087 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -75,7 +75,9 @@ Runner context manager :ref:`asyncio-debug-mode` settings. *loop_factory* could be used for overriding the loop creation. - :func:`asyncio.new_event_loop` is used if ``None``. + It is the responsibility of the *loop_factory* to set the created loop as the + current one. By default :func:`asyncio.new_event_loop` is used and set as + current event loop with :func:`asyncio.set_event_loop` if *loop_factory* is ``None``. Basically, :func:`asyncio.run()` example can be rewritten with the runner usage:: From webhook-mailer at python.org Sun Aug 14 12:02:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 14 Aug 2022 16:02:13 -0000 Subject: [Python-checkins] Clarify asyncio.Runner docs re: loop_factory (GH-95979) Message-ID: <mailman.671.1660492934.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3ce1d0093e61605209ed7ce93b541eb42aea6ffc commit: 3ce1d0093e61605209ed7ce93b541eb42aea6ffc branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-14T09:02:07-07:00 summary: Clarify asyncio.Runner docs re: loop_factory (GH-95979) (cherry picked from commit e8259e047c42976427b08f100b9d8ba52db7ee69) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: M Doc/library/asyncio-runner.rst diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index d0df1db892f..4abe7b6e087 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -75,7 +75,9 @@ Runner context manager :ref:`asyncio-debug-mode` settings. *loop_factory* could be used for overriding the loop creation. - :func:`asyncio.new_event_loop` is used if ``None``. + It is the responsibility of the *loop_factory* to set the created loop as the + current one. By default :func:`asyncio.new_event_loop` is used and set as + current event loop with :func:`asyncio.set_event_loop` if *loop_factory* is ``None``. Basically, :func:`asyncio.run()` example can be rewritten with the runner usage:: From webhook-mailer at python.org Mon Aug 15 01:41:16 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 15 Aug 2022 05:41:16 -0000 Subject: [Python-checkins] gh-95853: Address wasm build and test issues (GH-95985) Message-ID: <mailman.672.1660542076.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4a7f5a55dc88c14cef880ae38a96018514ca9d83 commit: 4a7f5a55dc88c14cef880ae38a96018514ca9d83 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-15T07:41:10+02:00 summary: gh-95853: Address wasm build and test issues (GH-95985) files: M Lib/test/test_decimal.py M Modules/pyexpat.c M Tools/wasm/wasm_build.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index f7a47c86a3fe..7c5964e3d553 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -37,7 +37,7 @@ requires_legacy_unicode_capi, check_sanitizer) from test.support import (TestFailed, run_with_locale, cpython_only, - darwin_malloc_err_warning) + darwin_malloc_err_warning, is_emscripten) from test.support.import_helper import import_fresh_module from test.support import threading_helper from test.support import warnings_helper @@ -5605,6 +5605,7 @@ def __abs__(self): # Issue 41540: @unittest.skipIf(sys.platform.startswith("aix"), "AIX: default ulimit: test is flaky because of extreme over-allocation") + @unittest.skipIf(is_emscripten, "Test is unstable on Emscripten") @unittest.skipIf(check_sanitizer(address=True, memory=True), "ASAN/MSAN sanitizer defaults to crashing " "instead of returning NULL for malloc failure.") diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 678347331ef4..165cb0effae2 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -775,7 +775,7 @@ readinst(char *buf, int buf_size, PyObject *meth) Py_ssize_t len; const char *ptr; - str = PyObject_CallFunction(meth, "n", buf_size); + str = PyObject_CallFunction(meth, "i", buf_size); if (str == NULL) goto error; diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py index e7a1f4a60071..df90f01a27b6 100755 --- a/Tools/wasm/wasm_build.py +++ b/Tools/wasm/wasm_build.py @@ -191,7 +191,11 @@ def _check_emscripten(): config_site=WASMTOOLS / "config.site-wasm32-emscripten", configure_wrapper=EMSCRIPTEN_ROOT / "emconfigure", make_wrapper=EMSCRIPTEN_ROOT / "emmake", - environ={"EM_COMPILER_WRAPPER": "ccache"} if HAS_CCACHE else {}, + environ={ + # workaround for https://github.com/emscripten-core/emscripten/issues/17635 + "TZ": "UTC", + "EM_COMPILER_WRAPPER": "ccache" if HAS_CCACHE else None, + }, check=_check_emscripten, ) @@ -352,12 +356,15 @@ def getenv(self) -> dict: env.setdefault("MAKEFLAGS", f"-j{os.cpu_count()}") platenv = self.host.platform.getenv(self) for key, value in platenv.items(): - if isinstance(value, str): - value = value.format( + if value is None: + env.pop(key, None) + elif isinstance(value, str): + env[key] = value.format( relbuilddir=self.builddir.relative_to(SRCDIR), srcdir=SRCDIR, ) - env[key] = value + else: + env[key] = value return env def _run_cmd(self, cmd: Iterable[str], args: Iterable[str]): From webhook-mailer at python.org Mon Aug 15 07:29:48 2022 From: webhook-mailer at python.org (markshannon) Date: Mon, 15 Aug 2022 11:29:48 -0000 Subject: [Python-checkins] GH-95707: Fix uses of `Py_TPFLAGS_MANAGED_DICT` (GH-95854) Message-ID: <mailman.673.1660562989.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3ef3c6306def489ba9115f0a8a57ab1e99795a5c commit: 3ef3c6306def489ba9115f0a8a57ab1e99795a5c branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-15T12:29:27+01:00 summary: GH-95707: Fix uses of `Py_TPFLAGS_MANAGED_DICT` (GH-95854) * Make sure that tp_dictoffset is correct with Py_TPFLAGS_MANAGED_DICT is set. * Avoid traversing managed dict twice when subclassing class with Py_TPFLAGS_MANAGED_DICT set. files: A Misc/NEWS.d/next/C API/2022-08-03-13-01-57.gh-issue-92678.DLwONN.rst M Lib/test/test_capi.py M Lib/test/test_sys.py M Modules/_testcapi/heaptype.c M Objects/object.c M Objects/typeobject.c M Tools/gdb/libpython.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 1ff14e7bc56f..e4d20355d430 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -539,6 +539,30 @@ def test_heaptype_with_dict(self): inst = _testcapi.HeapCTypeWithDict() self.assertEqual({}, inst.__dict__) + def test_heaptype_with_managed_dict(self): + inst = _testcapi.HeapCTypeWithManagedDict() + inst.foo = 42 + self.assertEqual(inst.foo, 42) + self.assertEqual(inst.__dict__, {"foo": 42}) + + inst = _testcapi.HeapCTypeWithManagedDict() + self.assertEqual({}, inst.__dict__) + + a = _testcapi.HeapCTypeWithManagedDict() + b = _testcapi.HeapCTypeWithManagedDict() + a.b = b + b.a = a + del a, b + + def test_sublclassing_managed_dict(self): + + class C(_testcapi.HeapCTypeWithManagedDict): + pass + + i = C() + i.spam = i + del i + def test_heaptype_with_negative_dict(self): inst = _testcapi.HeapCTypeWithNegativeDict() inst.foo = 42 diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 05fbcc19b6b7..78da09d6abc0 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1287,7 +1287,7 @@ class OverflowSizeof(int): def __sizeof__(self): return int(self) self.assertEqual(sys.getsizeof(OverflowSizeof(sys.maxsize)), - sys.maxsize + self.gc_headsize) + sys.maxsize + self.gc_headsize*2) with self.assertRaises(OverflowError): sys.getsizeof(OverflowSizeof(sys.maxsize + 1)) with self.assertRaises(ValueError): diff --git a/Misc/NEWS.d/next/C API/2022-08-03-13-01-57.gh-issue-92678.DLwONN.rst b/Misc/NEWS.d/next/C API/2022-08-03-13-01-57.gh-issue-92678.DLwONN.rst new file mode 100644 index 000000000000..a3a209f5e413 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-08-03-13-01-57.gh-issue-92678.DLwONN.rst @@ -0,0 +1,2 @@ +Support C extensions using managed dictionaries by setting the +``Py_TPFLAGS_MANAGED_DICT`` flag. diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index 514541ce348d..de990bac51d6 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -761,6 +761,45 @@ static PyType_Spec HeapCTypeWithDict2_spec = { HeapCTypeWithDict_slots }; +static int +heapmanaged_traverse(HeapCTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return _PyObject_VisitManagedDict((PyObject *)self, visit, arg); +} + +static void +heapmanaged_clear(HeapCTypeObject *self) +{ + _PyObject_ClearManagedDict((PyObject *)self); +} + +static void +heapmanaged_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_ClearManagedDict((PyObject *)self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithManagedDict_slots[] = { + {Py_tp_traverse, heapmanaged_traverse}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_clear, heapmanaged_clear}, + {Py_tp_dealloc, heapmanaged_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithManagedDict_spec = { + "_testcapi.HeapCTypeWithManagedDict", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT, + HeapCTypeWithManagedDict_slots +}; + static struct PyMemberDef heapctypewithnegativedict_members[] = { {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, @@ -963,6 +1002,12 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { } PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); + PyObject *HeapCTypeWithManagedDict = PyType_FromSpec(&HeapCTypeWithManagedDict_spec); + if (HeapCTypeWithManagedDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithManagedDict", HeapCTypeWithManagedDict); + PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); if (HeapCTypeWithWeakref == NULL) { return -1; diff --git a/Objects/object.c b/Objects/object.c index a90c6faf99db..9bbe0eef308f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1064,6 +1064,7 @@ _PyObject_ComputedDictPointer(PyObject *obj) if (dictoffset == 0) return NULL; if (dictoffset < 0) { + assert(dictoffset != -1); Py_ssize_t tsize = Py_SIZE(obj); if (tsize < 0) { tsize = -tsize; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 27b12a00d77f..67dfc6f8483d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1312,16 +1312,21 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) assert(base); } - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - int err = _PyObject_VisitManagedDict(self, visit, arg); - if (err) { - return err; + if (type->tp_dictoffset != base->tp_dictoffset) { + assert(base->tp_dictoffset == 0); + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + assert(type->tp_dictoffset == -1); + int err = _PyObject_VisitManagedDict(self, visit, arg); + if (err) { + return err; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); + if (dictptr && *dictptr) { + Py_VISIT(*dictptr); + } } - } - else if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_ComputedDictPointer(self); - if (dictptr && *dictptr) - Py_VISIT(*dictptr); } if (type->tp_flags & Py_TPFLAGS_HEAPTYPE @@ -1380,7 +1385,9 @@ subtype_clear(PyObject *self) /* Clear the instance dict (if any), to break cycles involving only __dict__ slots (as in the case 'self.__dict__ is self'). */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - _PyObject_ClearManagedDict(self); + if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + _PyObject_ClearManagedDict(self); + } } else if (type->tp_dictoffset != base->tp_dictoffset) { PyObject **dictptr = _PyObject_ComputedDictPointer(self); @@ -3085,20 +3092,15 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) } } - if (ctx->add_dict && ctx->base->tp_itemsize) { - type->tp_dictoffset = -(long)sizeof(PyObject *); - slotoffset += sizeof(PyObject *); - } - if (ctx->add_weak) { assert(!ctx->base->tp_itemsize); type->tp_weaklistoffset = slotoffset; slotoffset += sizeof(PyObject *); } - if (ctx->add_dict && ctx->base->tp_itemsize == 0) { + if (ctx->add_dict) { assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); type->tp_flags |= Py_TPFLAGS_MANAGED_DICT; - type->tp_dictoffset = -slotoffset - sizeof(PyObject *)*3; + type->tp_dictoffset = -1; } type->tp_basicsize = slotoffset; @@ -6161,6 +6163,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) COPYVAL(tp_itemsize); COPYVAL(tp_weaklistoffset); COPYVAL(tp_dictoffset); + #undef COPYVAL /* Setup fast subclass flags */ @@ -6567,6 +6570,21 @@ type_ready_fill_dict(PyTypeObject *type) return 0; } +static int +type_ready_dict_offset(PyTypeObject *type) +{ + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set", + type->tp_name); + return -1; + } + type->tp_dictoffset = -1; + } + return 0; +} static int type_ready_mro(PyTypeObject *type) @@ -6775,6 +6793,21 @@ type_ready_post_checks(PyTypeObject *type) type->tp_name); return -1; } + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset != -1) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set to incompatible value", + type->tp_name); + return -1; + } + } + else if (type->tp_dictoffset < sizeof(PyObject)) { + if (type->tp_dictoffset + type->tp_basicsize <= 0) { + PyErr_Format(PyExc_SystemError, + "type %s has a tp_dictoffset that is too small"); + } + } return 0; } @@ -6814,6 +6847,9 @@ type_ready(PyTypeObject *type) if (type_ready_inherit(type) < 0) { return -1; } + if (type_ready_dict_offset(type) < 0) { + return -1; + } if (type_ready_set_hash(type) < 0) { return -1; } diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index d03c63791258..899cb6c7dea0 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -478,13 +478,17 @@ def get_attr_dict(self): dictoffset = int_from_int(typeobj.field('tp_dictoffset')) if dictoffset != 0: if dictoffset < 0: - type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer() - tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size']) - if tsize < 0: - tsize = -tsize - size = _PyObject_VAR_SIZE(typeobj, tsize) - dictoffset += size - assert dictoffset % _sizeof_void_p() == 0 + if int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT: + assert dictoffset == -1 + dictoffset = -3 * _sizeof_void_p() + else: + type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer() + tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size']) + if tsize < 0: + tsize = -tsize + size = _PyObject_VAR_SIZE(typeobj, tsize) + dictoffset += size + assert dictoffset % _sizeof_void_p() == 0 dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer() From webhook-mailer at python.org Mon Aug 15 10:06:37 2022 From: webhook-mailer at python.org (markshannon) Date: Mon, 15 Aug 2022 14:06:37 -0000 Subject: [Python-checkins] gh-95707: Fix function signature (GH-95995) Message-ID: <mailman.674.1660572398.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8621e6d43a25651b39a4286c0ea62f7bf9c436ea commit: 8621e6d43a25651b39a4286c0ea62f7bf9c436ea branch: main author: Christian Heimes <christian at python.org> committer: markshannon <mark at hotpy.org> date: 2022-08-15T15:06:28+01:00 summary: gh-95707: Fix function signature (GH-95995) files: M Modules/_testcapi/heaptype.c diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index de990bac51d6..eca95450df98 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -768,10 +768,11 @@ heapmanaged_traverse(HeapCTypeObject *self, visitproc visit, void *arg) return _PyObject_VisitManagedDict((PyObject *)self, visit, arg); } -static void +static int heapmanaged_clear(HeapCTypeObject *self) { _PyObject_ClearManagedDict((PyObject *)self); + return 0; } static void From webhook-mailer at python.org Mon Aug 15 10:48:29 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 15 Aug 2022 14:48:29 -0000 Subject: [Python-checkins] gh-95231: Disable md5 & crypt modules if FIPS is enabled (GH-94742) Message-ID: <mailman.675.1660574910.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2fa03b1b0708d5d74630c351ec9abd2aac7550da commit: 2fa03b1b0708d5d74630c351ec9abd2aac7550da branch: main author: Shreenidhi Shedi <53473811+sshedi at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-15T07:48:07-07:00 summary: gh-95231: Disable md5 & crypt modules if FIPS is enabled (GH-94742) If kernel fips is enabled, we get permission error upon doing `import crypt`. So, if kernel fips is enabled, disable the unallowed hashing methods. Python 3.9.1 (default, May 10 2022, 11:36:26) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import crypt Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.9/crypt.py", line 117, in <module> _add_method('MD5', '1', 8, 34) File "/usr/lib/python3.9/crypt.py", line 94, in _add_method result = crypt('', salt) File "/usr/lib/python3.9/crypt.py", line 82, in crypt return _crypt.crypt(word, salt) PermissionError: [Errno 1] Operation not permitted Signed-off-by: Shreenidhi Shedi <sshedi at vmware.com> files: A Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst M Lib/crypt.py diff --git a/Lib/crypt.py b/Lib/crypt.py index 46c3de8474bf..de4a14a38847 100644 --- a/Lib/crypt.py +++ b/Lib/crypt.py @@ -98,7 +98,7 @@ def _add_method(name, *args, rounds=None): result = crypt('', salt) except OSError as e: # Not all libc libraries support all encryption methods. - if e.errno == errno.EINVAL: + if e.errno in {errno.EINVAL, errno.EPERM, errno.ENOSYS}: return False raise if result and len(result) == method.total_size: diff --git a/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst b/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst new file mode 100644 index 000000000000..aa53f2938bc9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst @@ -0,0 +1,3 @@ +Fail gracefully if :data:`~errno.EPERM` or :data:`~errno.ENOSYS` is raised when loading +:mod:`crypt` methods. This may happen when trying to load ``MD5`` on a Linux kernel +with :abbr:`FIPS (Federal Information Processing Standard)` enabled. From webhook-mailer at python.org Mon Aug 15 11:38:07 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 15 Aug 2022 15:38:07 -0000 Subject: [Python-checkins] gh-95231: Disable md5 & crypt modules if FIPS is enabled (GH-94742) Message-ID: <mailman.676.1660577889.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3fa97b8589c551e70ec935e7f39d56c3c5d5ed7e commit: 3fa97b8589c551e70ec935e7f39d56c3c5d5ed7e branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-15T08:37:51-07:00 summary: gh-95231: Disable md5 & crypt modules if FIPS is enabled (GH-94742) If kernel fips is enabled, we get permission error upon doing `import crypt`. So, if kernel fips is enabled, disable the unallowed hashing methods. Python 3.9.1 (default, May 10 2022, 11:36:26) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import crypt Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.9/crypt.py", line 117, in <module> _add_method('MD5', '1', 8, 34) File "/usr/lib/python3.9/crypt.py", line 94, in _add_method result = crypt('', salt) File "/usr/lib/python3.9/crypt.py", line 82, in crypt return _crypt.crypt(word, salt) PermissionError: [Errno 1] Operation not permitted Signed-off-by: Shreenidhi Shedi <sshedi at vmware.com> (cherry picked from commit 2fa03b1b0708d5d74630c351ec9abd2aac7550da) Co-authored-by: Shreenidhi Shedi <53473811+sshedi at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst M Lib/crypt.py diff --git a/Lib/crypt.py b/Lib/crypt.py index 46c3de8474bf..de4a14a38847 100644 --- a/Lib/crypt.py +++ b/Lib/crypt.py @@ -98,7 +98,7 @@ def _add_method(name, *args, rounds=None): result = crypt('', salt) except OSError as e: # Not all libc libraries support all encryption methods. - if e.errno == errno.EINVAL: + if e.errno in {errno.EINVAL, errno.EPERM, errno.ENOSYS}: return False raise if result and len(result) == method.total_size: diff --git a/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst b/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst new file mode 100644 index 000000000000..aa53f2938bc9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst @@ -0,0 +1,3 @@ +Fail gracefully if :data:`~errno.EPERM` or :data:`~errno.ENOSYS` is raised when loading +:mod:`crypt` methods. This may happen when trying to load ``MD5`` on a Linux kernel +with :abbr:`FIPS (Federal Information Processing Standard)` enabled. From webhook-mailer at python.org Mon Aug 15 13:03:08 2022 From: webhook-mailer at python.org (gvanrossum) Date: Mon, 15 Aug 2022 17:03:08 -0000 Subject: [Python-checkins] GH-95899: fix asyncio.Runner to call set_event_loop only once (#95900) Message-ID: <mailman.677.1660582990.3313.python-checkins@python.org> https://github.com/python/cpython/commit/914f6367a0d015986dafa7a9d542e24192753b6b commit: 914f6367a0d015986dafa7a9d542e24192753b6b branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-15T10:02:47-07:00 summary: GH-95899: fix asyncio.Runner to call set_event_loop only once (#95900) files: A Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst M Lib/asyncio/runners.py M Lib/test/test_asyncio/test_runners.py diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index a8b74d532fcd..840b133df83e 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -114,8 +114,6 @@ def run(self, coro, *, context=None): self._interrupt_count = 0 try: - if self._set_event_loop: - events.set_event_loop(self._loop) return self._loop.run_until_complete(task) except exceptions.CancelledError: if self._interrupt_count > 0: @@ -136,7 +134,11 @@ def _lazy_init(self): return if self._loop_factory is None: self._loop = events.new_event_loop() - self._set_event_loop = True + if not self._set_event_loop: + # Call set_event_loop only once to avoid calling + # attach_loop multiple times on child watchers + events.set_event_loop(self._loop) + self._set_event_loop = True else: self._loop = self._loop_factory() if self._debug is not None: diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index d61d073a3674..1308b7e2ba4f 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -455,6 +455,20 @@ async def coro(): ): runner.run(coro()) + def test_set_event_loop_called_once(self): + # See https://github.com/python/cpython/issues/95736 + async def coro(): + pass + + policy = asyncio.get_event_loop_policy() + policy.set_event_loop = mock.Mock() + runner = asyncio.Runner() + runner.run(coro()) + runner.run(coro()) + + self.assertEqual(1, policy.set_event_loop.call_count) + runner.close() + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst b/Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst new file mode 100644 index 000000000000..d2386cf3ae22 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.Runner` to call :func:`asyncio.set_event_loop` only once to avoid calling :meth:`~asyncio.AbstractChildWatcher.attach_loop` multiple times on child watchers. Patch by Kumar Aditya. From webhook-mailer at python.org Mon Aug 15 13:39:16 2022 From: webhook-mailer at python.org (brandtbucher) Date: Mon, 15 Aug 2022 17:39:16 -0000 Subject: [Python-checkins] GH-94808: Test __build_class__ inside non-dict __builtins__ (GH-95932) Message-ID: <mailman.678.1660585157.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3adb4d864bb18a51334c922a732e5e3602799ba1 commit: 3adb4d864bb18a51334c922a732e5e3602799ba1 branch: main author: Michael Droettboom <mdboom at gmail.com> committer: brandtbucher <brandtbucher at gmail.com> date: 2022-08-15T10:39:06-07:00 summary: GH-94808: Test __build_class__ inside non-dict __builtins__ (GH-95932) files: M Lib/test/test_builtin.py diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index d5eaf291a5c..6fa5ea67c8b 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -737,11 +737,6 @@ def test_exec_globals(self): self.assertRaises(TypeError, exec, code, {'__builtins__': 123}) - # no __build_class__ function - code = compile("class A: pass", "", "exec") - self.assertRaisesRegex(NameError, "__build_class__ not found", - exec, code, {'__builtins__': {}}) - class frozendict_error(Exception): pass @@ -758,6 +753,15 @@ def __setitem__(self, key, value): self.assertRaises(frozendict_error, exec, code, {'__builtins__': frozen_builtins}) + # no __build_class__ function + code = compile("class A: pass", "", "exec") + self.assertRaisesRegex(NameError, "__build_class__ not found", + exec, code, {'__builtins__': {}}) + # __build_class__ in a custom __builtins__ + exec(code, {'__builtins__': frozen_builtins}) + self.assertRaisesRegex(NameError, "__build_class__ not found", + exec, code, {'__builtins__': frozendict()}) + # read-only globals namespace = frozendict({}) code = compile("x=1", "test", "exec") From webhook-mailer at python.org Mon Aug 15 18:01:33 2022 From: webhook-mailer at python.org (gvanrossum) Date: Mon, 15 Aug 2022 22:01:33 -0000 Subject: [Python-checkins] GH-95899: fix asyncio.Runner to call set_event_loop only once (GH-95900) (#96003) Message-ID: <mailman.679.1660600894.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8bd7a0b5810529cd3ed378de42a74e9301856f12 commit: 8bd7a0b5810529cd3ed378de42a74e9301856f12 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-15T15:01:23-07:00 summary: GH-95899: fix asyncio.Runner to call set_event_loop only once (GH-95900) (#96003) (cherry picked from commit 914f6367a0d015986dafa7a9d542e24192753b6b) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst M Lib/asyncio/runners.py M Lib/test/test_asyncio/test_runners.py diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index a19a7f99af06..b3e0c44b7fb5 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -115,8 +115,6 @@ def run(self, coro, *, context=None): self._interrupt_count = 0 try: - if self._set_event_loop: - events.set_event_loop(self._loop) return self._loop.run_until_complete(task) except exceptions.CancelledError: if self._interrupt_count > 0: @@ -137,7 +135,11 @@ def _lazy_init(self): return if self._loop_factory is None: self._loop = events.new_event_loop() - self._set_event_loop = True + if not self._set_event_loop: + # Call set_event_loop only once to avoid calling + # attach_loop multiple times on child watchers + events.set_event_loop(self._loop) + self._set_event_loop = True else: self._loop = self._loop_factory() if self._debug is not None: diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 5e1db2357e75..4e3acb97c85d 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -456,6 +456,20 @@ async def coro(): ): runner.run(coro()) + def test_set_event_loop_called_once(self): + # See https://github.com/python/cpython/issues/95736 + async def coro(): + pass + + policy = asyncio.get_event_loop_policy() + policy.set_event_loop = mock.Mock() + runner = asyncio.Runner() + runner.run(coro()) + runner.run(coro()) + + self.assertEqual(1, policy.set_event_loop.call_count) + runner.close() + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst b/Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst new file mode 100644 index 000000000000..d2386cf3ae22 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-11-18-52-17.gh-issue-95899._Bi4uG.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.Runner` to call :func:`asyncio.set_event_loop` only once to avoid calling :meth:`~asyncio.AbstractChildWatcher.attach_loop` multiple times on child watchers. Patch by Kumar Aditya. From webhook-mailer at python.org Mon Aug 15 19:04:09 2022 From: webhook-mailer at python.org (terryjreedy) Date: Mon, 15 Aug 2022 23:04:09 -0000 Subject: [Python-checkins] gh-78143: IDLE - fix settings dialog page label. (#96009) Message-ID: <mailman.680.1660604650.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f6b811059ac945a283bb59bf37efac162c3bbab6 commit: f6b811059ac945a283bb59bf37efac162c3bbab6 branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: terryjreedy <tjreedy at udel.edu> date: 2022-08-15T19:03:56-04:00 summary: gh-78143: IDLE - fix settings dialog page label. (#96009) '/Tab' should have been removed from the font page label when the tab-spaces setting was moved to the Windows page. files: M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 57eaffeef396..8e478d743fb7 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -121,7 +121,7 @@ def create_widgets(self): self.winpage = WinPage(note) self.shedpage = ShedPage(note) - note.add(self.fontpage, text='Fonts/Tabs') + note.add(self.fontpage, text=' Fonts ') note.add(self.highpage, text='Highlights') note.add(self.keyspage, text=' Keys ') note.add(self.winpage, text=' Windows ') From webhook-mailer at python.org Mon Aug 15 19:25:28 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 15 Aug 2022 23:25:28 -0000 Subject: [Python-checkins] gh-78143: IDLE - fix settings dialog page label. (GH-96009) Message-ID: <mailman.681.1660605929.3313.python-checkins@python.org> https://github.com/python/cpython/commit/230b630a767a457c6e7e4d797548a172c64ae735 commit: 230b630a767a457c6e7e4d797548a172c64ae735 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-15T16:25:10-07:00 summary: gh-78143: IDLE - fix settings dialog page label. (GH-96009) '/Tab' should have been removed from the font page label when the tab-spaces setting was moved to the Windows page. (cherry picked from commit f6b811059ac945a283bb59bf37efac162c3bbab6) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 4c89c27e0c0d..09f455c2500f 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -121,7 +121,7 @@ def create_widgets(self): self.winpage = WinPage(note) self.shedpage = ShedPage(note) - note.add(self.fontpage, text='Fonts/Tabs') + note.add(self.fontpage, text=' Fonts ') note.add(self.highpage, text='Highlights') note.add(self.keyspage, text=' Keys ') note.add(self.winpage, text=' Windows ') From webhook-mailer at python.org Mon Aug 15 19:32:50 2022 From: webhook-mailer at python.org (1st1) Date: Mon, 15 Aug 2022 23:32:50 -0000 Subject: [Python-checkins] gh-95808: Add missing early returns in _asynciomodule.c (#95809) Message-ID: <mailman.682.1660606372.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b2afe482f21b826d53886a69ea2c99d0d940c59a commit: b2afe482f21b826d53886a69ea2c99d0d940c59a branch: main author: Yury Selivanov <yury at edgedb.com> committer: 1st1 <yury at edgedb.com> date: 2022-08-15T16:32:40-07:00 summary: gh-95808: Add missing early returns in _asynciomodule.c (#95809) files: M Modules/_asynciomodule.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index f94819cad24..9d2f83bf6c7 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -631,8 +631,6 @@ create_cancelled_error(FutureObj *fut) } else { exc = PyObject_CallOneArg(asyncio_CancelledError, msg); } - PyException_SetContext(exc, fut->fut_cancelled_exc); - Py_CLEAR(fut->fut_cancelled_exc); return exc; } @@ -640,6 +638,9 @@ static void future_set_cancelled_error(FutureObj *fut) { PyObject *exc = create_cancelled_error(fut); + if (exc == NULL) { + return; + } PyErr_SetObject(asyncio_CancelledError, exc); Py_DECREF(exc); } From webhook-mailer at python.org Mon Aug 15 19:33:23 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 15 Aug 2022 23:33:23 -0000 Subject: [Python-checkins] gh-78143: IDLE - fix settings dialog page label. (GH-96009) Message-ID: <mailman.683.1660606405.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d55a775ac2fe32f3ed7e4b25f76d9f4d77745a1d commit: d55a775ac2fe32f3ed7e4b25f76d9f4d77745a1d branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-15T16:33:16-07:00 summary: gh-78143: IDLE - fix settings dialog page label. (GH-96009) '/Tab' should have been removed from the font page label when the tab-spaces setting was moved to the Windows page. (cherry picked from commit f6b811059ac945a283bb59bf37efac162c3bbab6) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/idlelib/configdialog.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 57eaffeef396..8e478d743fb7 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -121,7 +121,7 @@ def create_widgets(self): self.winpage = WinPage(note) self.shedpage = ShedPage(note) - note.add(self.fontpage, text='Fonts/Tabs') + note.add(self.fontpage, text=' Fonts ') note.add(self.highpage, text='Highlights') note.add(self.keyspage, text=' Keys ') note.add(self.winpage, text=' Windows ') From webhook-mailer at python.org Tue Aug 16 04:38:37 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 16 Aug 2022 08:38:37 -0000 Subject: [Python-checkins] Change CODEOWNERS entries for iritkatriel (GH-96008) Message-ID: <mailman.684.1660639118.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bfc2028df075317fc9cc311169fc67677a93a42d commit: bfc2028df075317fc9cc311169fc67677a93a42d branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-16T09:38:32+01:00 summary: Change CODEOWNERS entries for iritkatriel (GH-96008) files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index df79aa6503e0..cacd925cf4e3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -18,7 +18,7 @@ Objects/codeobject.c @markshannon Objects/frameobject.c @markshannon Objects/call.c @markshannon Python/ceval.c @markshannon -Python/compile.c @markshannon +Python/compile.c @markshannon @iritkatriel Python/ast_opt.c @isidentical Lib/test/test_patma.py @brandtbucher Lib/test/test_peepholer.py @brandtbucher @@ -29,7 +29,6 @@ Lib/test/test_except*.py @iritkatriel Lib/test/test_traceback.py @iritkatriel Objects/exceptions.c @iritkatriel Python/traceback.c @iritkatriel -Python/pythonrun.c @iritkatriel # Hashing **/*hashlib* @tiran From webhook-mailer at python.org Tue Aug 16 05:52:47 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 16 Aug 2022 09:52:47 -0000 Subject: [Python-checkins] gh-95808: Add missing early returns in _asynciomodule.c (GH-95809) Message-ID: <mailman.685.1660643569.3313.python-checkins@python.org> https://github.com/python/cpython/commit/af3e491d2bb02988d9f8d24ac2ba6f0b22b2130a commit: af3e491d2bb02988d9f8d24ac2ba6f0b22b2130a branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-16T02:52:10-07:00 summary: gh-95808: Add missing early returns in _asynciomodule.c (GH-95809) (cherry picked from commit b2afe482f21b826d53886a69ea2c99d0d940c59a) Co-authored-by: Yury Selivanov <yury at edgedb.com> files: M Modules/_asynciomodule.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index cb7afecd8f2c..10679be2ef19 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -631,8 +631,6 @@ create_cancelled_error(FutureObj *fut) } else { exc = PyObject_CallOneArg(asyncio_CancelledError, msg); } - PyException_SetContext(exc, fut->fut_cancelled_exc); - Py_CLEAR(fut->fut_cancelled_exc); return exc; } @@ -640,6 +638,9 @@ static void future_set_cancelled_error(FutureObj *fut) { PyObject *exc = create_cancelled_error(fut); + if (exc == NULL) { + return; + } PyErr_SetObject(asyncio_CancelledError, exc); Py_DECREF(exc); } From webhook-mailer at python.org Tue Aug 16 07:44:38 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 16 Aug 2022 11:44:38 -0000 Subject: [Python-checkins] gh-95957: Add instructions for Tcl/Tk and OpenSSL on RHEL/CentOS 7 (#95964) Message-ID: <mailman.686.1660650279.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ab4d72954f3c3fe4bdf51dc6a9cf0ed38f210a68 commit: ab4d72954f3c3fe4bdf51dc6a9cf0ed38f210a68 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-16T13:44:02+02:00 summary: gh-95957: Add instructions for Tcl/Tk and OpenSSL on RHEL/CentOS 7 (#95964) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: A Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst A Misc/rhel7/README.md A Misc/rhel7/openssl.pc A Misc/rhel7/tcl.pc A Misc/rhel7/tk.pc M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index f1f023038abe..ef84339a0172 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1644,16 +1644,23 @@ Build Changes * Build dependencies, compiler flags, and linker flags for most stdlib extension modules are now detected by :program:`configure`. libffi, libnsl, - libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk libs, and uuid flags - are detected by ``pkg-config`` (when available). + libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk, and uuid flags + are detected by ``pkg-config`` (when available). :mod:`tkinter` now + requires ``pkg-config`` command to detect development settings for Tcl/Tk + headers and libraries. (Contributed by Christian Heimes and Erlend Egeberg Aasland in :issue:`45847`, :issue:`45747`, and :issue:`45763`.) .. note:: - Use the environment variables ``TCLTK_CFLAGS`` and ``TCLTK_LIBS`` to - manually specify the location of Tcl/Tk headers and libraries. - The :program:`configure` options ``--with-tcltk-includes`` and - ``--with-tcltk-libs`` have been removed. + Use the environment variables :envvar:`TCLTK_CFLAGS` and + :envvar:`TCLTK_LIBS` to manually specify the location of Tcl/Tk headers + and libraries. The :program:`configure` options ``--with-tcltk-includes`` + and ``--with-tcltk-libs`` have been removed. + + On RHEL 7 and CentOS 7 the development packages do not provide ``tcl.pc`` + and ``tk.pc``, use :envvar:`TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5"`. + The directory ``Misc/rhel7`` contains ``.pc`` files and instructions + how to build Python with RHEL 7's and CentOS 7's Tcl/Tk and OpenSSL. * CPython now has :pep:`11` tier 3 support for cross compiling to WebAssembly platform ``wasm32-unknown-emscripten`` (Python in the browser). The effort diff --git a/Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst b/Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst new file mode 100644 index 000000000000..c617bd42abd9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst @@ -0,0 +1,2 @@ +What's New 3.11 now has instructions for how to provide compiler and +linker flags for Tcl/Tk and OpenSSL on RHEL 7 and CentOS 7. diff --git a/Misc/rhel7/README.md b/Misc/rhel7/README.md new file mode 100644 index 000000000000..8642e7c678f2 --- /dev/null +++ b/Misc/rhel7/README.md @@ -0,0 +1,19 @@ +# pkg-config overrides for RHEL 7 and CentOS 7 + +RHEL 7 and CentOS 7 do not provide pkg-config `.pc` files for Tcl/Tk. The + OpenSSL 1.1.1 pkg-config file is named `openssl11.pc` and not picked up + by Python's `configure` script. + +To build Python with system Tcl/Tk libs and OpenSSL 1.1 package, first +install the developer packages and the `pkgconfig` package with `pkg-config` +command. + +```shell +sudo yum install pkgconfig 'tcl-devel >= 8.5.12' 'tk-devel >= 8.5.12' openssl11-devel +``` + +The run `configure` with `PKG_CONFIG_PATH` environment variable. + +```shell +PKG_CONFIG_PATH=Misc/rhel7 ./configure -C +``` diff --git a/Misc/rhel7/openssl.pc b/Misc/rhel7/openssl.pc new file mode 100644 index 000000000000..ffccd36cc30d --- /dev/null +++ b/Misc/rhel7/openssl.pc @@ -0,0 +1,3 @@ +Name: OpenSSL +Version: 1.1.1k +Requires: libssl11 libcrypto11 diff --git a/Misc/rhel7/tcl.pc b/Misc/rhel7/tcl.pc new file mode 100644 index 000000000000..922eb5126403 --- /dev/null +++ b/Misc/rhel7/tcl.pc @@ -0,0 +1,4 @@ +Name: Tool Command Language +Version: 8.5.12 +Libs: -ltcl8.5 -ltclstub8.5 +# Libs.private: -ldl -lz -lpthread -lm diff --git a/Misc/rhel7/tk.pc b/Misc/rhel7/tk.pc new file mode 100644 index 000000000000..67cebb27f791 --- /dev/null +++ b/Misc/rhel7/tk.pc @@ -0,0 +1,5 @@ +Name: The Tk Toolkit +Version: 8.5.12 +Requires: tcl >= 8.5.12 +Libs: -ltk8.5 -ltkstub8.5 +# Libs.private: -lXft -lfontconfig -lfreetype -lfontconfig -lX11 From webhook-mailer at python.org Tue Aug 16 08:47:38 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 16 Aug 2022 12:47:38 -0000 Subject: [Python-checkins] remove repetitive credit from what's new in 3.11 rst (GH-96024) Message-ID: <mailman.687.1660654059.3313.python-checkins@python.org> https://github.com/python/cpython/commit/829aab859266253320317caabdb0e17fa4e0f05e commit: 829aab859266253320317caabdb0e17fa4e0f05e branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-16T13:47:07+01:00 summary: remove repetitive credit from what's new in 3.11 rst (GH-96024) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index ef84339a017..3832fdfbe82 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -64,7 +64,6 @@ Summary -- Release highlights New syntax features: * :pep:`654`: Exception Groups and ``except*``. - (Contributed by Irit Katriel in :issue:`45292`.) New built-in features: From webhook-mailer at python.org Tue Aug 16 08:57:31 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 16 Aug 2022 12:57:31 -0000 Subject: [Python-checkins] GH-95245: Move weakreflist into the pre-header. (GH-95996) Message-ID: <mailman.688.1660654652.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5a8c15819c27c516e5b75b7c9d89eacdb16b77c3 commit: 5a8c15819c27c516e5b75b7c9d89eacdb16b77c3 branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-16T13:57:18+01:00 summary: GH-95245: Move weakreflist into the pre-header. (GH-95996) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-15-12-41-14.gh-issue-95245.N4gOUV.rst M Include/internal/pycore_object.h M Include/object.h M Lib/test/test_capi.py M Modules/_testcapi/heaptype.c M Objects/typeobject.c diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 5a328f04bae7..8b78f79e950e 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -279,7 +279,7 @@ static inline size_t _PyType_PreHeaderSize(PyTypeObject *tp) { return _PyType_IS_GC(tp) * sizeof(PyGC_Head) + - _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *); + _PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER) * 2 * sizeof(PyObject *); } void _PyObject_GC_Link(PyObject *op); @@ -296,7 +296,7 @@ extern int _Py_CheckSlotResult( // Test if a type supports weak references static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) { - return (type->tp_weaklistoffset > 0); + return (type->tp_weaklistoffset != 0); } extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems); @@ -346,7 +346,7 @@ _PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values) ptr->values = ((char *)values) - 1; } -#define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3) +#define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-4) extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); extern void _PyObject_FreeInstanceAttributes(PyObject *obj); diff --git a/Include/object.h b/Include/object.h index 7d499d8b306e..21d3a75834eb 100644 --- a/Include/object.h +++ b/Include/object.h @@ -360,12 +360,18 @@ given type object has a specified feature. /* Track types initialized using _PyStaticType_InitBuiltin(). */ #define _Py_TPFLAGS_STATIC_BUILTIN (1 << 1) +/* Placement of weakref pointers are managed by the VM, not by the type. + * The VM will automatically set tp_weaklistoffset. + */ +#define Py_TPFLAGS_MANAGED_WEAKREF (1 << 3) + /* Placement of dict (and values) pointers are managed by the VM, not by the type. - * The VM will automatically set tp_dictoffset. Should not be used for variable sized - * classes, such as classes that extend tuple. + * The VM will automatically set tp_dictoffset. */ #define Py_TPFLAGS_MANAGED_DICT (1 << 4) +#define Py_TPFLAGS_PREHEADER (Py_TPFLAGS_MANAGED_WEAKREF | Py_TPFLAGS_MANAGED_DICT) + /* Set if instances of the type object are treated as sequences for pattern matching */ #define Py_TPFLAGS_SEQUENCE (1 << 5) /* Set if instances of the type object are treated as mappings for pattern matching */ diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index e4d20355d430..e6516b33aec0 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -579,6 +579,37 @@ def test_heaptype_with_weakref(self): self.assertEqual(ref(), inst) self.assertEqual(inst.weakreflist, ref) + def test_heaptype_with_managed_weakref(self): + inst = _testcapi.HeapCTypeWithManagedWeakref() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + + def test_sublclassing_managed_weakref(self): + + class C(_testcapi.HeapCTypeWithManagedWeakref): + pass + + inst = C() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + + def test_sublclassing_managed_both(self): + + class C1(_testcapi.HeapCTypeWithManagedWeakref, _testcapi.HeapCTypeWithManagedDict): + pass + + class C2(_testcapi.HeapCTypeWithManagedDict, _testcapi.HeapCTypeWithManagedWeakref): + pass + + for cls in (C1, C2): + inst = cls() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + inst.spam = inst + del inst + ref = weakref.ref(cls()) + self.assertIs(ref(), None) + def test_heaptype_with_buffer(self): inst = _testcapi.HeapCTypeWithBuffer() b = bytes(inst) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-15-12-41-14.gh-issue-95245.N4gOUV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-12-41-14.gh-issue-95245.N4gOUV.rst new file mode 100644 index 000000000000..4449ddd8ded8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-12-41-14.gh-issue-95245.N4gOUV.rst @@ -0,0 +1,3 @@ +Reduces the size of a "simple" Python object from 8 to 6 words by moving the +weakreflist pointer into the pre-header directly before the object's +dict/values pointer. diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index eca95450df98..bf80fd64d80b 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -801,6 +801,32 @@ static PyType_Spec HeapCTypeWithManagedDict_spec = { HeapCTypeWithManagedDict_slots }; +static void +heapctypewithmanagedweakref_dealloc(PyObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + PyObject_ClearWeakRefs(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithManagedWeakref_slots[] = { + {Py_tp_traverse, heapgcctype_traverse}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithmanagedweakref_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithManagedWeakref_spec = { + "_testcapi.HeapCTypeWithManagedWeakref", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF, + HeapCTypeWithManagedWeakref_slots +}; + static struct PyMemberDef heapctypewithnegativedict_members[] = { {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, @@ -1009,6 +1035,12 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { } PyModule_AddObject(m, "HeapCTypeWithManagedDict", HeapCTypeWithManagedDict); + PyObject *HeapCTypeWithManagedWeakref = PyType_FromSpec(&HeapCTypeWithManagedWeakref_spec); + if (HeapCTypeWithManagedWeakref == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithManagedWeakref", HeapCTypeWithManagedWeakref); + PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); if (HeapCTypeWithWeakref == NULL) { return -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 67dfc6f8483d..c881aeb63d75 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2497,10 +2497,11 @@ subtype_getweakref(PyObject *obj, void *context) return NULL; } _PyObject_ASSERT((PyObject *)type, - type->tp_weaklistoffset > 0); + type->tp_weaklistoffset > 0 || + type->tp_weaklistoffset == MANAGED_WEAKREF_OFFSET); _PyObject_ASSERT((PyObject *)type, - ((type->tp_weaklistoffset + sizeof(PyObject *)) - <= (size_t)(type->tp_basicsize))); + ((type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject *)) + <= type->tp_basicsize)); weaklistptr = (PyObject **)((char *)obj + type->tp_weaklistoffset); if (*weaklistptr == NULL) result = Py_None; @@ -3093,9 +3094,9 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) } if (ctx->add_weak) { - assert(!ctx->base->tp_itemsize); - type->tp_weaklistoffset = slotoffset; - slotoffset += sizeof(PyObject *); + assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0); + type->tp_flags |= Py_TPFLAGS_MANAGED_WEAKREF; + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; } if (ctx->add_dict) { assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); @@ -5116,9 +5117,9 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* !same_slots_added(newbase, oldbase))) { goto differs; } - /* The above does not check for managed __dicts__ */ - if ((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == - ((newto->tp_flags & Py_TPFLAGS_MANAGED_DICT))) + /* The above does not check for the preheader */ + if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == + ((newto->tp_flags & Py_TPFLAGS_PREHEADER))) { return 1; } @@ -5217,7 +5218,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure) if (compatible_for_assignment(oldto, newto, "__class__")) { /* Changing the class will change the implicit dict keys, * so we must materialize the dictionary first. */ - assert((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == (newto->tp_flags & Py_TPFLAGS_MANAGED_DICT)); + assert((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == (newto->tp_flags & Py_TPFLAGS_PREHEADER)); _PyObject_GetDictPtr(self); if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self))) @@ -5360,7 +5361,7 @@ object_getstate_default(PyObject *obj, int required) { basicsize += sizeof(PyObject *); } - if (Py_TYPE(obj)->tp_weaklistoffset) { + if (Py_TYPE(obj)->tp_weaklistoffset > 0) { basicsize += sizeof(PyObject *); } if (slotnames != Py_None) { @@ -6150,7 +6151,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_clear == NULL) type->tp_clear = base->tp_clear; } - type->tp_flags |= (base->tp_flags & Py_TPFLAGS_MANAGED_DICT); + type->tp_flags |= (base->tp_flags & Py_TPFLAGS_PREHEADER); if (type->tp_basicsize == 0) type->tp_basicsize = base->tp_basicsize; @@ -6571,7 +6572,7 @@ type_ready_fill_dict(PyTypeObject *type) } static int -type_ready_dict_offset(PyTypeObject *type) +type_ready_preheader(PyTypeObject *type) { if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) { @@ -6583,6 +6584,18 @@ type_ready_dict_offset(PyTypeObject *type) } type->tp_dictoffset = -1; } + if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) { + if (type->tp_weaklistoffset != 0 && + type->tp_weaklistoffset != MANAGED_WEAKREF_OFFSET) + { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_WEAKREF flag " + "but tp_weaklistoffset is set", + type->tp_name); + return -1; + } + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; + } return 0; } @@ -6802,7 +6815,7 @@ type_ready_post_checks(PyTypeObject *type) return -1; } } - else if (type->tp_dictoffset < sizeof(PyObject)) { + else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) { if (type->tp_dictoffset + type->tp_basicsize <= 0) { PyErr_Format(PyExc_SystemError, "type %s has a tp_dictoffset that is too small"); @@ -6847,7 +6860,7 @@ type_ready(PyTypeObject *type) if (type_ready_inherit(type) < 0) { return -1; } - if (type_ready_dict_offset(type) < 0) { + if (type_ready_preheader(type) < 0) { return -1; } if (type_ready_set_hash(type) < 0) { From webhook-mailer at python.org Tue Aug 16 10:18:34 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 16 Aug 2022 14:18:34 -0000 Subject: [Python-checkins] remove repetitive credit from what's new in 3.11 rst (GH-96024) (GH-96025) Message-ID: <mailman.689.1660659515.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f6aa6ebf43edb1be3874e0ce137f315df99eafc8 commit: f6aa6ebf43edb1be3874e0ce137f315df99eafc8 branch: 3.11 author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-16T15:18:20+01:00 summary: remove repetitive credit from what's new in 3.11 rst (GH-96024) (GH-96025) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 99cf77dadb56..2fd8ee31f859 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -64,7 +64,6 @@ Summary -- Release highlights New syntax features: * :pep:`654`: Exception Groups and ``except*``. - (Contributed by Irit Katriel in :issue:`45292`.) New built-in features: From webhook-mailer at python.org Tue Aug 16 11:52:15 2022 From: webhook-mailer at python.org (gvanrossum) Date: Tue, 16 Aug 2022 15:52:15 -0000 Subject: [Python-checkins] GH-95736: fix IsolatedAsyncioTestCase to initialize Runner before calling setup functions (#95898) Message-ID: <mailman.690.1660665136.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9d515997f943b7b510268448f372dabcbf957858 commit: 9d515997f943b7b510268448f372dabcbf957858 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-16T08:52:06-07:00 summary: GH-95736: fix IsolatedAsyncioTestCase to initialize Runner before calling setup functions (#95898) files: A Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst M Lib/test/test_unittest/test_async_case.py M Lib/unittest/async_case.py diff --git a/Lib/test/test_unittest/test_async_case.py b/Lib/test/test_unittest/test_async_case.py index beadcac070b4..f59fc760d381 100644 --- a/Lib/test/test_unittest/test_async_case.py +++ b/Lib/test/test_unittest/test_async_case.py @@ -434,6 +434,21 @@ async def cleanup(self, fut): test.doCleanups() self.assertEqual(events, ['asyncSetUp', 'test', 'cleanup']) + def test_setup_get_event_loop(self): + # See https://github.com/python/cpython/issues/95736 + # Make sure the default event loop is not used + asyncio.set_event_loop(None) + + class TestCase1(unittest.IsolatedAsyncioTestCase): + def setUp(self): + asyncio.get_event_loop_policy().get_event_loop() + + async def test_demo1(self): + pass + + test = TestCase1('test_demo1') + result = test.run() + self.assertTrue(result.wasSuccessful()) if __name__ == "__main__": unittest.main() diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index a90eed98f871..8b06fad06209 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -116,6 +116,10 @@ def _setupAsyncioRunner(self): assert self._asyncioRunner is None, 'asyncio runner is already initialized' runner = asyncio.Runner(debug=True) self._asyncioRunner = runner + # Force loop to be initialized and set as the current loop + # so that setUp functions can use get_event_loop() and get the + # correct loop instance. + runner.get_loop() def _tearDownAsyncioRunner(self): runner = self._asyncioRunner diff --git a/Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst b/Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst new file mode 100644 index 000000000000..abc270fe35ca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst @@ -0,0 +1 @@ +Fix :class:`unittest.IsolatedAsyncioTestCase` to set event loop before calling setup functions. Patch by Kumar Aditya. From webhook-mailer at python.org Tue Aug 16 11:54:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 16 Aug 2022 15:54:18 -0000 Subject: [Python-checkins] gh-94823: Improve coverage in tokenizer.c:valid_utf8 (GH-94856) Message-ID: <mailman.691.1660665259.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f215d7cac9a6f9b51ba864e4252686dee4e45d64 commit: f215d7cac9a6f9b51ba864e4252686dee4e45d64 branch: main author: Michael Droettboom <mdboom at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-16T08:54:13-07:00 summary: gh-94823: Improve coverage in tokenizer.c:valid_utf8 (GH-94856) When loading a source file from disk, there is a separate UTF-8 validator distinct from the one in `unicode_decode_utf8`. This exercises that code path with the same set of invalid inputs as we use for testing the "other" UTF-8 decoder. files: M Lib/test/test_source_encoding.py diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index a0375fda0d3..e1b0de2adef 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -224,6 +224,67 @@ def test_crcrcrlf2(self): out = self.check_script_output(src, br"'\n\n\n'") +class UTF8ValidatorTest(unittest.TestCase): + @unittest.skipIf(not sys.platform.startswith("linux"), + "Too slow to run on non-Linux platforms") + def test_invalid_utf8(self): + # This is a port of test_utf8_decode_invalid_sequences in + # test_unicode.py to exercise the separate utf8 validator in + # Parser/tokenizer.c used when reading source files. + + # That file is written using low-level C file I/O, so the only way to + # test it is to write actual files to disk. + + # Each example is put inside a string at the top of the file so + # it's an otherwise valid Python source file. + template = b'"%s"\n' + + with tempfile.TemporaryDirectory() as tmpd: + fn = os.path.join(tmpd, 'test.py') + + def check(content): + with open(fn, 'wb') as fp: + fp.write(template % content) + script_helper.assert_python_failure(fn) + + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] + # start bytes of a 2-byte sequence equivalent to code points < 0x7F + invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] + # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF + invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] + ) + + for byte in invalid_start_bytes: + check(byte) + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + check(sb + cb) + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + check(sb+cb1+b'\x80'+cb3) + + for cb in [bytes([x]) for x in range(0x80, 0xA0)]: + check(b'\xE0'+cb+b'\x80') + check(b'\xE0'+cb+b'\xBF') + # surrogates + for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: + check(b'\xED'+cb+b'\x80') + check(b'\xED'+cb+b'\xBF') + for cb in [bytes([x]) for x in range(0x80, 0x90)]: + check(b'\xF0'+cb+b'\x80\x80') + check(b'\xF0'+cb+b'\xBF\xBF') + for cb in [bytes([x]) for x in range(0x90, 0xC0)]: + check(b'\xF4'+cb+b'\x80\x80') + check(b'\xF4'+cb+b'\xBF\xBF') + + class BytesSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase): def check_script_output(self, src, expected): From webhook-mailer at python.org Tue Aug 16 12:26:51 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 16 Aug 2022 16:26:51 -0000 Subject: [Python-checkins] [3.11] gh-94823: Improve coverage in tokenizer.c:valid_utf8 (GH-94856) (#96029) Message-ID: <mailman.692.1660667212.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2bb363cfcd7563fdd29ac93563f95b8a5205b008 commit: 2bb363cfcd7563fdd29ac93563f95b8a5205b008 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-16T17:26:40+01:00 summary: [3.11] gh-94823: Improve coverage in tokenizer.c:valid_utf8 (GH-94856) (#96029) Co-authored-by: Michael Droettboom <mdboom at gmail.com> files: M Lib/test/test_source_encoding.py diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index a0375fda0d36..e1b0de2adef6 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -224,6 +224,67 @@ def test_crcrcrlf2(self): out = self.check_script_output(src, br"'\n\n\n'") +class UTF8ValidatorTest(unittest.TestCase): + @unittest.skipIf(not sys.platform.startswith("linux"), + "Too slow to run on non-Linux platforms") + def test_invalid_utf8(self): + # This is a port of test_utf8_decode_invalid_sequences in + # test_unicode.py to exercise the separate utf8 validator in + # Parser/tokenizer.c used when reading source files. + + # That file is written using low-level C file I/O, so the only way to + # test it is to write actual files to disk. + + # Each example is put inside a string at the top of the file so + # it's an otherwise valid Python source file. + template = b'"%s"\n' + + with tempfile.TemporaryDirectory() as tmpd: + fn = os.path.join(tmpd, 'test.py') + + def check(content): + with open(fn, 'wb') as fp: + fp.write(template % content) + script_helper.assert_python_failure(fn) + + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] + # start bytes of a 2-byte sequence equivalent to code points < 0x7F + invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] + # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF + invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] + ) + + for byte in invalid_start_bytes: + check(byte) + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + check(sb + cb) + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + check(sb+cb1+b'\x80'+cb3) + + for cb in [bytes([x]) for x in range(0x80, 0xA0)]: + check(b'\xE0'+cb+b'\x80') + check(b'\xE0'+cb+b'\xBF') + # surrogates + for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: + check(b'\xED'+cb+b'\x80') + check(b'\xED'+cb+b'\xBF') + for cb in [bytes([x]) for x in range(0x80, 0x90)]: + check(b'\xF0'+cb+b'\x80\x80') + check(b'\xF0'+cb+b'\xBF\xBF') + for cb in [bytes([x]) for x in range(0x90, 0xC0)]: + check(b'\xF4'+cb+b'\x80\x80') + check(b'\xF4'+cb+b'\xBF\xBF') + + class BytesSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase): def check_script_output(self, src, expected): From webhook-mailer at python.org Tue Aug 16 14:20:24 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 16 Aug 2022 18:20:24 -0000 Subject: [Python-checkins] gh-96005: Handle WASI ENOTCAPABLE in getpath (GH-96006) Message-ID: <mailman.693.1660674026.3313.python-checkins@python.org> https://github.com/python/cpython/commit/48174fa0b949d6b1d0c1f074e7d4e47793759a43 commit: 48174fa0b949d6b1d0c1f074e7d4e47793759a43 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-16T20:20:15+02:00 summary: gh-96005: Handle WASI ENOTCAPABLE in getpath (GH-96006) - On WASI `ENOTCAPABLE` is now mapped to `PermissionError`. - The `errno` modules exposes the new error number. - `getpath.py` now ignores `PermissionError` when it cannot open landmark files `pybuilddir.txt` and `pyenv.cfg`. files: A Misc/NEWS.d/next/Core and Builtins/2022-08-15-21-08-11.gh-issue-96005.6eoc8k.rst M Doc/library/errno.rst M Doc/library/exceptions.rst M Modules/errnomodule.c M Modules/getpath.py M Objects/exceptions.c diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index 035340e25687..da4e964ac3f0 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -657,3 +657,12 @@ defined by the module. The specific list of defined symbols is available as Interface output queue is full .. versionadded:: 3.11 + +.. data:: ENOTCAPABLE + + Capabilities insufficient. This error is mapped to the exception + :exc:`PermissionError`. + + .. availability:: WASI + + .. versionadded:: 3.11.1 diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 2eccbd17c482..fc856277d67b 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -746,7 +746,12 @@ depending on the system error code. Raised when trying to run an operation without the adequate access rights - for example filesystem permissions. - Corresponds to :c:data:`errno` :py:data:`~errno.EACCES` and :py:data:`~errno.EPERM`. + Corresponds to :c:data:`errno` :py:data:`~errno.EACCES`, + :py:data:`~errno.EPERM`, and :py:data:`~errno.ENOTCAPABLE`. + + .. versionchanged:: 3.11.1 + WASI's :py:data:`~errno.ENOTCAPABLE` is now mapped to + :exc:`PermissionError`. .. exception:: ProcessLookupError diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-15-21-08-11.gh-issue-96005.6eoc8k.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-21-08-11.gh-issue-96005.6eoc8k.rst new file mode 100644 index 000000000000..06e414bca0f9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-21-08-11.gh-issue-96005.6eoc8k.rst @@ -0,0 +1,4 @@ +On WASI :data:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. +The :mod:`errno` modules exposes the new error number. ``getpath.py`` now +ignores :exc:`PermissionError` when it cannot open landmark files +``pybuilddir.txt`` and ``pyenv.cfg``. diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c index 0516e7367050..4de4144520aa 100644 --- a/Modules/errnomodule.c +++ b/Modules/errnomodule.c @@ -927,6 +927,10 @@ errno_exec(PyObject *module) #ifdef EQFULL add_errcode("EQFULL", EQFULL, "Interface output queue is full"); #endif +#ifdef ENOTCAPABLE + // WASI extension + add_errcode("ENOTCAPABLE", ENOTCAPABLE, "Capabilities insufficient"); +#endif Py_DECREF(error_dict); return 0; diff --git a/Modules/getpath.py b/Modules/getpath.py index a50313aea78b..e3558bc49e38 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -351,11 +351,11 @@ def search_up(prefix, *landmarks, test=isfile): try: # Read pyvenv.cfg from one level above executable pyvenvcfg = readlines(joinpath(venv_prefix, VENV_LANDMARK)) - except FileNotFoundError: + except (FileNotFoundError, PermissionError): # Try the same directory as executable pyvenvcfg = readlines(joinpath(venv_prefix2, VENV_LANDMARK)) venv_prefix = venv_prefix2 - except FileNotFoundError: + except (FileNotFoundError, PermissionError): venv_prefix = None pyvenvcfg = [] @@ -475,7 +475,7 @@ def search_up(prefix, *landmarks, test=isfile): # File exists but is empty platstdlib_dir = real_executable_dir build_prefix = joinpath(real_executable_dir, VPATH) - except FileNotFoundError: + except (FileNotFoundError, PermissionError): if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)): build_prefix = joinpath(real_executable_dir, VPATH) if os_name == 'nt': diff --git a/Objects/exceptions.c b/Objects/exceptions.c index c56886870d3c..3703fdcda4db 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -3635,6 +3635,11 @@ _PyExc_InitState(PyInterpreterState *interp) ADD_ERRNO(InterruptedError, EINTR); ADD_ERRNO(PermissionError, EACCES); ADD_ERRNO(PermissionError, EPERM); +#ifdef ENOTCAPABLE + // Extension for WASI capability-based security. Process lacks + // capability to access a resource. + ADD_ERRNO(PermissionError, ENOTCAPABLE); +#endif ADD_ERRNO(ProcessLookupError, ESRCH); ADD_ERRNO(TimeoutError, ETIMEDOUT); From webhook-mailer at python.org Tue Aug 16 14:22:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 16 Aug 2022 18:22:18 -0000 Subject: [Python-checkins] GH-95909: Make `_PyArg_Parser` initialization thread safe (GH-95958) Message-ID: <mailman.694.1660674140.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9b30b965f0c1da216397b495faef4d93ff7a5328 commit: 9b30b965f0c1da216397b495faef4d93ff7a5328 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-16T11:22:14-07:00 summary: GH-95909: Make `_PyArg_Parser` initialization thread safe (GH-95958) files: M Include/internal/pycore_runtime.h M Python/getargs.c M Python/pystate.c diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index ae63ae74afa5..2c04ead45869 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -14,6 +14,9 @@ extern "C" { #include "pycore_interp.h" // PyInterpreterState #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids +struct _getargs_runtime_state { + PyThread_type_lock mutex; +}; /* ceval state */ @@ -114,6 +117,7 @@ typedef struct pyruntimestate { struct _ceval_runtime_state ceval; struct _gilstate_runtime_state gilstate; + struct _getargs_runtime_state getargs; PyPreConfig preconfig; diff --git a/Python/getargs.c b/Python/getargs.c index 457dd99ce4a5..f0b84b8338dd 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1974,15 +1974,10 @@ new_kwtuple(const char * const *keywords, int total, int pos) } static int -parser_init(struct _PyArg_Parser *parser) +_parser_init(struct _PyArg_Parser *parser) { const char * const *keywords = parser->keywords; assert(keywords != NULL); - - if (parser->initialized) { - assert(parser->kwtuple != NULL); - return 1; - } assert(parser->pos == 0 && (parser->format == NULL || parser->fname == NULL) && parser->custom_msg == NULL && @@ -2035,6 +2030,28 @@ parser_init(struct _PyArg_Parser *parser) return 1; } +static int +parser_init(struct _PyArg_Parser *parser) +{ + // volatile as it can be modified by other threads + // and should not be optimized or reordered by compiler + if (*((volatile int *)&parser->initialized)) { + assert(parser->kwtuple != NULL); + return 1; + } + PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK); + // Check again if another thread initialized the parser + // while we were waiting for the lock. + if (*((volatile int *)&parser->initialized)) { + assert(parser->kwtuple != NULL); + PyThread_release_lock(_PyRuntime.getargs.mutex); + return 1; + } + int ret = _parser_init(parser); + PyThread_release_lock(_PyRuntime.getargs.mutex); + return ret; +} + static void parser_clear(struct _PyArg_Parser *parser) { diff --git a/Python/pystate.c b/Python/pystate.c index bcdb825a8629..642d680ba20b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -57,7 +57,7 @@ _Py_COMP_DIAG_POP static int alloc_for_runtime(PyThread_type_lock *plock1, PyThread_type_lock *plock2, - PyThread_type_lock *plock3) + PyThread_type_lock *plock3, PyThread_type_lock *plock4) { /* Force default allocator, since _PyRuntimeState_Fini() must use the same allocator than this function. */ @@ -82,11 +82,20 @@ alloc_for_runtime(PyThread_type_lock *plock1, PyThread_type_lock *plock2, return -1; } + PyThread_type_lock lock4 = PyThread_allocate_lock(); + if (lock4 == NULL) { + PyThread_free_lock(lock1); + PyThread_free_lock(lock2); + PyThread_free_lock(lock3); + return -1; + } + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); *plock1 = lock1; *plock2 = lock2; *plock3 = lock3; + *plock4 = lock4; return 0; } @@ -97,7 +106,8 @@ init_runtime(_PyRuntimeState *runtime, Py_ssize_t unicode_next_index, PyThread_type_lock unicode_ids_mutex, PyThread_type_lock interpreters_mutex, - PyThread_type_lock xidregistry_mutex) + PyThread_type_lock xidregistry_mutex, + PyThread_type_lock getargs_mutex) { if (runtime->_initialized) { Py_FatalError("runtime already initialized"); @@ -119,6 +129,8 @@ init_runtime(_PyRuntimeState *runtime, runtime->xidregistry.mutex = xidregistry_mutex; + runtime->getargs.mutex = getargs_mutex; + // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); @@ -141,8 +153,8 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) // is called multiple times. Py_ssize_t unicode_next_index = runtime->unicode_ids.next_index; - PyThread_type_lock lock1, lock2, lock3; - if (alloc_for_runtime(&lock1, &lock2, &lock3) != 0) { + PyThread_type_lock lock1, lock2, lock3, lock4; + if (alloc_for_runtime(&lock1, &lock2, &lock3, &lock4) != 0) { return _PyStatus_NO_MEMORY(); } @@ -152,7 +164,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) memcpy(runtime, &initial, sizeof(*runtime)); } init_runtime(runtime, open_code_hook, open_code_userdata, audit_hook_head, - unicode_next_index, lock1, lock2, lock3); + unicode_next_index, lock1, lock2, lock3, lock4); return _PyStatus_OK(); } @@ -172,6 +184,7 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) FREE_LOCK(runtime->interpreters.mutex); FREE_LOCK(runtime->xidregistry.mutex); FREE_LOCK(runtime->unicode_ids.lock); + FREE_LOCK(runtime->getargs.mutex); #undef FREE_LOCK PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -194,6 +207,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock); + int reinit_getargs = _PyThread_at_fork_reinit(&runtime->getargs.mutex); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -204,7 +218,8 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) if (reinit_interp < 0 || reinit_main_id < 0 || reinit_xidregistry < 0 - || reinit_unicode_ids < 0) + || reinit_unicode_ids < 0 + || reinit_getargs < 0) { return _PyStatus_ERR("Failed to reinitialize runtime locks"); From webhook-mailer at python.org Tue Aug 16 21:23:26 2022 From: webhook-mailer at python.org (gvanrossum) Date: Wed, 17 Aug 2022 01:23:26 -0000 Subject: [Python-checkins] GH-95704: Don't suppress errors from tasks when TG is cancelled (#95761) Message-ID: <mailman.695.1660699407.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f51f54f39d384da63be622bcdc9cf4cfb43bad3d commit: f51f54f39d384da63be622bcdc9cf4cfb43bad3d branch: main author: Guido van Rossum <guido at python.org> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-16T18:23:06-07:00 summary: GH-95704: Don't suppress errors from tasks when TG is cancelled (#95761) When a task catches CancelledError and raises some other error, the other error should not silently be suppressed. Any scenario where a task crashes in cleanup upon cancellation will now result in an ExceptionGroup wrapping the crash(es) instead of propagating CancelledError and ignoring the side errors. NOTE: This represents a change in behavior (hence the need to change several tests). But it is only an edge case. Co-authored-by: Thomas Grainger <tagrain at gmail.com> files: A Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst M Lib/asyncio/taskgroups.py M Lib/test/test_asyncio/test_taskgroups.py diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 9be4838e3c7a..5d5e2a8a85dd 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -116,10 +116,9 @@ async def __aexit__(self, et, exc, tb): if self._base_error is not None: raise self._base_error - if propagate_cancellation_error is not None: - # The wrapping task was cancelled; since we're done with - # closing all child tasks, just propagate the cancellation - # request now. + # Propagate CancelledError if there is one, except if there + # are other errors -- those have priority. + if propagate_cancellation_error and not self._errors: raise propagate_cancellation_error if et is not None and et is not exceptions.CancelledError: diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 74bae06af8e7..6a0231f2859a 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -230,29 +230,29 @@ async def runner(): self.assertEqual(NUM, 15) - async def test_cancellation_in_body(self): + async def test_taskgroup_08(self): async def foo(): - await asyncio.sleep(0.1) - 1 / 0 + try: + await asyncio.sleep(10) + finally: + 1 / 0 async def runner(): async with taskgroups.TaskGroup() as g: for _ in range(5): g.create_task(foo()) - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - raise + await asyncio.sleep(10) r = asyncio.create_task(runner()) await asyncio.sleep(0.1) self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError) as cm: + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) async def test_taskgroup_09(self): @@ -316,8 +316,10 @@ async def runner(): async def test_taskgroup_11(self): async def foo(): - await asyncio.sleep(0.1) - 1 / 0 + try: + await asyncio.sleep(10) + finally: + 1 / 0 async def runner(): async with taskgroups.TaskGroup(): @@ -325,24 +327,26 @@ async def runner(): for _ in range(5): g2.create_task(foo()) - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - raise + await asyncio.sleep(10) r = asyncio.create_task(runner()) await asyncio.sleep(0.1) self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError}) + async def test_taskgroup_12(self): async def foo(): - await asyncio.sleep(0.1) - 1 / 0 + try: + await asyncio.sleep(10) + finally: + 1 / 0 async def runner(): async with taskgroups.TaskGroup() as g1: @@ -352,19 +356,19 @@ async def runner(): for _ in range(5): g2.create_task(foo()) - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - raise + await asyncio.sleep(10) r = asyncio.create_task(runner()) await asyncio.sleep(0.1) self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError}) + async def test_taskgroup_13(self): async def crash_after(t): @@ -424,8 +428,9 @@ async def runner(): self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) async def test_taskgroup_16(self): @@ -451,8 +456,9 @@ async def runner(): self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) async def test_taskgroup_17(self): NUM = 0 diff --git a/Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst b/Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst new file mode 100644 index 000000000000..31f9fc6547d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst @@ -0,0 +1,2 @@ +When a task catches :exc:`asyncio.CancelledError` and raises some other error, +the other error should generally not silently be suppressed. From webhook-mailer at python.org Wed Aug 17 01:24:58 2022 From: webhook-mailer at python.org (tiran) Date: Wed, 17 Aug 2022 05:24:58 -0000 Subject: [Python-checkins] gh-96005: FreeBSD has ENOTCAPABLE, too (GH-96034) Message-ID: <mailman.696.1660713899.3313.python-checkins@python.org> https://github.com/python/cpython/commit/da0aa518bf5e6ac9de444a405c40649cfb0245eb commit: da0aa518bf5e6ac9de444a405c40649cfb0245eb branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-17T07:24:53+02:00 summary: gh-96005: FreeBSD has ENOTCAPABLE, too (GH-96034) files: M Doc/library/errno.rst M Lib/test/test_exception_hierarchy.py diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index da4e964ac3f..5122c69697e 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -663,6 +663,6 @@ defined by the module. The specific list of defined symbols is available as Capabilities insufficient. This error is mapped to the exception :exc:`PermissionError`. - .. availability:: WASI + .. availability:: WASI, FreeBSD .. versionadded:: 3.11.1 diff --git a/Lib/test/test_exception_hierarchy.py b/Lib/test/test_exception_hierarchy.py index 89fe9ddcefb..3318fa8e774 100644 --- a/Lib/test/test_exception_hierarchy.py +++ b/Lib/test/test_exception_hierarchy.py @@ -63,7 +63,7 @@ def test_select_error(self): +-- InterruptedError EINTR +-- IsADirectoryError EISDIR +-- NotADirectoryError ENOTDIR - +-- PermissionError EACCES, EPERM + +-- PermissionError EACCES, EPERM, ENOTCAPABLE +-- ProcessLookupError ESRCH +-- TimeoutError ETIMEDOUT """ @@ -75,6 +75,8 @@ def _make_map(s): continue excname, _, errnames = line.partition(' ') for errname in filter(None, errnames.strip().split(', ')): + if errname == "ENOTCAPABLE" and not hasattr(errno, errname): + continue _map[getattr(errno, errname)] = getattr(builtins, excname) return _map _map = _make_map(_pep_map) @@ -91,7 +93,7 @@ def test_errno_mapping(self): othercodes = set(errno.errorcode) - set(self._map) for errcode in othercodes: e = OSError(errcode, "Some message") - self.assertIs(type(e), OSError) + self.assertIs(type(e), OSError, repr(e)) def test_try_except(self): filename = "some_hopefully_non_existing_file" From webhook-mailer at python.org Wed Aug 17 05:05:56 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 17 Aug 2022 09:05:56 -0000 Subject: [Python-checkins] gh-95736: Fix event loop creation in IsolatedAsyncioTestCase (GH-96033) Message-ID: <mailman.697.1660727158.3313.python-checkins@python.org> https://github.com/python/cpython/commit/36517101dd80cae93da379e95e98a688c52935b7 commit: 36517101dd80cae93da379e95e98a688c52935b7 branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-17T02:05:17-07:00 summary: gh-95736: Fix event loop creation in IsolatedAsyncioTestCase (GH-96033) It should be created before calling the setUp() method, but after checking for skipping a test. Automerge-Triggered-By: GH:tiran files: M Lib/unittest/async_case.py diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index 8b06fad0620..3457e92e5da 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -79,6 +79,10 @@ async def enterAsyncContext(self, cm): return result def _callSetUp(self): + # Force loop to be initialized and set as the current loop + # so that setUp functions can use get_event_loop() and get the + # correct loop instance. + self._asyncioRunner.get_loop() self._asyncioTestContext.run(self.setUp) self._callAsync(self.asyncSetUp) @@ -116,10 +120,6 @@ def _setupAsyncioRunner(self): assert self._asyncioRunner is None, 'asyncio runner is already initialized' runner = asyncio.Runner(debug=True) self._asyncioRunner = runner - # Force loop to be initialized and set as the current loop - # so that setUp functions can use get_event_loop() and get the - # correct loop instance. - runner.get_loop() def _tearDownAsyncioRunner(self): runner = self._asyncioRunner From webhook-mailer at python.org Wed Aug 17 07:37:22 2022 From: webhook-mailer at python.org (markshannon) Date: Wed, 17 Aug 2022 11:37:22 -0000 Subject: [Python-checkins] GH-93911: Specialize `LOAD_ATTR` for custom `__getattribute__` (GH-93988) Message-ID: <mailman.698.1660736244.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7276ca25f5f1440aa4d025350d3de15141854dde commit: 7276ca25f5f1440aa4d025350d3de15141854dde branch: main author: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> committer: markshannon <mark at hotpy.org> date: 2022-08-17T12:37:07+01:00 summary: GH-93911: Specialize `LOAD_ATTR` for custom `__getattribute__` (GH-93988) files: A Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst M Include/internal/pycore_code.h M Include/internal/pycore_opcode.h M Include/internal/pycore_typeobject.h M Include/opcode.h M Lib/opcode.py M Objects/typeobject.c M Python/ceval.c M Python/opcode_targets.h M Python/pylifecycle.c M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 61e40eb8a94..7d5fe941fcb 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -118,6 +118,7 @@ struct callable_cache { PyObject *isinstance; PyObject *len; PyObject *list_append; + PyObject *object__getattribute__; }; /* "Locals plus" for a code object is the set of locals + cell vars + diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index 90bf5bbd1ba..6906cd5c788 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -152,6 +152,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_ATTR] = LOAD_ATTR, [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, [LOAD_ATTR_CLASS] = LOAD_ATTR, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, @@ -315,20 +316,20 @@ static const char *const _PyOpcode_OpName[267] = { [PRINT_EXPR] = "PRINT_EXPR", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", - [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", + [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", - [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [LIST_TO_TUPLE] = "LIST_TO_TUPLE", [RETURN_VALUE] = "RETURN_VALUE", [IMPORT_STAR] = "IMPORT_STAR", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [POP_EXCEPT] = "POP_EXCEPT", @@ -355,7 +356,7 @@ static const char *const _PyOpcode_OpName[267] = { [JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", + [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -363,7 +364,7 @@ static const char *const _PyOpcode_OpName[267] = { [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", @@ -383,9 +384,9 @@ static const char *const _PyOpcode_OpName[267] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", - [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", @@ -395,37 +396,37 @@ static const char *const _PyOpcode_OpName[267] = { [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [RESUME_QUICK] = "RESUME_QUICK", [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", - [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", + [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", - [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [CALL] = "CALL", [KW_NAMES] = "KW_NAMES", [POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE", [POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE", [POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", + [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", - [183] = "<183>", [184] = "<184>", [185] = "<185>", [186] = "<186>", @@ -513,7 +514,6 @@ static const char *const _PyOpcode_OpName[267] = { #endif #define EXTRA_CASES \ - case 183: \ case 184: \ case 185: \ case 186: \ diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 4eb0efcedb5..2efe3881007 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -75,6 +75,9 @@ extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type); extern void _PyStaticType_Dealloc(PyTypeObject *type); +PyObject *_Py_slot_tp_getattro(PyObject *self, PyObject *name); +PyObject *_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name); + #ifdef __cplusplus } #endif diff --git a/Include/opcode.h b/Include/opcode.h index f90ebb1d6e0..210e3fe002c 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -176,35 +176,36 @@ extern "C" { #define JUMP_BACKWARD_QUICK 66 #define LOAD_ATTR_ADAPTIVE 67 #define LOAD_ATTR_CLASS 72 -#define LOAD_ATTR_INSTANCE_VALUE 73 -#define LOAD_ATTR_MODULE 76 -#define LOAD_ATTR_PROPERTY 77 -#define LOAD_ATTR_SLOT 78 -#define LOAD_ATTR_WITH_HINT 79 -#define LOAD_ATTR_METHOD_LAZY_DICT 80 -#define LOAD_ATTR_METHOD_NO_DICT 81 -#define LOAD_ATTR_METHOD_WITH_DICT 86 -#define LOAD_ATTR_METHOD_WITH_VALUES 113 -#define LOAD_CONST__LOAD_FAST 121 -#define LOAD_FAST__LOAD_CONST 141 -#define LOAD_FAST__LOAD_FAST 143 -#define LOAD_GLOBAL_ADAPTIVE 153 -#define LOAD_GLOBAL_BUILTIN 154 -#define LOAD_GLOBAL_MODULE 158 -#define RESUME_QUICK 159 -#define STORE_ATTR_ADAPTIVE 160 -#define STORE_ATTR_INSTANCE_VALUE 161 -#define STORE_ATTR_SLOT 166 -#define STORE_ATTR_WITH_HINT 167 -#define STORE_FAST__LOAD_FAST 168 -#define STORE_FAST__STORE_FAST 169 -#define STORE_SUBSCR_ADAPTIVE 170 -#define STORE_SUBSCR_DICT 177 -#define STORE_SUBSCR_LIST_INT 178 -#define UNPACK_SEQUENCE_ADAPTIVE 179 -#define UNPACK_SEQUENCE_LIST 180 -#define UNPACK_SEQUENCE_TUPLE 181 -#define UNPACK_SEQUENCE_TWO_TUPLE 182 +#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 73 +#define LOAD_ATTR_INSTANCE_VALUE 76 +#define LOAD_ATTR_MODULE 77 +#define LOAD_ATTR_PROPERTY 78 +#define LOAD_ATTR_SLOT 79 +#define LOAD_ATTR_WITH_HINT 80 +#define LOAD_ATTR_METHOD_LAZY_DICT 81 +#define LOAD_ATTR_METHOD_NO_DICT 86 +#define LOAD_ATTR_METHOD_WITH_DICT 113 +#define LOAD_ATTR_METHOD_WITH_VALUES 121 +#define LOAD_CONST__LOAD_FAST 141 +#define LOAD_FAST__LOAD_CONST 143 +#define LOAD_FAST__LOAD_FAST 153 +#define LOAD_GLOBAL_ADAPTIVE 154 +#define LOAD_GLOBAL_BUILTIN 158 +#define LOAD_GLOBAL_MODULE 159 +#define RESUME_QUICK 160 +#define STORE_ATTR_ADAPTIVE 161 +#define STORE_ATTR_INSTANCE_VALUE 166 +#define STORE_ATTR_SLOT 167 +#define STORE_ATTR_WITH_HINT 168 +#define STORE_FAST__LOAD_FAST 169 +#define STORE_FAST__STORE_FAST 170 +#define STORE_SUBSCR_ADAPTIVE 177 +#define STORE_SUBSCR_DICT 178 +#define STORE_SUBSCR_LIST_INT 179 +#define UNPACK_SEQUENCE_ADAPTIVE 180 +#define UNPACK_SEQUENCE_LIST 181 +#define UNPACK_SEQUENCE_TUPLE 182 +#define UNPACK_SEQUENCE_TWO_TUPLE 183 #define DO_TRACING 255 #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\ diff --git a/Lib/opcode.py b/Lib/opcode.py index 8a07fb75b2e..665852291a6 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -338,6 +338,7 @@ def pseudo_op(name, op, real_ops): "LOAD_ATTR_ADAPTIVE", # These potentially push [NULL, bound method] onto the stack. "LOAD_ATTR_CLASS", + "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", "LOAD_ATTR_INSTANCE_VALUE", "LOAD_ATTR_MODULE", "LOAD_ATTR_PROPERTY", diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst new file mode 100644 index 00000000000..9fc0df5266d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst @@ -0,0 +1 @@ +Specialize ``LOAD_ATTR`` for objects with custom ``__getattr__`` and ``__getattribute__``. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c881aeb63d7..f796a91b3c2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -8102,17 +8102,17 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) /* There are two slot dispatch functions for tp_getattro. - - slot_tp_getattro() is used when __getattribute__ is overridden + - _Py_slot_tp_getattro() is used when __getattribute__ is overridden but no __getattr__ hook is present; - - slot_tp_getattr_hook() is used when a __getattr__ hook is present. + - _Py_slot_tp_getattr_hook() is used when a __getattr__ hook is present. - The code in update_one_slot() always installs slot_tp_getattr_hook(); this - detects the absence of __getattr__ and then installs the simpler slot if - necessary. */ + The code in update_one_slot() always installs _Py_slot_tp_getattr_hook(); + this detects the absence of __getattr__ and then installs the simpler + slot if necessary. */ -static PyObject * -slot_tp_getattro(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattro(PyObject *self, PyObject *name) { PyObject *stack[2] = {self, name}; return vectorcall_method(&_Py_ID(__getattribute__), stack, 2); @@ -8143,8 +8143,8 @@ call_attribute(PyObject *self, PyObject *attr, PyObject *name) return res; } -static PyObject * -slot_tp_getattr_hook(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name) { PyTypeObject *tp = Py_TYPE(self); PyObject *getattr, *getattribute, *res; @@ -8157,8 +8157,8 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) getattr = _PyType_Lookup(tp, &_Py_ID(__getattr__)); if (getattr == NULL) { /* No __getattr__ hook: use a simpler dispatcher */ - tp->tp_getattro = slot_tp_getattro; - return slot_tp_getattro(self, name); + tp->tp_getattro = _Py_slot_tp_getattro; + return _Py_slot_tp_getattro(self, name); } Py_INCREF(getattr); /* speed hack: we could use lookup_maybe, but that would resolve the @@ -8519,10 +8519,10 @@ static slotdef slotdefs[] = { PyWrapperFlag_KEYWORDS), TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, "__str__($self, /)\n--\n\nReturn str(self)."), - TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, + TPSLOT("__getattribute__", tp_getattro, _Py_slot_tp_getattr_hook, wrap_binaryfunc, "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), - TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), + TPSLOT("__getattr__", tp_getattro, _Py_slot_tp_getattr_hook, NULL, ""), TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, diff --git a/Python/ceval.c b/Python/ceval.c index d34d6bfeec0..8c17e51e808 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3698,6 +3698,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); assert(type_version != 0); PyObject *fget = read_obj(cache->descr); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; uint32_t func_version = read_u32(cache->keys_version); assert(func_version != 0); @@ -3709,8 +3710,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_INCREF(fget); _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f); SET_TOP(NULL); - int push_null = !(oparg & 1); - STACK_SHRINK(push_null); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); new_frame->localsplus[0] = owner; for (int i = 1; i < code->co_nlocalsplus; i++) { new_frame->localsplus[i] = NULL; @@ -3724,6 +3725,44 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto start_frame; } + TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { + assert(cframe.use_tracing == 0); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + PyObject *owner = TOP(); + PyTypeObject *cls = Py_TYPE(owner); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + PyObject *getattribute = read_obj(cache->descr); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + PyCodeObject *code = (PyCodeObject *)f->func_code; + DEOPT_IF(((PyCodeObject *)f->func_code)->co_argcount != 2, LOAD_ATTR); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(LOAD_ATTR, hit); + + PyObject *name = GETITEM(names, oparg >> 1); + Py_INCREF(f); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f); + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + Py_INCREF(name); + new_frame->localsplus[0] = owner; + new_frame->localsplus[1] = name; + for (int i = 2; i < code->co_nlocalsplus; i++) { + new_frame->localsplus[i] = NULL; + } + _PyFrame_SetStackPointer(frame, stack_pointer); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + frame->prev_instr = next_instr - 1; + new_frame->previous = frame; + frame = cframe.current_frame = new_frame; + CALL_STAT_INC(inlined_py_calls); + goto start_frame; + } + TARGET(STORE_ATTR_ADAPTIVE) { assert(cframe.use_tracing == 0); _PyAttrCache *cache = (_PyAttrCache *)next_instr; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index c9f65edfad1..db4bbc466a9 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -72,20 +72,20 @@ static void *opcode_targets[256] = { &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, &&TARGET_LOAD_ATTR_CLASS, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, + &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, + &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, - &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_ASYNC_GEN_WRAP, &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, + &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, &&TARGET_POP_JUMP_FORWARD_IF_FALSE, &&TARGET_POP_JUMP_FORWARD_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,7 +120,7 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, @@ -140,9 +140,9 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_LOAD_FAST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, @@ -152,30 +152,31 @@ static void *opcode_targets[256] = { &&TARGET_YIELD_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_LOAD_GLOBAL_ADAPTIVE, - &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, + &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_RESUME_QUICK, &&TARGET_STORE_ATTR_ADAPTIVE, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, - &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_CALL, &&TARGET_KW_NAMES, &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, + &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, @@ -253,6 +254,5 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_DO_TRACING }; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 11a45800533..bb646f1a0ee 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -787,6 +787,9 @@ pycore_init_builtins(PyThreadState *tstate) PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append)); assert(list_append); interp->callable_cache.list_append = list_append; + PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__)); + assert(object__getattribute__); + interp->callable_cache.object__getattribute__ = object__getattribute__; if (_PyBuiltins_AddExceptions(bimod) < 0) { return _PyStatus_ERR("failed to add exceptions to builtins"); diff --git a/Python/specialize.c b/Python/specialize.c index d5877a191a1..2dc7495ec79 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -362,6 +362,8 @@ miss_counter_start(void) { #define SPEC_FAIL_OUT_OF_RANGE 4 #define SPEC_FAIL_EXPECTED_ERROR 5 #define SPEC_FAIL_WRONG_NUMBER_ARGUMENTS 6 +#define SPEC_FAIL_NOT_PY_FUNCTION 7 + #define SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT 18 @@ -387,6 +389,7 @@ miss_counter_start(void) { #define SPEC_FAIL_ATTR_HAS_MANAGED_DICT 25 #define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26 #define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27 +#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28 /* Binary subscr and store subscr */ @@ -498,6 +501,9 @@ miss_counter_start(void) { #define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 8 #define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 9 +static int function_kind(PyCodeObject *code); +static bool function_check_args(PyObject *o, int expected_argcount, int opcode); +static uint32_t function_get_version(PyObject *o, int opcode); static int specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, @@ -557,13 +563,15 @@ typedef enum { MUTABLE, /* Instance of a mutable class; might, or might not, be a descriptor */ ABSENT, /* Attribute is not present on the class */ DUNDER_CLASS, /* __class__ attribute */ - GETSET_OVERRIDDEN /* __getattribute__ or __setattr__ has been overridden */ + GETSET_OVERRIDDEN, /* __getattribute__ or __setattr__ has been overridden */ + GETATTRIBUTE_IS_PYTHON_FUNCTION /* Descriptor requires calling a Python __getattribute__ */ } DescriptorClassification; static DescriptorClassification analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int store) { + bool has_getattr = false; if (store) { if (type->tp_setattro != PyObject_GenericSetAttr) { *descr = NULL; @@ -571,7 +579,42 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto } } else { - if (type->tp_getattro != PyObject_GenericGetAttr) { + getattrofunc getattro_slot = type->tp_getattro; + if (getattro_slot == PyObject_GenericGetAttr) { + /* Normal attribute lookup; */ + has_getattr = false; + } + else if (getattro_slot == _Py_slot_tp_getattr_hook || + getattro_slot == _Py_slot_tp_getattro) { + /* One or both of __getattribute__ or __getattr__ may have been + overridden See typeobject.c for why these functions are special. */ + PyObject *getattribute = _PyType_Lookup(type, + &_Py_ID(__getattribute__)); + PyInterpreterState *interp = _PyInterpreterState_GET(); + bool has_custom_getattribute = getattribute != NULL && + getattribute != interp->callable_cache.object__getattribute__; + has_getattr = _PyType_Lookup(type, &_Py_ID(__getattr__)) != NULL; + if (has_custom_getattribute) { + if (getattro_slot == _Py_slot_tp_getattro && + !has_getattr && + Py_IS_TYPE(getattribute, &PyFunction_Type)) { + *descr = getattribute; + return GETATTRIBUTE_IS_PYTHON_FUNCTION; + } + /* Potentially both __getattr__ and __getattribute__ are set. + Too complicated */ + *descr = NULL; + return GETSET_OVERRIDDEN; + } + /* Potentially has __getattr__ but no custom __getattribute__. + Fall through to usual descriptor analysis. + Usual attribute lookup should only be allowed at runtime + if we can guarantee that there is no way an exception can be + raised. This means some specializations, e.g. specializing + for property() isn't safe. + */ + } + else { *descr = NULL; return GETSET_OVERRIDDEN; } @@ -595,7 +638,10 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto return OTHER_SLOT; } if (desc_cls == &PyProperty_Type) { - return PROPERTY; + /* We can't detect at runtime whether an attribute exists + with property. So that means we may have to call + __getattr__. */ + return has_getattr ? GETSET_OVERRIDDEN : PROPERTY; } if (PyUnicode_CompareWithASCIIString(name, "__class__") == 0) { if (descriptor == _PyType_Lookup(&PyBaseObject_Type, name)) { @@ -674,7 +720,6 @@ specialize_dict_access( static int specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, PyObject* descr, DescriptorClassification kind); static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name); -static int function_kind(PyCodeObject *code); int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) @@ -729,24 +774,13 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); goto fail; } - if (Py_TYPE(fget) != &PyFunction_Type) { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY); + if (!Py_IS_TYPE(fget, &PyFunction_Type)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION); goto fail; } - PyFunctionObject *func = (PyFunctionObject *)fget; - PyCodeObject *fcode = (PyCodeObject *)func->func_code; - int kind = function_kind(fcode); - if (kind != SIMPLE_FUNCTION) { - SPECIALIZATION_FAIL(LOAD_ATTR, kind); - goto fail; - } - if (fcode->co_argcount != 1) { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); - goto fail; - } - int version = _PyFunction_GetVersionForCurrentState(func); + uint32_t version = function_check_args(fget, 1, LOAD_ATTR) && + function_get_version(fget, LOAD_ATTR); if (version == 0) { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } write_u32(lm_cache->keys_version, version); @@ -795,6 +829,22 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) case GETSET_OVERRIDDEN: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; + case GETATTRIBUTE_IS_PYTHON_FUNCTION: + { + assert(type->tp_getattro == _Py_slot_tp_getattro); + assert(Py_IS_TYPE(descr, &PyFunction_Type)); + _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1); + uint32_t func_version = function_check_args(descr, 2, LOAD_ATTR) && + function_get_version(descr, LOAD_ATTR); + if (func_version == 0) { + goto fail; + } + /* borrowed */ + write_obj(lm_cache->descr, descr); + write_u32(lm_cache->type_version, type->tp_version_tag); + _Py_SET_OPCODE(*instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); + goto success; + } case BUILTIN_CLASSMETHOD: case PYTHON_CLASSMETHOD: case NON_OVERRIDING: @@ -873,6 +923,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) case MUTABLE: SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS); goto fail; + case GETATTRIBUTE_IS_PYTHON_FUNCTION: case GETSET_OVERRIDDEN: SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; @@ -1215,6 +1266,39 @@ function_kind(PyCodeObject *code) { return SIMPLE_FUNCTION; } +/* Returning false indicates a failure. */ +static bool +function_check_args(PyObject *o, int expected_argcount, int opcode) +{ + assert(Py_IS_TYPE(o, &PyFunction_Type)); + PyFunctionObject *func = (PyFunctionObject *)o; + PyCodeObject *fcode = (PyCodeObject *)func->func_code; + int kind = function_kind(fcode); + if (kind != SIMPLE_FUNCTION) { + SPECIALIZATION_FAIL(opcode, kind); + return false; + } + if (fcode->co_argcount != expected_argcount) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + return false; + } + return true; +} + +/* Returning 0 indicates a failure. */ +static uint32_t +function_get_version(PyObject *o, int opcode) +{ + assert(Py_IS_TYPE(o, &PyFunction_Type)); + PyFunctionObject *func = (PyFunctionObject *)o; + uint32_t version = _PyFunction_GetVersionForCurrentState(func); + if (version == 0) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); + return 0; + } + return version; +} + int _Py_Specialize_BinarySubscr( PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) From webhook-mailer at python.org Wed Aug 17 07:49:04 2022 From: webhook-mailer at python.org (encukou) Date: Wed, 17 Aug 2022 11:49:04 -0000 Subject: [Python-checkins] gh-95991: Add some infrastructure for testing Limited API in _testcapi (GH-95992) Message-ID: <mailman.699.1660736944.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0f2b469ce1a6f123ad9e151b1771651b3e1d2de6 commit: 0f2b469ce1a6f123ad9e151b1771651b3e1d2de6 branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-17T13:48:43+02:00 summary: gh-95991: Add some infrastructure for testing Limited API in _testcapi (GH-95992) - Limited API needs to be enabled per source file - Some builds don't support Limited API, so Limited API tests must be skipped on those builds (currently this is `Py_TRACE_REFS`, but that may change.) - `Py_LIMITED_API` must be defined before `<Python.h>` is included. This puts the hoop-jumping in `testcapi/parts.h`, so individual test files can be relatively simple. (Currently that's only `vectorcall_limited.c`, imagine more.) files: M Doc/library/test.rst M Lib/test/support/__init__.py M Lib/test/test_call.py M Modules/_testcapi/parts.h M Modules/_testcapi/vectorcall_limited.c M Modules/_testcapimodule.c M PCbuild/_testcapi.vcxproj diff --git a/Doc/library/test.rst b/Doc/library/test.rst index e255952d4570..f3bc7e7560a6 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -794,6 +794,12 @@ The :mod:`test.support` module defines the following functions: Decorator for only running the test if :data:`HAVE_DOCSTRINGS`. +.. decorator:: requires_limited_api + + Decorator for only running the test if :ref:`Limited C API <stable>` + is available. + + .. decorator:: cpython_only Decorator for tests only applicable to CPython. diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index c51a1f26f29a..2409fb05d728 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -46,6 +46,7 @@ "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", + "requires_limited_api", # sys "is_jython", "is_android", "is_emscripten", "is_wasi", "check_impl_detail", "unix_shell", "setswitchinterval", @@ -1069,6 +1070,15 @@ def refcount_test(test): return no_tracing(cpython_only(test)) +def requires_limited_api(test): + try: + import _testcapi + except ImportError: + return unittest.skip('needs _testcapi module')(test) + return unittest.skipUnless( + _testcapi.LIMITED_API_AVAILABLE, 'needs Limited API support')(test) + + def _filter_suite(suite, pred): """Recursively filter test cases in a suite based on a predicate.""" newtests = [] diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 131b45e6caaa..c00de27b265d 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,5 +1,5 @@ import unittest -from test.support import cpython_only +from test.support import cpython_only, requires_limited_api try: import _testcapi except ImportError: @@ -760,9 +760,7 @@ def __call__(self, *args): self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) - @unittest.skipIf( - hasattr(sys, 'getobjects'), - "Limited API is not compatible with Py_TRACE_REFS") + @requires_limited_api def test_vectorcall_limited(self): from _testcapi import pyobject_vectorcall obj = _testcapi.LimitedVectorCallClass() diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index a76ddd93c0ef..304e5922c0d5 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -1,9 +1,36 @@ -#include "Python.h" +#ifndef Py_TESTCAPI_PARTS_H +#define Py_TESTCAPI_PARTS_H + +#include "pyconfig.h" // for Py_TRACE_REFS + +// Figure out if Limited API is available for this build. If it isn't we won't +// build tests for it. +// Currently, only Py_TRACE_REFS disables Limited API. +#ifdef Py_TRACE_REFS +#undef LIMITED_API_AVAILABLE +#else +#define LIMITED_API_AVAILABLE 1 +#endif -/* Always enable assertions */ +// Always enable assertions #undef NDEBUG +#if !defined(LIMITED_API_AVAILABLE) && defined(Py_LIMITED_API) +// Limited API being unavailable means that with Py_LIMITED_API defined +// we can't even include Python.h. +// Do nothing; the .c file that defined Py_LIMITED_API should also do nothing. + +#else + +#include "Python.h" + int _PyTestCapi_Init_Vectorcall(PyObject *module); -int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_Heaptype(PyObject *module); int _PyTestCapi_Init_Unicode(PyObject *module); + +#ifdef LIMITED_API_AVAILABLE +int _PyTestCapi_Init_VectorcallLimited(PyObject *module); +#endif // LIMITED_API_AVAILABLE + +#endif +#endif // Py_TESTCAPI_PARTS_H diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c index c5184318e292..ee57af84b1bb 100644 --- a/Modules/_testcapi/vectorcall_limited.c +++ b/Modules/_testcapi/vectorcall_limited.c @@ -1,18 +1,8 @@ -#include "pyconfig.h" // Py_TRACE_REFS - -#ifdef Py_TRACE_REFS - -// Py_TRACE_REFS is incompatible with Limited API +#define Py_LIMITED_API 0x030c0000 // 3.12 #include "parts.h" -int -_PyTestCapi_Init_VectorcallLimited(PyObject *m) { - return 0; -} -#else +#ifdef LIMITED_API_AVAILABLE -#define Py_LIMITED_API 0x030c0000 // 3.12 -#include "parts.h" #include "structmember.h" // PyMemberDef /* Test Vectorcall in the limited API */ @@ -89,4 +79,4 @@ _PyTestCapi_Init_VectorcallLimited(PyObject *m) { return 0; } -#endif // Py_TRACE_REFS +#endif // LIMITED_API_AVAILABLE diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8d9a0c15b1b0..2d4c73cfe970 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6544,9 +6544,6 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Vectorcall(m) < 0) { return NULL; } - if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { - return NULL; - } if (_PyTestCapi_Init_Heaptype(m) < 0) { return NULL; } @@ -6554,6 +6551,15 @@ PyInit__testcapi(void) return NULL; } +#ifndef LIMITED_API_AVAILABLE + PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False); +#else + PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_True); + if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { + return NULL; + } +#endif + PyState_AddModule(m, &_testcapimodule); return m; } diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index 23bb5ec85274..b7d40c8cdc30 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -107,6 +107,10 @@ <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> </ProjectReference> + <ProjectReference Include="python3dll.vcxproj"> + <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> From webhook-mailer at python.org Wed Aug 17 07:50:58 2022 From: webhook-mailer at python.org (markshannon) Date: Wed, 17 Aug 2022 11:50:58 -0000 Subject: [Python-checkins] GH-95589: Dont crash when subclassing extension classes with multiple inheritance (GH-96028) Message-ID: <mailman.700.1660737058.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b73e3b6d4a6c505f2869ae4d0a4a93241450cf32 commit: b73e3b6d4a6c505f2869ae4d0a4a93241450cf32 branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-17T12:50:53+01:00 summary: GH-95589: Dont crash when subclassing extension classes with multiple inheritance (GH-96028) * Treat tp_weakref and tp_dictoffset like other opaque slots for multiple inheritance. * Document Py_TPFLAGS_MANAGED_DICT and Py_TPFLAGS_MANAGED_WEAKREF in what's new. files: A Misc/NEWS.d/next/C API/2022-08-16-16-54-42.gh-issue-95589.6xE1ar.rst M Doc/whatsnew/3.12.rst M Lib/test/test_capi.py M Objects/typeobject.c diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 5926205ce5c0..9689d9df9dfc 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -450,6 +450,11 @@ New Features inherit the ``Py_TPFLAGS_HAVE_VECTORCALL`` flag. (Contributed by Petr Viktorin in :gh:`93274`.) + The :const:`Py_TPFLAGS_MANAGED_DICT` and :const:`Py_TPFLAGS_MANAGED_WEAKREF` + flags have been added. This allows extensions classes to support object + ``__dict__`` and weakrefs with less bookkeeping, + using less memory and with faster access. + Porting to Python 3.12 ---------------------- @@ -486,6 +491,18 @@ Porting to Python 3.12 :c:func:`PyUnicode_FromFormatV`. (Contributed by Philip Georgi in :gh:`95504`.) +* Extension classes wanting to add a ``__dict__`` or weak reference slot + should use :const:`Py_TPFLAGS_MANAGED_DICT` and + :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead of ``tp_dictoffset`` and + ``tp_weaklistoffset``, respectively. + The use of ``tp_dictoffset`` and ``tp_weaklistoffset`` is still + supported, but does not fully support multiple inheritance + (:gh: `95589`), and performance may be worse. + Classes declaring :const:`Py_TPFLAGS_MANAGED_DICT` should call + :c:func:`_PyObject_VisitManagedDict` and :c:func:`_PyObject_ClearManagedDict` + to traverse and clear their instance's dictionaries. + To clear weakrefs, call :c:func:`PyObject_ClearWeakRefs`, as before. + Deprecated ---------- diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index e6516b33aec0..b698e34dec4e 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -677,21 +677,43 @@ def test_heaptype_with_custom_metaclass(self): def test_multiple_inheritance_ctypes_with_weakref_or_dict(self): - class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + with self.assertRaises(TypeError): + class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + pass + with self.assertRaises(TypeError): + class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + pass + + def test_multiple_inheritance_ctypes_with_weakref_or_dict_and_other_builtin(self): + + with self.assertRaises(TypeError): + class C1(_testcapi.HeapCTypeWithDict, list): + pass + + with self.assertRaises(TypeError): + class C2(_testcapi.HeapCTypeWithWeakref, list): + pass + + class C3(_testcapi.HeapCTypeWithManagedDict, list): pass - class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + class C4(_testcapi.HeapCTypeWithManagedWeakref, list): pass - for cls in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, - _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): - for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, - _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): - if cls is not cls2: - class S(cls, cls2): - pass - class B1(Both1, cls): + inst = C3() + inst.append(0) + str(inst.__dict__) + + inst = C4() + inst.append(0) + str(inst.__weakref__) + + for cls in (_testcapi.HeapCTypeWithManagedDict, _testcapi.HeapCTypeWithManagedWeakref): + for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + class S(cls, cls2): + pass + class B1(C3, cls): pass - class B2(Both1, cls): + class B2(C4, cls): pass def test_pytype_fromspec_with_repeated_slots(self): diff --git a/Misc/NEWS.d/next/C API/2022-08-16-16-54-42.gh-issue-95589.6xE1ar.rst b/Misc/NEWS.d/next/C API/2022-08-16-16-54-42.gh-issue-95589.6xE1ar.rst new file mode 100644 index 000000000000..696e3c80db62 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-08-16-16-54-42.gh-issue-95589.6xE1ar.rst @@ -0,0 +1,4 @@ +Extensions classes that set ``tp_dictoffset`` and ``tp_weaklistoffset`` +lose the support for multiple inheritance, but are now safe. Extension +classes should use :const:`Py_TPFLAGS_MANAGED_DICT` and +:const:`Py_TPFLAGS_MANAGED_WEAKREF` instead. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f796a91b3c27..e8c36cf15399 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2330,36 +2330,13 @@ best_base(PyObject *bases) return base; } -#define ADDED_FIELD_AT_OFFSET(name, offset) \ - (type->tp_ ## name && (base->tp_ ##name == 0) && \ - type->tp_ ## name + sizeof(PyObject *) == (offset) && \ - type->tp_flags & Py_TPFLAGS_HEAPTYPE) - static int -extra_ivars(PyTypeObject *type, PyTypeObject *base) +shape_differs(PyTypeObject *t1, PyTypeObject *t2) { - size_t t_size = type->tp_basicsize; - size_t b_size = base->tp_basicsize; - - assert(t_size >= b_size); /* Else type smaller than base! */ - if (type->tp_itemsize || base->tp_itemsize) { - /* If itemsize is involved, stricter rules */ - return t_size != b_size || - type->tp_itemsize != base->tp_itemsize; - } - /* Check for __dict__ and __weakrefs__ slots in either order */ - if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0 && - ADDED_FIELD_AT_OFFSET(dictoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - /* Check __weakrefs__ again, in case it precedes __dict__ */ - if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - return t_size != b_size; + return ( + t1->tp_basicsize != t2->tp_basicsize || + t1->tp_itemsize != t2->tp_itemsize + ); } static PyTypeObject * @@ -2367,14 +2344,18 @@ solid_base(PyTypeObject *type) { PyTypeObject *base; - if (type->tp_base) + if (type->tp_base) { base = solid_base(type->tp_base); - else + } + else { base = &PyBaseObject_Type; - if (extra_ivars(type, base)) + } + if (shape_differs(type, base)) { return type; - else + } + else { return base; + } } static void object_dealloc(PyObject *); From webhook-mailer at python.org Wed Aug 17 07:59:57 2022 From: webhook-mailer at python.org (markshannon) Date: Wed, 17 Aug 2022 11:59:57 -0000 Subject: [Python-checkins] Correct news entry. (GH-96043) Message-ID: <mailman.701.1660737598.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d8c07f8cb4eebbe4ed0f76ba98024313f76a181c commit: d8c07f8cb4eebbe4ed0f76ba98024313f76a181c branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-17T12:59:44+01:00 summary: Correct news entry. (GH-96043) files: M Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst index 9fc0df5266d..7fc8f6a2d49 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-06-18-17-00-33.gh-issue-93911.y286of.rst @@ -1 +1 @@ -Specialize ``LOAD_ATTR`` for objects with custom ``__getattr__`` and ``__getattribute__``. +Specialize ``LOAD_ATTR`` for objects with custom ``__getattribute__``. From webhook-mailer at python.org Wed Aug 17 13:05:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 17 Aug 2022 17:05:08 -0000 Subject: [Python-checkins] GH-95704: Don't suppress errors from tasks when TG is cancelled (GH-95761) Message-ID: <mailman.702.1660755910.3313.python-checkins@python.org> https://github.com/python/cpython/commit/36c114ab11d478c9ede246035606c12fc080e6ff commit: 36c114ab11d478c9ede246035606c12fc080e6ff branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-17T10:04:59-07:00 summary: GH-95704: Don't suppress errors from tasks when TG is cancelled (GH-95761) When a task catches CancelledError and raises some other error, the other error should not silently be suppressed. Any scenario where a task crashes in cleanup upon cancellation will now result in an ExceptionGroup wrapping the crash(es) instead of propagating CancelledError and ignoring the side errors. NOTE: This represents a change in behavior (hence the need to change several tests). But it is only an edge case. Co-authored-by: Thomas Grainger <tagrain at gmail.com> (cherry picked from commit f51f54f39d384da63be622bcdc9cf4cfb43bad3d) Co-authored-by: Guido van Rossum <guido at python.org> files: A Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst M Lib/asyncio/taskgroups.py M Lib/test/test_asyncio/test_taskgroups.py diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 9be4838e3c7a..5d5e2a8a85dd 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -116,10 +116,9 @@ async def __aexit__(self, et, exc, tb): if self._base_error is not None: raise self._base_error - if propagate_cancellation_error is not None: - # The wrapping task was cancelled; since we're done with - # closing all child tasks, just propagate the cancellation - # request now. + # Propagate CancelledError if there is one, except if there + # are other errors -- those have priority. + if propagate_cancellation_error and not self._errors: raise propagate_cancellation_error if et is not None and et is not exceptions.CancelledError: diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 74bae06af8e7..6a0231f2859a 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -230,29 +230,29 @@ async def runner(): self.assertEqual(NUM, 15) - async def test_cancellation_in_body(self): + async def test_taskgroup_08(self): async def foo(): - await asyncio.sleep(0.1) - 1 / 0 + try: + await asyncio.sleep(10) + finally: + 1 / 0 async def runner(): async with taskgroups.TaskGroup() as g: for _ in range(5): g.create_task(foo()) - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - raise + await asyncio.sleep(10) r = asyncio.create_task(runner()) await asyncio.sleep(0.1) self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError) as cm: + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) async def test_taskgroup_09(self): @@ -316,8 +316,10 @@ async def runner(): async def test_taskgroup_11(self): async def foo(): - await asyncio.sleep(0.1) - 1 / 0 + try: + await asyncio.sleep(10) + finally: + 1 / 0 async def runner(): async with taskgroups.TaskGroup(): @@ -325,24 +327,26 @@ async def runner(): for _ in range(5): g2.create_task(foo()) - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - raise + await asyncio.sleep(10) r = asyncio.create_task(runner()) await asyncio.sleep(0.1) self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError}) + async def test_taskgroup_12(self): async def foo(): - await asyncio.sleep(0.1) - 1 / 0 + try: + await asyncio.sleep(10) + finally: + 1 / 0 async def runner(): async with taskgroups.TaskGroup() as g1: @@ -352,19 +356,19 @@ async def runner(): for _ in range(5): g2.create_task(foo()) - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - raise + await asyncio.sleep(10) r = asyncio.create_task(runner()) await asyncio.sleep(0.1) self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError}) + async def test_taskgroup_13(self): async def crash_after(t): @@ -424,8 +428,9 @@ async def runner(): self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) async def test_taskgroup_16(self): @@ -451,8 +456,9 @@ async def runner(): self.assertFalse(r.done()) r.cancel() - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(ExceptionGroup) as cm: await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) async def test_taskgroup_17(self): NUM = 0 diff --git a/Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst b/Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst new file mode 100644 index 000000000000..31f9fc6547d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-08-01-42-11.gh-issue-95704.MOPFfX.rst @@ -0,0 +1,2 @@ +When a task catches :exc:`asyncio.CancelledError` and raises some other error, +the other error should generally not silently be suppressed. From webhook-mailer at python.org Wed Aug 17 15:55:06 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Wed, 17 Aug 2022 19:55:06 -0000 Subject: [Python-checkins] gh-90110: Get the C Analyzer Tool Working Again (gh-96057) Message-ID: <mailman.703.1660766107.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5aac85101b3b0285770bf5739a94cb26245b9eaf commit: 5aac85101b3b0285770bf5739a94cb26245b9eaf branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-17T13:55:01-06:00 summary: gh-90110: Get the C Analyzer Tool Working Again (gh-96057) We broke it with a recent `_PyArg_Parser` change. Also: * moved the `_PyArg_Parser` whitelist entries over to ignored.tsv now that they are thread-safe * added some known globals from a currently-excluded file * dropped some outdated globals from the whitelist files: M Tools/c-analyzer/cpython/_parser.py M Tools/c-analyzer/cpython/globals-to-fix.tsv M Tools/c-analyzer/cpython/ignored.tsv diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index af223b114941..14ab6198ff25 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -141,6 +141,7 @@ def clean_lines(text): Objects/**/*.c Py_BUILD_CORE 1 Modules/_asynciomodule.c Py_BUILD_CORE 1 +Modules/_codecsmodule.c Py_BUILD_CORE 1 Modules/_collectionsmodule.c Py_BUILD_CORE 1 Modules/_ctypes/_ctypes.c Py_BUILD_CORE 1 Modules/_ctypes/cfield.c Py_BUILD_CORE 1 @@ -293,6 +294,10 @@ def clean_lines(text): ] MAX_SIZES = { + # GLOB: (MAXTEXT, MAXLINES), + # First match wins. + _abs('Include/internal/pycore_global_strings.h'): (5_000, 1000), + _abs('Include/internal/pycore_runtime_init_generated.h'): (5_000, 1000), _abs('Include/**/*.h'): (5_000, 500), _abs('Modules/_ctypes/ctypes.h'): (5_000, 500), _abs('Modules/_datetimemodule.c'): (20_000, 300), diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index c8d23e9db0e1..d760d6012c0e 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -290,7 +290,6 @@ Objects/exceptions.c - PyExc_EncodingWarning - Objects/boolobject.c - _Py_FalseStruct - Objects/boolobject.c - _Py_TrueStruct - Objects/dictobject.c - empty_keys_struct - -Objects/dictobject.c - empty_values_struct - Objects/object.c - _Py_NoneStruct - Objects/object.c - _Py_NotImplementedStruct - Objects/setobject.c - _dummy_struct - @@ -301,96 +300,27 @@ Objects/sliceobject.c - _Py_EllipsisObject - # cached - initialized once # manually cached PyUnicodeObject -# XXX This should have been found by the analyzer but wasn't: Python/ast_unparse.c - _str_replace_inf - -# _PyArg_Parser (holds tuple of strings) -Objects/clinic/bytearrayobject.c.h bytearray___init__ _parser - -Objects/clinic/bytearrayobject.c.h bytearray_decode _parser - -Objects/clinic/bytearrayobject.c.h bytearray_hex _parser - -Objects/clinic/bytearrayobject.c.h bytearray_rsplit _parser - -Objects/clinic/bytearrayobject.c.h bytearray_split _parser - -Objects/clinic/bytearrayobject.c.h bytearray_splitlines _parser - -Objects/clinic/bytearrayobject.c.h bytearray_translate _parser - -Objects/clinic/bytesobject.c.h bytes_decode _parser - -Objects/clinic/bytesobject.c.h bytes_hex _parser - -Objects/clinic/bytesobject.c.h bytes_new _parser - -Objects/clinic/bytesobject.c.h bytes_rsplit _parser - -Objects/clinic/bytesobject.c.h bytes_split _parser - -Objects/clinic/bytesobject.c.h bytes_splitlines _parser - -Objects/clinic/bytesobject.c.h bytes_translate _parser - -Objects/clinic/codeobject.c.h code__varname_from_oparg _parser - -Objects/clinic/codeobject.c.h code_replace _parser - -Objects/clinic/complexobject.c.h complex_new _parser - -Objects/clinic/descrobject.c.h mappingproxy_new _parser - -Objects/clinic/descrobject.c.h property_init _parser - -Objects/clinic/enumobject.c.h enum_new _parser - -Objects/clinic/funcobject.c.h func_new _parser - -Objects/clinic/listobject.c.h list_sort _parser - -Objects/clinic/longobject.c.h int_from_bytes _parser - -Objects/clinic/longobject.c.h int_to_bytes _parser - -Objects/clinic/longobject.c.h long_new _parser - -Objects/clinic/memoryobject.c.h memoryview _parser - -Objects/clinic/memoryobject.c.h memoryview_cast _parser - -Objects/clinic/memoryobject.c.h memoryview_hex _parser - -Objects/clinic/memoryobject.c.h memoryview_tobytes _parser - -Objects/clinic/moduleobject.c.h module___init__ _parser - -Objects/clinic/odictobject.c.h OrderedDict_fromkeys _parser - -Objects/clinic/odictobject.c.h OrderedDict_move_to_end _parser - -Objects/clinic/odictobject.c.h OrderedDict_pop _parser - -Objects/clinic/odictobject.c.h OrderedDict_popitem _parser - -Objects/clinic/odictobject.c.h OrderedDict_setdefault _parser - -Objects/clinic/structseq.c.h structseq_new _parser - -Objects/clinic/unicodeobject.c.h unicode_encode _parser - -Objects/clinic/unicodeobject.c.h unicode_expandtabs _parser - -Objects/clinic/unicodeobject.c.h unicode_new _parser - -Objects/clinic/unicodeobject.c.h unicode_rsplit _parser - -Objects/clinic/unicodeobject.c.h unicode_split _parser - -Objects/clinic/unicodeobject.c.h unicode_splitlines _parser - -Python/clinic/Python-tokenize.c.h tokenizeriter_new _parser - -Python/clinic/_warnings.c.h warnings_warn _parser - -Python/clinic/_warnings.c.h warnings_warn_explicit _parser - -Python/clinic/bltinmodule.c.h builtin___import__ _parser - -Python/clinic/bltinmodule.c.h builtin_compile _parser - -Python/clinic/bltinmodule.c.h builtin_exec _parser - -Python/clinic/bltinmodule.c.h builtin_pow _parser - -Python/clinic/bltinmodule.c.h builtin_print _parser - -Python/clinic/bltinmodule.c.h builtin_round _parser - -Python/clinic/bltinmodule.c.h builtin_sum _parser - -Python/clinic/import.c.h _imp_find_frozen _parser - -Python/clinic/import.c.h _imp_source_hash _parser - -Python/clinic/sysmodule.c.h sys_addaudithook _parser - -Python/clinic/sysmodule.c.h sys_set_coroutine_origin_tracking_depth _parser - -Python/clinic/traceback.c.h tb_new _parser - - # holds strings Objects/typeobject.c - slotdefs - # other -Objects/typeobject.c - method_cache - Objects/typeobject.c object___reduce_ex___impl objreduce - Objects/unicodeobject.c - _string_module - Objects/unicodeobject.c - interned - -Objects/unicodeobject.c - static_strings - #----------------------- # other # initialized once -# XXX This should have been found by the analyzer but wasn't: Python/context.c - _token_missing - -# XXX This should have been found by the analyzer but wasn't: Python/fileutils.c - _Py_open_cloexec_works - -# XXX This should have been found by the analyzer but wasn't: Python/hamt.c - _empty_bitmap_node - -# XXX This should have been found by the analyzer but wasn't: Python/hamt.c - _empty_hamt - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c PyImport_Import silly_list - # state Objects/typeobject.c resolve_slotdups pname - -# XXX This should have been found by the analyzer but wasn't: Python/import.c - extensions - @@ -406,23 +336,43 @@ Modules/getbuildinfo.c Py_GetBuildInfo buildinfo - # during init Objects/typeobject.c - slotdefs_initialized - Objects/unicodeobject.c - bloom_linebreak - -Parser/parser.c - Py_DebugFlag - Python/bootstrap_hash.c - _Py_HashSecret_Initialized - Python/bootstrap_hash.c py_getrandom getrandom_works - +Python/initconfig.c - Py_DebugFlag - +Python/initconfig.c - Py_UTF8Mode - +Python/initconfig.c - Py_DebugFlag - +Python/initconfig.c - Py_VerboseFlag - +Python/initconfig.c - Py_QuietFlag - +Python/initconfig.c - Py_InteractiveFlag - +Python/initconfig.c - Py_InspectFlag - +Python/initconfig.c - Py_OptimizeFlag - +Python/initconfig.c - Py_NoSiteFlag - +Python/initconfig.c - Py_BytesWarningFlag - +Python/initconfig.c - Py_FrozenFlag - +Python/initconfig.c - Py_IgnoreEnvironmentFlag - +Python/initconfig.c - Py_DontWriteBytecodeFlag - +Python/initconfig.c - Py_NoUserSiteDirectory - +Python/initconfig.c - Py_UnbufferedStdioFlag - +Python/initconfig.c - Py_HashRandomizationFlag - +Python/initconfig.c - Py_IsolatedFlag - +Python/initconfig.c - Py_LegacyWindowsFSEncodingFlag - +Python/initconfig.c - Py_LegacyWindowsStdioFlag - +Python/initconfig.c - orig_argv - Python/pyhash.c - _Py_HashSecret - Python/pylifecycle.c - runtime_initialized - Python/sysmodule.c - _PySys_ImplCacheTag - Python/sysmodule.c - _PySys_ImplName - Python/sysmodule.c - _preinit_warnoptions - Python/sysmodule.c - _preinit_xoptions - -Python/thread.c - thread_debug - Python/thread.c - initialized - +# set by embedders during init +Python/initconfig.c - _Py_StandardStreamEncoding - +Python/initconfig.c - _Py_StandardStreamErrors - + # lazy Objects/floatobject.c - double_format - Objects/floatobject.c - float_format - -Objects/floatobject.c - detected_double_format - -Objects/floatobject.c - detected_float_format - Objects/longobject.c PyLong_FromString log_base_BASE - Objects/longobject.c PyLong_FromString convwidth_base - Objects/longobject.c PyLong_FromString convmultmax_base - @@ -431,11 +381,8 @@ Parser/action_helpers.c _PyPegen_dummy_name cache - Python/dtoa.c - p5s - Python/fileutils.c - force_ascii - Python/fileutils.c set_inheritable ioctl_works - -# XXX This should have been found by the analyzer but wasn't: Python/import.c - import_lock - -# XXX This should have been found by the analyzer but wasn't: Python/import.c import_find_and_load header - -Python/specialize.c - _list_append - #----------------------- # unlikely to change after init (or main thread) @@ -501,37 +448,24 @@ Python/getargs.c - static_arg_parsers - # other Objects/dictobject.c - _pydict_global_version - Objects/dictobject.c - next_dict_keys_version - -Objects/dictobject.c - pydict_global_version - Objects/funcobject.c - next_func_version - Objects/moduleobject.c - max_module_number - Objects/object.c - _Py_RefTotal - Objects/typeobject.c - next_version_tag - Objects/typeobject.c resolve_slotdups ptrs - Parser/pegen.c - memo_statistics - -# XXX This should have been found by the analyzer but wasn't: Python/bootstrap_hash.c - urandom_cache - -# XXX This should have been found by the analyzer but wasn't: -Python/ceval.c - lltrace - -# XXX This should have been found by the analyzer but wasn't: Python/ceval.c make_pending_calls busy - Python/ceval.c _PyEval_SetProfile reentrant - Python/ceval.c _PyEval_SetTrace reentrant - -Python/dynload_shlib.c - handles - -Python/dynload_shlib.c - nhandles - -# XXX This should have been found by the analyzer but wasn't: Python/import.c - import_lock_level - -# XXX This should have been found by the analyzer but wasn't: Python/import.c - import_lock_thread - -# XXX This should have been found by the analyzer but wasn't: Python/import.c import_find_and_load accumulated - -# XXX This should have been found by the analyzer but wasn't: Python/import.c import_find_and_load import_level - Python/modsupport.c - _Py_PackageContext - Python/pyfpe.c - PyFPE_counter - Python/pylifecycle.c _Py_FatalErrorFormat reentrant - -# XXX This should have been found by the analyzer but wasn't: Python/pylifecycle.c - _Py_UnhandledKeyboardInterrupt - -# XXX This should have been found by the analyzer but wasn't: Python/pylifecycle.c fatal_error reentrant - Python/specialize.c - _Py_QuickenedCount - @@ -547,10 +481,6 @@ Modules/_collectionsmodule.c - deque_type - Modules/_collectionsmodule.c - dequeiter_type - Modules/_collectionsmodule.c - dequereviter_type - Modules/_collectionsmodule.c - tuplegetter_type - -Modules/_functoolsmodule.c - keyobject_type - -Modules/_functoolsmodule.c - lru_cache_type - -Modules/_functoolsmodule.c - lru_list_elem_type - -Modules/_functoolsmodule.c - partial_type - Modules/_io/bufferedio.c - PyBufferedIOBase_Type - Modules/_io/bufferedio.c - PyBufferedRWPair_Type - Modules/_io/bufferedio.c - PyBufferedRandom_Type - @@ -565,15 +495,12 @@ Modules/_io/stringio.c - PyStringIO_Type - Modules/_io/textio.c - PyIncrementalNewlineDecoder_Type - Modules/_io/textio.c - PyTextIOBase_Type - Modules/_io/textio.c - PyTextIOWrapper_Type - +# XXX This should have been found by the analyzer but wasn't: Modules/_io/winconsoleio.c - PyWindowsConsoleIO_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type - Modules/_testcapi/vectorcall.c - MethodDescriptor2_Type - -Modules/_threadmodule.c - Locktype - -Modules/_threadmodule.c - RLocktype - -Modules/_threadmodule.c - localdummytype - -Modules/_threadmodule.c - localtype - Modules/itertoolsmodule.c - _grouper_type - Modules/itertoolsmodule.c - accumulate_type - Modules/itertoolsmodule.c - chain_type - @@ -596,87 +523,14 @@ Modules/itertoolsmodule.c - tee_type - Modules/itertoolsmodule.c - teedataobject_type - Modules/itertoolsmodule.c - ziplongest_type - -#----------------------- -# non-static types - initialized once - -# structseq types -Modules/_threadmodule.c - ExceptHookArgsType - -Modules/signalmodule.c - SiginfoType - -Modules/timemodule.c - StructTimeType - - -# exception types -Modules/_threadmodule.c - ThreadError - -Modules/signalmodule.c - ItimerError - - -#----------------------- -# cached - initialized once - -# _PyArg_Parser -Modules/clinic/_asynciomodule.c.h _asyncio_Task__check_future _parser - -Modules/clinic/_csv.c.h _csv_unregister_dialect _parser - -Modules/clinic/_csv.c.h _csv_get_dialect _parser - -Modules/clinic/_csv.c.h _csv_field_size_limit _parser - -Modules/clinic/_codecsmodule.c.h _codecs_decode _parser - -Modules/clinic/_codecsmodule.c.h _codecs_encode _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_expand _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_groupdict _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_groups _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_findall _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_finditer _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_fullmatch _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_match _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_scanner _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_search _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_split _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_sub _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_subn _parser - -Modules/clinic/_sre.c.h _sre_SRE_Scanner_match _parser - -Modules/clinic/_sre.c.h _sre_SRE_Scanner_search _parser - -Modules/clinic/_sre.c.h _sre_compile _parser - -Modules/clinic/_winapi.c.h _winapi_LCMapStringEx _parser - -Modules/clinic/arraymodule.c.h array_array_fromfile _parser - -Modules/clinic/arraymodule.c.h array_array_tofile _parser - -Modules/clinic/arraymodule.c.h array_array___reduce_ex__ _parser - -Modules/clinic/gcmodule.c.h gc_collect _parser - -Modules/clinic/gcmodule.c.h gc_get_objects _parser - -Modules/clinic/itertoolsmodule.c.h itertools_accumulate _parser - -Modules/clinic/itertoolsmodule.c.h itertools_combinations _parser - -Modules/clinic/itertoolsmodule.c.h itertools_combinations_with_replacement _parser - -Modules/clinic/itertoolsmodule.c.h itertools_compress _parser - -Modules/clinic/itertoolsmodule.c.h itertools_count _parser - -Modules/clinic/itertoolsmodule.c.h itertools_groupby _parser - -Modules/clinic/itertoolsmodule.c.h itertools_permutations _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_dir _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_file _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_symlink _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_stat _parser - -Modules/clinic/posixmodule.c.h os__exit _parser - -Modules/clinic/posixmodule.c.h os__path_normpath _parser - -Modules/clinic/posixmodule.c.h os_access _parser - -Modules/clinic/posixmodule.c.h os_chdir _parser - -Modules/clinic/posixmodule.c.h os_chmod _parser - -Modules/clinic/posixmodule.c.h os_close _parser - -Modules/clinic/posixmodule.c.h os_device_encoding _parser - -Modules/clinic/posixmodule.c.h os_dup2 _parser - -Modules/clinic/posixmodule.c.h os_fspath _parser - -Modules/clinic/posixmodule.c.h os_fstat _parser - -Modules/clinic/posixmodule.c.h os_listdir _parser - -Modules/clinic/posixmodule.c.h os_lstat _parser - -Modules/clinic/posixmodule.c.h os_mkdir _parser - -Modules/clinic/posixmodule.c.h os_open _parser - -Modules/clinic/posixmodule.c.h os_remove _parser - -Modules/clinic/posixmodule.c.h os_rename _parser - -Modules/clinic/posixmodule.c.h os_replace _parser - -Modules/clinic/posixmodule.c.h os_rmdir _parser - -Modules/clinic/posixmodule.c.h os_scandir _parser - -Modules/clinic/posixmodule.c.h os_stat _parser - -Modules/clinic/posixmodule.c.h os_unlink _parser - -Modules/clinic/posixmodule.c.h os_utime _parser - -Modules/clinic/socketmodule.c.h sock_initobj _parser - - #----------------------- # other +# statically initializd pointer to static type +# XXX should be const? +# XXX This should have been found by the analyzer but wasn't: +Modules/_io/winconsoleio.c - _PyWindowsConsoleIO_Type - + # initialized once Modules/_functoolsmodule.c - kwd_mark - Modules/_io/_iomodule.c - _PyIO_empty_bytes - @@ -701,13 +555,9 @@ Modules/signalmodule.c - Handlers - # initialized once Modules/_io/bufferedio.c _PyIO_trap_eintr eintr_int - -#Modules/cjkcodecs/cjkcodecs.h - codec_list - -#Modules/cjkcodecs/cjkcodecs.h - mapping_list - Modules/posixmodule.c os_dup2_impl dup3_works - Modules/posixmodule.c - structseq_new - Modules/posixmodule.c - ticks_per_second - -Modules/signalmodule.c - initialized - -Modules/timemodule.c - initialized - Modules/timemodule.c _PyTime_GetClockWithInfo initialized - Modules/timemodule.c _PyTime_GetProcessTimeWithInfo ticks_per_second - @@ -734,75 +584,6 @@ Modules/signalmodule.c - wakeup - ################################## # global objects to fix in extension modules -#----------------------- -# modules - -Modules/_asynciomodule.c - _asynciomodule - -Modules/_bisectmodule.c - _bisectmodule - -Modules/_blake2/blake2module.c - blake2_module - -Modules/_bz2module.c - _bz2module - -Modules/_contextvarsmodule.c - _contextvarsmodule - -Modules/_cryptmodule.c - cryptmodule - -Modules/_csv.c - _csvmodule - -Modules/_ctypes/_ctypes.c - _ctypesmodule - -Modules/_curses_panel.c - _curses_panelmodule - -Modules/_cursesmodule.c - _cursesmodule - -Modules/_datetimemodule.c - datetimemodule - -Modules/_decimal/_decimal.c - _decimal_module - -Modules/_elementtree.c - elementtreemodule - -Modules/_gdbmmodule.c - _gdbmmodule - -Modules/_hashopenssl.c - _hashlibmodule - -Modules/_heapqmodule.c - _heapqmodule - -Modules/_json.c - jsonmodule - -Modules/_lsprof.c - _lsprofmodule - -Modules/_lzmamodule.c - _lzmamodule - -Modules/_multiprocessing/multiprocessing.c - multiprocessing_module - -Modules/_multiprocessing/posixshmem.c - this_module - -Modules/_opcode.c - opcodemodule - -Modules/_operator.c - operatormodule - -Modules/_pickle.c - _picklemodule - -Modules/_posixsubprocess.c - _posixsubprocessmodule - -Modules/_queuemodule.c - queuemodule - -Modules/_randommodule.c - _randommodule - -Modules/_sha3/sha3module.c - _sha3module - -Modules/_sqlite/module.c - _sqlite3module - -Modules/_ssl.c - PySocketModule - -Modules/_ssl.c - _sslmodule - -Modules/_statisticsmodule.c - statisticsmodule - -Modules/_struct.c - _structmodule - -Modules/_tkinter.c - _tkintermodule - -Modules/_uuidmodule.c - uuidmodule - -Modules/_xxsubinterpretersmodule.c - interpretersmodule - -Modules/_zoneinfo.c - zoneinfomodule - -Modules/arraymodule.c - arraymodule - -Modules/audioop.c - audioopmodule - -Modules/binascii.c - binasciimodule - -Modules/cjkcodecs/multibytecodec.c - _multibytecodecmodule - -Modules/cmathmodule.c - cmathmodule - -Modules/fcntlmodule.c - fcntlmodule - -Modules/grpmodule.c - grpmodule - -Modules/mathmodule.c - mathmodule - -Modules/md5module.c - _md5module - -Modules/mmapmodule.c - mmapmodule - -Modules/nismodule.c - nismodule - -Modules/ossaudiodev.c - ossaudiodevmodule - -Modules/pyexpat.c - pyexpatmodule - -Modules/readline.c - readlinemodule - -Modules/resource.c - resourcemodule - -Modules/selectmodule.c - selectmodule - -Modules/sha1module.c - _sha1module - -Modules/sha256module.c - _sha256module - -Modules/sha512module.c - _sha512module - -Modules/socketmodule.c - socketmodule - -Modules/spwdmodule.c - spwdmodule - -Modules/syslogmodule.c - syslogmodule - -Modules/termios.c - termiosmodule - -Modules/unicodedata.c - unicodedata_module - -Modules/xxlimited.c - xxmodule - -Modules/xxmodule.c - xxmodule - -Modules/xxsubtype.c - xxsubtypemodule - -Modules/zlibmodule.c - zlibmodule - - #----------------------- # static types @@ -811,9 +592,6 @@ Modules/_asynciomodule.c - FutureType - Modules/_asynciomodule.c - PyRunningLoopHolder_Type - Modules/_asynciomodule.c - TaskStepMethWrapper_Type - Modules/_asynciomodule.c - TaskType - -Modules/_csv.c - Dialect_Type - -Modules/_csv.c - Reader_Type - -Modules/_csv.c - Writer_Type - Modules/_ctypes/_ctypes.c - DictRemover_Type - Modules/_ctypes/_ctypes.c - PyCArrayType_Type - Modules/_ctypes/_ctypes.c - PyCArray_Type - @@ -824,7 +602,6 @@ Modules/_ctypes/_ctypes.c - PyCPointerType_Type - Modules/_ctypes/_ctypes.c - PyCPointer_Type - Modules/_ctypes/_ctypes.c - PyCSimpleType_Type - Modules/_ctypes/_ctypes.c - PyCStructType_Type - -Modules/_ctypes/_ctypes.c - PyComError_Type - Modules/_ctypes/_ctypes.c - Simple_Type - Modules/_ctypes/_ctypes.c - StructParam_Type - Modules/_ctypes/_ctypes.c - Struct_Type - @@ -850,35 +627,16 @@ Modules/_elementtree.c - ElementIter_Type - Modules/_elementtree.c - Element_Type - Modules/_elementtree.c - TreeBuilder_Type - Modules/_elementtree.c - XMLParser_Type - -Modules/_multiprocessing/semaphore.c - _PyMp_SemLockType - Modules/_pickle.c - Pdata_Type - Modules/_pickle.c - PicklerMemoProxyType - Modules/_pickle.c - Pickler_Type - Modules/_pickle.c - UnpicklerMemoProxyType - Modules/_pickle.c - Unpickler_Type - -Modules/_queuemodule.c - PySimpleQueueType - -Modules/_sre.c - Match_Type - -Modules/_sre.c - Pattern_Type - -Modules/_sre.c - Scanner_Type - -Modules/_ssl.c - PySSLContext_Type - -Modules/_ssl.c - PySSLMemoryBIO_Type - -Modules/_ssl.c - PySSLSession_Type - -Modules/_ssl.c - PySSLSocket_Type - Modules/_xxsubinterpretersmodule.c - ChannelIDtype - Modules/_zoneinfo.c - PyZoneInfo_ZoneInfoType - -Modules/arraymodule.c - Arraytype - -Modules/arraymodule.c - PyArrayIter_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteCodec_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteIncrementalDecoder_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteIncrementalEncoder_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteStreamReader_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteStreamWriter_Type - -Modules/mmapmodule.c - mmap_object_type - Modules/ossaudiodev.c - OSSAudioType - Modules/ossaudiodev.c - OSSMixerType - -Modules/pyexpat.c - Xmlparsetype - Modules/socketmodule.c - sock_type - -Modules/xxlimited_35.c - Xxo_Type - Modules/xxmodule.c - Null_Type - Modules/xxmodule.c - Str_Type - Modules/xxmodule.c - Xxo_Type - @@ -888,31 +646,18 @@ Modules/xxsubtype.c - spamlist_type - #----------------------- # non-static types - initialized once -# structseq types -Modules/_cursesmodule.c - NcursesVersionType - -Modules/resource.c - StructRUsageType - -Modules/spwdmodule.c - StructSpwdType - - # heap types Modules/_decimal/_decimal.c - DecimalTuple - Modules/_decimal/_decimal.c - PyDecSignalDict_Type - Modules/_tkinter.c - PyTclObject_Type - Modules/_tkinter.c - Tkapp_Type - Modules/_tkinter.c - Tktt_Type - -Modules/xxlimited.c - Xxo_Type - +Modules/xxlimited_35.c - Xxo_Type - # exception types Modules/_ctypes/_ctypes.c - PyExc_ArgError - Modules/_cursesmodule.c - PyCursesError - Modules/_decimal/_decimal.c - DecimalException - -Modules/_queuemodule.c - EmptyError - -Modules/_ssl.c - PySSLErrorObject - -Modules/_ssl.c - PySSLCertVerificationErrorObject - -Modules/_ssl.c - PySSLZeroReturnErrorObject - -Modules/_ssl.c - PySSLWantReadErrorObject - -Modules/_ssl.c - PySSLWantWriteErrorObject - -Modules/_ssl.c - PySSLSyscallErrorObject - -Modules/_ssl.c - PySSLEOFErrorObject - Modules/_tkinter.c - Tkinter_TclError - Modules/_xxsubinterpretersmodule.c - ChannelError - Modules/_xxsubinterpretersmodule.c - ChannelNotFoundError - @@ -921,11 +666,9 @@ Modules/_xxsubinterpretersmodule.c - ChannelEmptyError - Modules/_xxsubinterpretersmodule.c - ChannelNotEmptyError - Modules/_xxsubinterpretersmodule.c - RunFailedError - Modules/ossaudiodev.c - OSSAudioError - -Modules/pyexpat.c - ErrorObject - Modules/socketmodule.c - socket_herror - Modules/socketmodule.c - socket_gaierror - -Modules/socketmodule.c - socket_timeout - -Modules/xxlimited.c - ErrorObject - +Modules/xxlimited_35.c - ErrorObject - Modules/xxmodule.c - ErrorObject - #----------------------- @@ -934,43 +677,17 @@ Modules/xxmodule.c - ErrorObject - # _Py_IDENTIFIER (global) Modules/_asynciomodule.c - PyId___asyncio_running_event_loop__ - Modules/_asynciomodule.c - PyId__asyncio_future_blocking - -Modules/_asynciomodule.c - PyId__check_future static - Modules/_asynciomodule.c - PyId_add_done_callback - Modules/_asynciomodule.c - PyId_call_soon - Modules/_asynciomodule.c - PyId_cancel - Modules/_asynciomodule.c - PyId_get_event_loop - Modules/_asynciomodule.c - PyId_throw - -Modules/_bisectmodule.c - PyId_insert - Modules/_datetimemodule.c - PyId_as_integer_ratio - Modules/_datetimemodule.c - PyId_fromutc - Modules/_datetimemodule.c - PyId_isoformat - Modules/_datetimemodule.c - PyId_strftime - -Modules/_sqlite/connection.c - PyId_cursor - -Modules/cjkcodecs/multibytecodec.c - PyId_write - -Modules/unicodedata.c - PyId_NFC - -Modules/unicodedata.c - PyId_NFD - -Modules/unicodedata.c - PyId_NFKC - -Modules/unicodedata.c - PyId_NFKD - # _Py_IDENTIFIER (local) -Modules/_json.c _encoded_const PyId_false - -Modules/_json.c _encoded_const PyId_null - -Modules/_json.c _encoded_const PyId_true - -Modules/_json.c encoder_listencode_dict PyId_close_dict - -Modules/_json.c encoder_listencode_dict PyId_empty_dict - -Modules/_json.c encoder_listencode_dict PyId_open_dict - -Modules/_json.c encoder_listencode_list PyId_close_array - -Modules/_json.c encoder_listencode_list PyId_empty_array - -Modules/_json.c encoder_listencode_list PyId_open_array - -Modules/_json.c raise_errmsg PyId_JSONDecodeError - -Modules/_json.c raise_errmsg PyId_decoder - -Modules/_sqlite/connection.c final_callback PyId_finalize - -Modules/_sqlite/connection.c pysqlite_connection_execute_impl PyId_execute - -Modules/_sqlite/connection.c pysqlite_connection_executemany_impl PyId_executemany - -Modules/_sqlite/connection.c pysqlite_connection_executescript PyId_executescript - -Modules/_sqlite/connection.c pysqlite_connection_iterdump_impl PyId__iterdump - -Modules/_sqlite/module.c pysqlite_register_converter_impl PyId_upper - -Modules/pyexpat.c pyexpat_xmlparser_ParseFile_impl PyId_read - Modules/_asynciomodule.c FutureObj_finalize PyId_call_exception_handler - Modules/_asynciomodule.c FutureObj_finalize PyId_exception - Modules/_asynciomodule.c FutureObj_finalize PyId_future - @@ -979,7 +696,6 @@ Modules/_asynciomodule.c FutureObj_finalize PyId_source_traceback - Modules/_asynciomodule.c FutureObj_get_state PyId_CANCELLED - Modules/_asynciomodule.c FutureObj_get_state PyId_FINISHED - Modules/_asynciomodule.c FutureObj_get_state PyId_PENDING - -Modules/_asynciomodule.c FutureObj_repr PyId__repr_info - Modules/_asynciomodule.c TaskObj_finalize PyId_call_exception_handler - Modules/_asynciomodule.c TaskObj_finalize PyId_message - Modules/_asynciomodule.c TaskObj_finalize PyId_source_traceback - @@ -989,7 +705,6 @@ Modules/_asynciomodule.c get_future_loop PyId__loop - Modules/_asynciomodule.c get_future_loop PyId_get_loop - Modules/_asynciomodule.c register_task PyId_add - Modules/_asynciomodule.c unregister_task PyId_discard - -Modules/_csv.c csv_writer PyId_write - Modules/_ctypes/_ctypes.c CDataType_from_param PyId__as_parameter_ - Modules/_ctypes/_ctypes.c PyCArrayType_new PyId__length_ - Modules/_ctypes/_ctypes.c PyCArrayType_new PyId__type_ - @@ -1021,15 +736,12 @@ Modules/_cursesmodule.c _curses_getwin PyId_read - Modules/_cursesmodule.c _curses_window_putwin PyId_write - Modules/_cursesmodule.c update_lines_cols PyId_COLS - Modules/_cursesmodule.c update_lines_cols PyId_LINES - -Modules/_datetimemodule.c build_struct_time PyId_struct_time - Modules/_datetimemodule.c call_tzname PyId_tzname - Modules/_datetimemodule.c date_strftime PyId_timetuple - Modules/_datetimemodule.c date_today PyId_fromtimestamp - Modules/_datetimemodule.c datetime_strptime PyId__strptime_datetime - Modules/_datetimemodule.c make_Zreplacement PyId_replace - -Modules/_datetimemodule.c time_time PyId_time - Modules/_datetimemodule.c tzinfo_reduce PyId___getinitargs__ - -Modules/_datetimemodule.c tzinfo_reduce PyId___getstate__ - Modules/_elementtree.c _elementtree_Element_find_impl PyId_find - Modules/_elementtree.c _elementtree_Element_findall_impl PyId_findall - Modules/_elementtree.c _elementtree_Element_findtext_impl PyId_findtext - @@ -1038,225 +750,27 @@ Modules/_elementtree.c expat_start_doctype_handler PyId_doctype - Modules/_elementtree.c treebuilder_add_subelement PyId_append - Modules/_elementtree.c treebuilder_flush_data PyId_tail - Modules/_elementtree.c treebuilder_flush_data PyId_text - -Modules/_gdbmmodule.c gdbm__exit__ PyId_close - -Modules/_lzmamodule.c build_filter_spec PyId_dict_size - -Modules/_lzmamodule.c build_filter_spec PyId_dist - -Modules/_lzmamodule.c build_filter_spec PyId_id - -Modules/_lzmamodule.c build_filter_spec PyId_lc - -Modules/_lzmamodule.c build_filter_spec PyId_lp - -Modules/_lzmamodule.c build_filter_spec PyId_pb - -Modules/_lzmamodule.c build_filter_spec PyId_start_offset - -Modules/_operator.c methodcaller_reduce PyId_partial - -Modules/_pickle.c _Pickle_InitState PyId_getattr - -Modules/_pickle.c _Pickler_SetOutputStream PyId_write - -Modules/_pickle.c _Unpickler_SetInputStream PyId_peek - -Modules/_pickle.c _Unpickler_SetInputStream PyId_read - -Modules/_pickle.c _Unpickler_SetInputStream PyId_readinto - -Modules/_pickle.c _Unpickler_SetInputStream PyId_readline - -Modules/_pickle.c _pickle_Pickler___init___impl PyId_dispatch_table - -Modules/_pickle.c _pickle_Pickler___init___impl PyId_persistent_id - -Modules/_pickle.c _pickle_Unpickler___init___impl PyId_persistent_load - -Modules/_pickle.c do_append PyId_append - -Modules/_pickle.c do_append PyId_extend - -Modules/_pickle.c dump PyId_reducer_override - -Modules/_pickle.c find_class PyId_find_class - -Modules/_pickle.c get_class PyId___class__ - -Modules/_pickle.c instantiate PyId___getinitargs__ - -Modules/_pickle.c instantiate PyId___new__ - -Modules/_pickle.c load_additems PyId_add - -Modules/_pickle.c load_build PyId___dict__ - -Modules/_pickle.c load_build PyId___setstate__ - -Modules/_pickle.c save PyId___reduce__ - -Modules/_pickle.c save PyId___reduce_ex__ - -Modules/_pickle.c save_bytes PyId_latin1 - -Modules/_pickle.c save_dict PyId_items - -Modules/_pickle.c save_global PyId___name__ - -Modules/_pickle.c save_global PyId___qualname__ - -Modules/_pickle.c save_reduce PyId___name__ - -Modules/_pickle.c save_reduce PyId___new__ - -Modules/_pickle.c save_reduce PyId___newobj__ - -Modules/_pickle.c save_reduce PyId___newobj_ex__ - -Modules/_pickle.c whichmodule PyId___main__ - -Modules/_pickle.c whichmodule PyId___module__ - -Modules/_pickle.c whichmodule PyId_modules - -Modules/_sqlite/connection.c _pysqlite_final_callback PyId_finalize - -Modules/_sqlite/connection.c pysqlite_connection_create_collation PyId_upper - -Modules/_sqlite/connection.c pysqlite_connection_iterdump PyId__iterdump - -Modules/_sqlite/connection.c pysqlite_connection_set_isolation_level PyId_upper - -Modules/_sqlite/cursor.c _pysqlite_get_converter PyId_upper - -Modules/_sqlite/microprotocols.c pysqlite_microprotocols_adapt PyId___adapt__ - -Modules/_sqlite/microprotocols.c pysqlite_microprotocols_adapt PyId___conform__ - -Modules/_sqlite/module.c module_register_converter PyId_upper - -Modules/_ssl.c fill_and_set_sslerror PyId_library - -Modules/_ssl.c fill_and_set_sslerror PyId_reason - -Modules/_ssl.c fill_and_set_sslerror PyId_verify_code - -Modules/_ssl.c fill_and_set_sslerror PyId_verify_message - -Modules/arraymodule.c array_array___reduce_ex__ PyId___dict__ - -Modules/arraymodule.c array_array___reduce_ex__ PyId__array_reconstructor - -Modules/arraymodule.c array_array_fromfile_impl PyId_read - -Modules/arraymodule.c array_array_tofile PyId_write - -Modules/arraymodule.c array_arrayiterator___reduce___impl PyId_iter - -Modules/mathmodule.c math_ceil PyId___ceil__ - -Modules/mathmodule.c math_floor PyId___floor__ - -Modules/mathmodule.c math_trunc PyId___trunc__ - -Modules/mmapmodule.c mmap__exit__method PyId_close - +Modules/_json.c _encoded_const PyId_false - +Modules/_json.c _encoded_const PyId_null - +Modules/_json.c _encoded_const PyId_true - +Modules/_json.c raise_errmsg PyId_JSONDecodeError - +Modules/_json.c raise_errmsg PyId_decoder - Modules/ossaudiodev.c oss_exit PyId_close - -Modules/pyexpat.c pyexpat_xmlparser_ParseFile PyId_read - - -# _Py_static_string -Modules/_pickle.c get_dotted_path PyId_dot - # manually cached PyUnicodeOjbect Modules/_asynciomodule.c - context_kwname - Modules/_ctypes/callproc.c _ctypes_get_errobj error_object_name - Modules/_ctypes/_ctypes.c CreateSwappedType suffix - -Modules/_json.c _encoded_const s_null - -Modules/_json.c _encoded_const s_true - -Modules/_json.c _encoded_const s_false - -Modules/_json.c encoder_listencode_dict open_dict - -Modules/_json.c encoder_listencode_dict close_dict - -Modules/_json.c encoder_listencode_dict empty_dict - -Modules/_json.c encoder_listencode_list open_array - -Modules/_json.c encoder_listencode_list close_array - -Modules/_json.c encoder_listencode_list empty_array - - -# _PyArg_Parser -Modules/clinic/_asynciomodule.c.h _asyncio_Future___init__ _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future_add_done_callback _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future_cancel _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task___init__ _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_cancel _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_get_stack _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_print_stack _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__enter_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__get_event_loop _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__leave_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__register_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__unregister_task _parser - -Modules/clinic/_bisectmodule.c.h _bisect_bisect_left _parser - -Modules/clinic/_bisectmodule.c.h _bisect_bisect_right _parser - -Modules/clinic/_bisectmodule.c.h _bisect_insort_left _parser - -Modules/clinic/_bisectmodule.c.h _bisect_insort_right _parser - -Modules/clinic/_bz2module.c.h _bz2_BZ2Decompressor_decompress _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_bottom _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_hide _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_move _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_replace _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_set_userptr _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_show _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_top _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_userptr _parser - -Modules/clinic/_cursesmodule.c.h _curses_setupterm _parser - -Modules/clinic/_datetimemodule.c.h datetime_datetime_now _parser - -Modules/clinic/_datetimemodule.c.h iso_calendar_date_new _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_get _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_keys _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_setdefault _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_find _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_findall _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_findtext _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_get _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_iter _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_iterfind _parser - -Modules/clinic/_elementtree.c.h _elementtree_TreeBuilder___init__ _parser - -Modules/clinic/_elementtree.c.h _elementtree_XMLParser___init__ _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_firstkey _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_keys _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_nextkey _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_reorganize _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_sync _parser - -Modules/clinic/_hashopenssl.c.h EVP_new _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_HMAC_update _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_hmac_new _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_hmac_singleshot _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_md5 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha1 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha224 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha256 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha384 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha512 _parser - -Modules/clinic/_hashopenssl.c.h pbkdf2_hmac _parser - -Modules/clinic/_lsprof.c.h _lsprof_Profiler_getstats _parser - -Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor___init__ _parser - -Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor_decompress _parser - -Modules/clinic/_opcode.c.h _opcode_stack_effect _parser - -Modules/clinic/_pickle.c.h _pickle_Pickler___init__ _parser - -Modules/clinic/_pickle.c.h _pickle_Unpickler___init__ _parser - -Modules/clinic/_pickle.c.h _pickle_dump _parser - -Modules/clinic/_pickle.c.h _pickle_dumps _parser - -Modules/clinic/_pickle.c.h _pickle_load _parser - -Modules/clinic/_pickle.c.h _pickle_loads _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_get _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_get_nowait _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put_nowait _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_bio _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_socket _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_get_ca_certs _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_load_cert_chain _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_load_verify_locations _parser - -Modules/clinic/_ssl.c.h _ssl__SSLSocket_get_channel_binding _parser - -Modules/clinic/_ssl.c.h _ssl_txt2obj _parser - -Modules/clinic/_struct.c.h Struct___init__ _parser - -Modules/clinic/_struct.c.h Struct_unpack_from _parser - -Modules/clinic/_struct.c.h unpack_from _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_get_count _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_get_defining_module _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_getmodulebydef_bad_def _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_increment_count_clinic _parser - -Modules/clinic/_winapi.c.h _winapi_ConnectNamedPipe _parser - -Modules/clinic/_winapi.c.h _winapi_GetFileType _parser - -Modules/clinic/_winapi.c.h _winapi_ReadFile _parser - -Modules/clinic/_winapi.c.h _winapi_WriteFile _parser - -Modules/clinic/_winapi.c.h _winapi__mimetypes_read_windows_registry _parser - -Modules/clinic/arraymodule.c.h array_array_extend _parser - -Modules/clinic/binascii.c.h binascii_a2b_base64 _parser - -Modules/clinic/binascii.c.h binascii_a2b_qp _parser - -Modules/clinic/binascii.c.h binascii_b2a_base64 _parser - -Modules/clinic/binascii.c.h binascii_b2a_hex _parser - -Modules/clinic/binascii.c.h binascii_b2a_qp _parser - -Modules/clinic/binascii.c.h binascii_b2a_uu _parser - -Modules/clinic/binascii.c.h binascii_hexlify _parser - -Modules/clinic/cmathmodule.c.h cmath_isclose _parser - -Modules/clinic/grpmodule.c.h grp_getgrgid _parser - -Modules/clinic/grpmodule.c.h grp_getgrnam _parser - -Modules/clinic/mathmodule.c.h math_isclose _parser - -Modules/clinic/mathmodule.c.h math_prod _parser - -Modules/clinic/md5module.c.h MD5Type_copy _parser - -Modules/clinic/md5module.c.h _md5_md5 _parser - -Modules/clinic/overlapped.c.h _overlapped_Overlapped _parser - -Modules/clinic/pyexpat.c.h pyexpat_ParserCreate _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ExternalEntityParserCreate _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_Parse _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ParseFile _parser - -Modules/clinic/sha1module.c.h SHA1Type_copy _parser - -Modules/clinic/sha1module.c.h _sha1_sha1 _parser - -Modules/clinic/sha256module.c.h SHA256Type_copy _parser - -Modules/clinic/sha256module.c.h _sha256_sha224 _parser - -Modules/clinic/sha256module.c.h _sha256_sha256 _parser - -Modules/clinic/sha512module.c.h SHA512Type_copy _parser - -Modules/clinic/sha512module.c.h _sha512_sha384 _parser - -Modules/clinic/sha512module.c.h _sha512_sha512 _parser - -Modules/clinic/zlibmodule.c.h zlib_Compress_compress _parser - -Modules/clinic/zlibmodule.c.h zlib_Compress_flush _parser - -Modules/clinic/zlibmodule.c.h zlib_Decompress_decompress _parser - -Modules/clinic/zlibmodule.c.h zlib_Decompress_flush _parser - -Modules/clinic/zlibmodule.c.h zlib_compress _parser - -Modules/clinic/zlibmodule.c.h zlib_compressobj _parser - -Modules/clinic/zlibmodule.c.h zlib_decompress _parser - -Modules/clinic/zlibmodule.c.h zlib_decompressobj _parser - # other - during module init Modules/_asynciomodule.c - asyncio_mod - Modules/_asynciomodule.c - traceback_extract_stack - Modules/_asynciomodule.c - asyncio_future_repr_func - -Modules/_asynciomodule.c - asyncio_future_repr_info_func - Modules/_asynciomodule.c - asyncio_get_event_loop_policy - Modules/_asynciomodule.c - asyncio_iscoroutine_func - Modules/_asynciomodule.c - asyncio_task_get_stack_func - Modules/_asynciomodule.c - asyncio_task_print_stack_func - Modules/_asynciomodule.c - asyncio_task_repr_func - -Modules/_asynciomodule.c - asyncio_task_repr_info_func - Modules/_asynciomodule.c - asyncio_InvalidStateError - Modules/_asynciomodule.c - asyncio_CancelledError - Modules/_zoneinfo.c - io_open - @@ -1280,7 +794,6 @@ Modules/_datetimemodule.c - us_per_hour - Modules/_datetimemodule.c - us_per_day - Modules/_datetimemodule.c - us_per_week - Modules/_datetimemodule.c - seconds_per_day - -Modules/_decimal/_decimal.c PyInit__decimal capsule - Modules/_decimal/_decimal.c - basic_context_template - Modules/_decimal/_decimal.c - current_context_var - Modules/_decimal/_decimal.c - default_context_template - @@ -1288,18 +801,7 @@ Modules/_decimal/_decimal.c - extended_context_template - Modules/_decimal/_decimal.c - round_map - Modules/_decimal/_decimal.c - Rational - Modules/_decimal/_decimal.c - SignalTuple - -Modules/_json.c raise_errmsg JSONDecodeError - -Modules/_sqlite/microprotocols.c - psyco_adapters - -Modules/_sqlite/module.h - _pysqlite_converters - -Modules/_ssl.c - err_codes_to_names - -Modules/_ssl.c - err_names_to_codes - -Modules/_ssl.c - lib_codes_to_names - -# XXX This should have been found by the analyzer but wasn't: -Modules/_ssl.c - _ssl_locks - -Modules/_struct.c - cache - -Modules/arraymodule.c array_array___reduce_ex__ array_reconstructor - Modules/arraymodule.c array_array___reduce_ex___impl array_reconstructor - -Modules/cjkcodecs/cjkcodecs.h getmultibytecodec cofunc - # state Modules/_asynciomodule.c - cached_running_holder - @@ -1317,7 +819,6 @@ Modules/_tkinter.c - trbInCmd - Modules/_zoneinfo.c - TIMEDELTA_CACHE - Modules/_zoneinfo.c - ZONEINFO_WEAK_CACHE - Modules/syslogmodule.c - S_ident_o - -Modules/xxlimited_35.c - ErrorObject - ################################## @@ -1339,32 +840,20 @@ Modules/_cursesmodule.c - initialised - Modules/_cursesmodule.c - initialised_setupterm - Modules/_cursesmodule.c - initialisedcolors - Modules/_cursesmodule.c - screen_encoding - -Modules/_cursesmodule.c PyInit__curses PyCurses_API - -Modules/_datetimemodule.c - CAPI - -Modules/_decimal/_decimal.c PyInit__decimal initialized - Modules/_decimal/_decimal.c - _py_long_multiply - Modules/_decimal/_decimal.c - _py_long_floor_divide - Modules/_decimal/_decimal.c - _py_long_power - Modules/_decimal/_decimal.c - _py_float_abs - Modules/_decimal/_decimal.c - _py_long_bit_length - Modules/_decimal/_decimal.c - _py_float_as_integer_ratio - -Modules/_decimal/_decimal.c - _decimal_api - Modules/_elementtree.c - expat_capi - -Modules/_sqlite/module.h - _pysqlite_enable_callback_tracebacks - -Modules/_sqlite/module.h - pysqlite_BaseTypeAdapted - -Modules/_ssl.c - _ssl_locks_count - Modules/cjkcodecs/cjkcodecs.h - codec_list - Modules/cjkcodecs/cjkcodecs.h - mapping_list - -Modules/getaddrinfo.c - gai_afdl - -Modules/pyexpat.c PyInit_pyexpat capi - Modules/readline.c - libedit_append_replace_history_offset - Modules/readline.c - using_libedit_emulation - Modules/readline.c - libedit_history_start - -Modules/resource.c - initialized - Modules/socketmodule.c - accept4_works - Modules/socketmodule.c - sock_cloexec_works - -Modules/socketmodule.c - PySocketModuleAPI - -Modules/spwdmodule.c - initialized - #----------------------- # state @@ -1398,4 +887,3 @@ Modules/rotatingtree.c - random_stream - Modules/rotatingtree.c - random_value - Modules/socketmodule.c - defaulttimeout - Modules/syslogmodule.c - S_log_open - -Modules/clinic/_asynciomodule.c.h _asyncio_Task__check_future _parser - diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index a395775e8f1b..bc3b37dd7da0 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -2,10 +2,246 @@ filename funcname name reason #??? - somevar ??? ################################## -# ignored by design +# mutable but known to be safe Python/pylifecycle.c - _PyRuntime - +#----------------------- +# _PyArg_Parser (holds tuple of strings) +# XXX The analyzer should ignore these. + +# core +Objects/clinic/bytearrayobject.c.h bytearray___init__ _parser - +Objects/clinic/bytearrayobject.c.h bytearray_decode _parser - +Objects/clinic/bytearrayobject.c.h bytearray_hex _parser - +Objects/clinic/bytearrayobject.c.h bytearray_rsplit _parser - +Objects/clinic/bytearrayobject.c.h bytearray_split _parser - +Objects/clinic/bytearrayobject.c.h bytearray_splitlines _parser - +Objects/clinic/bytearrayobject.c.h bytearray_translate _parser - +Objects/clinic/bytesobject.c.h bytes_decode _parser - +Objects/clinic/bytesobject.c.h bytes_hex _parser - +Objects/clinic/bytesobject.c.h bytes_new _parser - +Objects/clinic/bytesobject.c.h bytes_rsplit _parser - +Objects/clinic/bytesobject.c.h bytes_split _parser - +Objects/clinic/bytesobject.c.h bytes_splitlines _parser - +Objects/clinic/bytesobject.c.h bytes_translate _parser - +Objects/clinic/codeobject.c.h code__varname_from_oparg _parser - +Objects/clinic/codeobject.c.h code_replace _parser - +Objects/clinic/complexobject.c.h complex_new _parser - +Objects/clinic/descrobject.c.h mappingproxy_new _parser - +Objects/clinic/descrobject.c.h property_init _parser - +Objects/clinic/enumobject.c.h enum_new _parser - +Objects/clinic/funcobject.c.h func_new _parser - +Objects/clinic/listobject.c.h list_sort _parser - +Objects/clinic/longobject.c.h int_from_bytes _parser - +Objects/clinic/longobject.c.h int_to_bytes _parser - +Objects/clinic/longobject.c.h long_new _parser - +Objects/clinic/memoryobject.c.h memoryview _parser - +Objects/clinic/memoryobject.c.h memoryview_cast _parser - +Objects/clinic/memoryobject.c.h memoryview_hex _parser - +Objects/clinic/memoryobject.c.h memoryview_tobytes _parser - +Objects/clinic/moduleobject.c.h module___init__ _parser - +Objects/clinic/odictobject.c.h OrderedDict_fromkeys _parser - +Objects/clinic/odictobject.c.h OrderedDict_move_to_end _parser - +Objects/clinic/odictobject.c.h OrderedDict_pop _parser - +Objects/clinic/odictobject.c.h OrderedDict_popitem _parser - +Objects/clinic/odictobject.c.h OrderedDict_setdefault _parser - +Objects/clinic/structseq.c.h structseq_new _parser - +Objects/clinic/unicodeobject.c.h unicode_encode _parser - +Objects/clinic/unicodeobject.c.h unicode_expandtabs _parser - +Objects/clinic/unicodeobject.c.h unicode_new _parser - +Objects/clinic/unicodeobject.c.h unicode_rsplit _parser - +Objects/clinic/unicodeobject.c.h unicode_split _parser - +Objects/clinic/unicodeobject.c.h unicode_splitlines _parser - +Python/clinic/Python-tokenize.c.h tokenizeriter_new _parser - +Python/clinic/_warnings.c.h warnings_warn _parser - +Python/clinic/_warnings.c.h warnings_warn_explicit _parser - +Python/clinic/bltinmodule.c.h builtin___import__ _parser - +Python/clinic/bltinmodule.c.h builtin_compile _parser - +Python/clinic/bltinmodule.c.h builtin_exec _parser - +Python/clinic/bltinmodule.c.h builtin_pow _parser - +Python/clinic/bltinmodule.c.h builtin_print _parser - +Python/clinic/bltinmodule.c.h builtin_round _parser - +Python/clinic/bltinmodule.c.h builtin_sum _parser - +Python/clinic/import.c.h _imp_find_frozen _parser - +Python/clinic/import.c.h _imp_source_hash _parser - +Python/clinic/sysmodule.c.h sys_addaudithook _parser - +Python/clinic/sysmodule.c.h sys_set_coroutine_origin_tracking_depth _parser - +Python/clinic/traceback.c.h tb_new _parser - + +# builtin modules +Modules/clinic/_codecsmodule.c.h _codecs_decode _parser - +Modules/clinic/_codecsmodule.c.h _codecs_encode _parser - +Modules/clinic/_sre.c.h _sre_SRE_Match_expand _parser - +Modules/clinic/_sre.c.h _sre_SRE_Match_groupdict _parser - +Modules/clinic/_sre.c.h _sre_SRE_Match_groups _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_findall _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_finditer _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_fullmatch _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_match _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_scanner _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_search _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_split _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_sub _parser - +Modules/clinic/_sre.c.h _sre_SRE_Pattern_subn _parser - +Modules/clinic/_sre.c.h _sre_SRE_Scanner_match _parser - +Modules/clinic/_sre.c.h _sre_SRE_Scanner_search _parser - +Modules/clinic/_sre.c.h _sre_compile _parser - +Modules/clinic/gcmodule.c.h gc_collect _parser - +Modules/clinic/gcmodule.c.h gc_get_objects _parser - +Modules/clinic/itertoolsmodule.c.h itertools_accumulate _parser - +Modules/clinic/itertoolsmodule.c.h itertools_combinations _parser - +Modules/clinic/itertoolsmodule.c.h itertools_combinations_with_replacement _parser - +Modules/clinic/itertoolsmodule.c.h itertools_compress _parser - +Modules/clinic/itertoolsmodule.c.h itertools_count _parser - +Modules/clinic/itertoolsmodule.c.h itertools_groupby _parser - +Modules/clinic/itertoolsmodule.c.h itertools_permutations _parser - +Modules/clinic/posixmodule.c.h os_DirEntry_is_dir _parser - +Modules/clinic/posixmodule.c.h os_DirEntry_is_file _parser - +Modules/clinic/posixmodule.c.h os_DirEntry_is_symlink _parser - +Modules/clinic/posixmodule.c.h os_DirEntry_stat _parser - +Modules/clinic/posixmodule.c.h os__exit _parser - +Modules/clinic/posixmodule.c.h os__path_normpath _parser - +Modules/clinic/posixmodule.c.h os_access _parser - +Modules/clinic/posixmodule.c.h os_chdir _parser - +Modules/clinic/posixmodule.c.h os_chmod _parser - +Modules/clinic/posixmodule.c.h os_close _parser - +Modules/clinic/posixmodule.c.h os_device_encoding _parser - +Modules/clinic/posixmodule.c.h os_dup2 _parser - +Modules/clinic/posixmodule.c.h os_fspath _parser - +Modules/clinic/posixmodule.c.h os_fstat _parser - +Modules/clinic/posixmodule.c.h os_listdir _parser - +Modules/clinic/posixmodule.c.h os_lstat _parser - +Modules/clinic/posixmodule.c.h os_mkdir _parser - +Modules/clinic/posixmodule.c.h os_open _parser - +Modules/clinic/posixmodule.c.h os_remove _parser - +Modules/clinic/posixmodule.c.h os_rename _parser - +Modules/clinic/posixmodule.c.h os_replace _parser - +Modules/clinic/posixmodule.c.h os_rmdir _parser - +Modules/clinic/posixmodule.c.h os_scandir _parser - +Modules/clinic/posixmodule.c.h os_stat _parser - +Modules/clinic/posixmodule.c.h os_unlink _parser - +Modules/clinic/posixmodule.c.h os_utime _parser - + +# extension modules +Modules/clinic/_asynciomodule.c.h _asyncio_Task__check_future _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Future___init__ _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Future_add_done_callback _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Future_cancel _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Task___init__ _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Task_cancel _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Task_get_stack _parser - +Modules/clinic/_asynciomodule.c.h _asyncio_Task_print_stack _parser - +Modules/clinic/_asynciomodule.c.h _asyncio__enter_task _parser - +Modules/clinic/_asynciomodule.c.h _asyncio__get_event_loop _parser - +Modules/clinic/_asynciomodule.c.h _asyncio__leave_task _parser - +Modules/clinic/_asynciomodule.c.h _asyncio__register_task _parser - +Modules/clinic/_asynciomodule.c.h _asyncio__unregister_task _parser - +Modules/clinic/_bisectmodule.c.h _bisect_bisect_left _parser - +Modules/clinic/_bisectmodule.c.h _bisect_bisect_right _parser - +Modules/clinic/_bisectmodule.c.h _bisect_insort_left _parser - +Modules/clinic/_bisectmodule.c.h _bisect_insort_right _parser - +Modules/clinic/_bz2module.c.h _bz2_BZ2Decompressor_decompress _parser - +Modules/clinic/_csv.c.h _csv_unregister_dialect _parser - +Modules/clinic/_csv.c.h _csv_get_dialect _parser - +Modules/clinic/_csv.c.h _csv_field_size_limit _parser - +Modules/clinic/_curses_panel.c.h _curses_panel_panel_move _parser - +Modules/clinic/_curses_panel.c.h _curses_panel_panel_replace _parser - +Modules/clinic/_curses_panel.c.h _curses_panel_panel_set_userptr _parser - +Modules/clinic/_cursesmodule.c.h _curses_setupterm _parser - +Modules/clinic/_datetimemodule.c.h datetime_datetime_now _parser - +Modules/clinic/_datetimemodule.c.h iso_calendar_date_new _parser - +Modules/clinic/_dbmmodule.c.h _dbm_dbm_get _parser - +Modules/clinic/_dbmmodule.c.h _dbm_dbm_setdefault _parser - +Modules/clinic/_elementtree.c.h _elementtree_Element_find _parser - +Modules/clinic/_elementtree.c.h _elementtree_Element_findall _parser - +Modules/clinic/_elementtree.c.h _elementtree_Element_findtext _parser - +Modules/clinic/_elementtree.c.h _elementtree_Element_get _parser - +Modules/clinic/_elementtree.c.h _elementtree_Element_iter _parser - +Modules/clinic/_elementtree.c.h _elementtree_Element_iterfind _parser - +Modules/clinic/_elementtree.c.h _elementtree_TreeBuilder___init__ _parser - +Modules/clinic/_elementtree.c.h _elementtree_XMLParser___init__ _parser - +Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_nextkey _parser - +Modules/clinic/_hashopenssl.c.h EVP_new _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_HMAC_update _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_hmac_new _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_hmac_singleshot _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_openssl_md5 _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha1 _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha224 _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha256 _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha384 _parser - +Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha512 _parser - +Modules/clinic/_hashopenssl.c.h pbkdf2_hmac _parser - +Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor___init__ _parser - +Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor_decompress _parser - +Modules/clinic/_opcode.c.h _opcode_stack_effect _parser - +Modules/clinic/_pickle.c.h _pickle_Pickler___init__ _parser - +Modules/clinic/_pickle.c.h _pickle_Unpickler___init__ _parser - +Modules/clinic/_pickle.c.h _pickle_dump _parser - +Modules/clinic/_pickle.c.h _pickle_dumps _parser - +Modules/clinic/_pickle.c.h _pickle_load _parser - +Modules/clinic/_pickle.c.h _pickle_loads _parser - +Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_get _parser - +Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put _parser - +Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put_nowait _parser - +Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_bio _parser - +Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_socket _parser - +Modules/clinic/_ssl.c.h _ssl__SSLContext_get_ca_certs _parser - +Modules/clinic/_ssl.c.h _ssl__SSLContext_load_cert_chain _parser - +Modules/clinic/_ssl.c.h _ssl__SSLContext_load_verify_locations _parser - +Modules/clinic/_ssl.c.h _ssl__SSLSocket_get_channel_binding _parser - +Modules/clinic/_ssl.c.h _ssl_txt2obj _parser - +Modules/clinic/_struct.c.h Struct___init__ _parser - +Modules/clinic/_struct.c.h Struct_unpack_from _parser - +Modules/clinic/_struct.c.h unpack_from _parser - +Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_increment_count_clinic _parser - +Modules/clinic/_winapi.c.h _winapi_ConnectNamedPipe _parser - +Modules/clinic/_winapi.c.h _winapi_GetFileType _parser - +Modules/clinic/_winapi.c.h _winapi_LCMapStringEx _parser - +Modules/clinic/_winapi.c.h _winapi_ReadFile _parser - +Modules/clinic/_winapi.c.h _winapi_WriteFile _parser - +Modules/clinic/_winapi.c.h _winapi__mimetypes_read_windows_registry _parser - +Modules/clinic/arraymodule.c.h array_array_extend _parser - +Modules/clinic/arraymodule.c.h array_array_fromfile _parser - +Modules/clinic/arraymodule.c.h array_array_tofile _parser - +Modules/clinic/arraymodule.c.h array_array___reduce_ex__ _parser - +Modules/clinic/binascii.c.h binascii_a2b_base64 _parser - +Modules/clinic/binascii.c.h binascii_a2b_qp _parser - +Modules/clinic/binascii.c.h binascii_b2a_base64 _parser - +Modules/clinic/binascii.c.h binascii_b2a_hex _parser - +Modules/clinic/binascii.c.h binascii_b2a_qp _parser - +Modules/clinic/binascii.c.h binascii_b2a_uu _parser - +Modules/clinic/binascii.c.h binascii_hexlify _parser - +Modules/clinic/cmathmodule.c.h cmath_isclose _parser - +Modules/clinic/grpmodule.c.h grp_getgrgid _parser - +Modules/clinic/grpmodule.c.h grp_getgrnam _parser - +Modules/clinic/mathmodule.c.h math_isclose _parser - +Modules/clinic/mathmodule.c.h math_prod _parser - +Modules/clinic/md5module.c.h _md5_md5 _parser - +Modules/clinic/overlapped.c.h _overlapped_Overlapped _parser - +Modules/clinic/pyexpat.c.h pyexpat_ParserCreate _parser - +Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ExternalEntityParserCreate _parser - +Modules/clinic/pyexpat.c.h pyexpat_xmlparser_Parse _parser - +Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ParseFile _parser - +Modules/clinic/sha1module.c.h _sha1_sha1 _parser - +Modules/clinic/sha256module.c.h _sha256_sha224 _parser - +Modules/clinic/sha256module.c.h _sha256_sha256 _parser - +Modules/clinic/sha512module.c.h _sha512_sha384 _parser - +Modules/clinic/sha512module.c.h _sha512_sha512 _parser - +Modules/clinic/socketmodule.c.h sock_initobj _parser - +Modules/clinic/zlibmodule.c.h zlib_Compress_compress _parser - +Modules/clinic/zlibmodule.c.h zlib_Compress_flush _parser - +Modules/clinic/zlibmodule.c.h zlib_Decompress_decompress _parser - +Modules/clinic/zlibmodule.c.h zlib_Decompress_flush _parser - +Modules/clinic/zlibmodule.c.h zlib_compress _parser - +Modules/clinic/zlibmodule.c.h zlib_compressobj _parser - +Modules/clinic/zlibmodule.c.h zlib_decompress _parser - +Modules/clinic/zlibmodule.c.h zlib_decompressobj _parser - + +#----------------------- +# others + ################################## # forward/extern references @@ -407,6 +643,7 @@ Python/sysmodule.c sys_set_asyncgen_hooks keywords - #----------------------- # PyModuleDef +# builtin modules Modules/_abc.c - _abcmodule - Modules/_codecsmodule.c - codecsmodule - Modules/_collectionsmodule.c - _collectionsmodule - @@ -444,6 +681,71 @@ Python/import.c - imp_module - Python/marshal.c - marshalmodule - Python/sysmodule.c - sysmodule - +# extension modules +Modules/_asynciomodule.c - _asynciomodule - +Modules/_bisectmodule.c - _bisectmodule - +Modules/_blake2/blake2module.c - blake2_module - +Modules/_bz2module.c - _bz2module - +Modules/_contextvarsmodule.c - _contextvarsmodule - +Modules/_cryptmodule.c - cryptmodule - +Modules/_csv.c - _csvmodule - +Modules/_ctypes/_ctypes.c - _ctypesmodule - +Modules/_curses_panel.c - _curses_panelmodule - +Modules/_cursesmodule.c - _cursesmodule - +Modules/_datetimemodule.c - datetimemodule - +Modules/_decimal/_decimal.c - _decimal_module - +Modules/_elementtree.c - elementtreemodule - +Modules/_gdbmmodule.c - _gdbmmodule - +Modules/_hashopenssl.c - _hashlibmodule - +Modules/_heapqmodule.c - _heapqmodule - +Modules/_json.c - jsonmodule - +Modules/_lsprof.c - _lsprofmodule - +Modules/_lzmamodule.c - _lzmamodule - +Modules/_multiprocessing/multiprocessing.c - multiprocessing_module - +Modules/_opcode.c - opcodemodule - +Modules/_operator.c - operatormodule - +Modules/_pickle.c - _picklemodule - +Modules/_posixsubprocess.c - _posixsubprocessmodule - +Modules/_queuemodule.c - queuemodule - +Modules/_randommodule.c - _randommodule - +Modules/_sha3/sha3module.c - _sha3module - +Modules/_sqlite/module.c - _sqlite3module - +Modules/_statisticsmodule.c - statisticsmodule - +Modules/_struct.c - _structmodule - +Modules/_testcapi/unicode.c - _testcapimodule - +Modules/_tkinter.c - _tkintermodule - +Modules/_uuidmodule.c - uuidmodule - +Modules/_xxsubinterpretersmodule.c - interpretersmodule - +Modules/_zoneinfo.c - zoneinfomodule - +Modules/arraymodule.c - arraymodule - +Modules/audioop.c - audioopmodule - +Modules/binascii.c - binasciimodule - +Modules/cjkcodecs/multibytecodec.c - _multibytecodecmodule - +Modules/cmathmodule.c - cmathmodule - +Modules/fcntlmodule.c - fcntlmodule - +Modules/grpmodule.c - grpmodule - +Modules/mathmodule.c - mathmodule - +Modules/md5module.c - _md5module - +Modules/mmapmodule.c - mmapmodule - +Modules/nismodule.c - nismodule - +Modules/ossaudiodev.c - ossaudiodevmodule - +Modules/pyexpat.c - pyexpatmodule - +Modules/readline.c - readlinemodule - +Modules/resource.c - resourcemodule - +Modules/selectmodule.c - selectmodule - +Modules/sha1module.c - _sha1module - +Modules/sha256module.c - _sha256module - +Modules/sha512module.c - _sha512module - +Modules/socketmodule.c - socketmodule - +Modules/spwdmodule.c - spwdmodule - +Modules/syslogmodule.c - syslogmodule - +Modules/termios.c - termiosmodule - +Modules/unicodedata.c - unicodedata_module - +Modules/xxlimited.c - xxmodule - +Modules/xxmodule.c - xxmodule - +Modules/xxsubtype.c - xxsubtypemodule - +Modules/zlibmodule.c - zlibmodule - + #----------------------- # PyModuleDef_Slot @@ -648,14 +950,14 @@ Modules/_sqlite/connection.c - connection_methods - Modules/_sqlite/cursor.c - cursor_methods - Modules/_sqlite/module.c - module_methods - Modules/_sqlite/row.c - row_methods - -Modules/_sre/sre.c - _functions - -Modules/_sre/sre.c - pattern_methods - -Modules/_sre/sre.c - match_methods - -Modules/_sre/sre.c - scanner_methods - Modules/_sre.c - _functions - Modules/_sre.c - match_methods - Modules/_sre.c - pattern_methods - Modules/_sre.c - scanner_methods - +Modules/_sre/sre.c - _functions - +Modules/_sre/sre.c - match_methods - +Modules/_sre/sre.c - pattern_methods - +Modules/_sre/sre.c - scanner_methods - Modules/_ssl.c - PySSLMethods - Modules/_ssl.c - PySSL_methods - Modules/_ssl.c - context_methods - @@ -667,7 +969,10 @@ Modules/_struct.c - module_functions - Modules/_struct.c - s_methods - Modules/_struct.c - unpackiter_methods - Modules/_testcapi/heaptype.c - TestMethods - +Modules/_testcapi/unicode.c - TestMethods - Modules/_testcapi/vectorcall.c - TestMethods - +Modules/_testcapi/vectorcall.c - VectorCallClass_methods - +Modules/_testcapi/vectorcall_limited.c - TestMethods - Modules/_threadmodule.c - lock_methods - Modules/_threadmodule.c - rlock_methods - Modules/_threadmodule.c - thread_methods - @@ -806,8 +1111,8 @@ Objects/exceptions.c - OSError_methods - Objects/fileobject.c - stdprinter_methods - Objects/floatobject.c - float_methods - Objects/frameobject.c - frame_methods - -Objects/genericaliasobject.c - ga_methods - Objects/genericaliasobject.c - ga_iter_methods - +Objects/genericaliasobject.c - ga_methods - Objects/genobject.c - async_gen_asend_methods - Objects/genobject.c - async_gen_athrow_methods - Objects/genobject.c - async_gen_methods - @@ -866,8 +1171,8 @@ Python/context.c - PyContextTokenType_methods - Python/context.c - PyContextVar_methods - Python/context.c - PyContext_methods - Python/hamt.c - PyHamt_methods - -Python/import.c - imp_slots - Python/import.c - imp_methods - +Python/import.c - imp_slots - Python/marshal.c - marshal_methods - Python/sysmodule.c - sys_methods - Python/traceback.c - tb_methods - @@ -906,12 +1211,12 @@ Modules/_sqlite/blob.c - blob_members - Modules/_sqlite/connection.c - connection_members - Modules/_sqlite/cursor.c - cursor_members - Modules/_sqlite/statement.c - stmt_members - -Modules/_sre/sre.c - match_members - -Modules/_sre/sre.c - pattern_members - -Modules/_sre/sre.c - scanner_members - Modules/_sre.c - match_members - Modules/_sre.c - pattern_members - Modules/_sre.c - scanner_members - +Modules/_sre/sre.c - match_members - +Modules/_sre/sre.c - pattern_members - +Modules/_sre/sre.c - scanner_members - Modules/_struct.c - s_members - Modules/_testcapi/heaptype.c - heapctype_members - Modules/_testcapi/heaptype.c - heapctypesetattr_members - @@ -920,6 +1225,8 @@ Modules/_testcapi/heaptype.c - heapctypewithdict_members - Modules/_testcapi/heaptype.c - heapctypewithnegativedict_members - Modules/_testcapi/heaptype.c - heapctypewithweakref_members - Modules/_testcapi/heaptype.c - members_to_repeat - +Modules/_testcapi/vectorcall.c - VectorCallClass_members - +Modules/_testcapi/vectorcall_limited.c - LimitedVectorCallClass_members - Modules/_threadmodule.c - local_dummy_type_members - Modules/_threadmodule.c - local_type_members - Modules/_threadmodule.c - lock_type_members - @@ -1244,12 +1551,12 @@ Modules/_sqlite/cursor.c - cursor_slots - Modules/_sqlite/prepare_protocol.c - type_slots - Modules/_sqlite/row.c - row_slots - Modules/_sqlite/statement.c - stmt_slots - -Modules/_sre/sre.c - match_slots - -Modules/_sre/sre.c - pattern_slots - -Modules/_sre/sre.c - scanner_slots - Modules/_sre.c - match_slots - Modules/_sre.c - pattern_slots - Modules/_sre.c - scanner_slots - +Modules/_sre/sre.c - match_slots - +Modules/_sre/sre.c - pattern_slots - +Modules/_sre/sre.c - scanner_slots - Modules/_ssl.c - PySSLContext_slots - Modules/_ssl.c - PySSLMemoryBIO_slots - Modules/_ssl.c - PySSLSession_slots - @@ -1274,6 +1581,8 @@ Modules/_testcapi/heaptype.c - NullTpDocType_slots - Modules/_testcapi/heaptype.c - empty_type_slots - Modules/_testcapi/heaptype.c - repeated_doc_slots - Modules/_testcapi/heaptype.c - repeated_members_slots - +Modules/_testcapi/vectorcall.c - VectorCallClass_slots - +Modules/_testcapi/vectorcall_limited.c - LimitedVectorallClass_slots - Modules/_testcapimodule.c - HeapTypeNameType_slots - Modules/_testcapimodule.c - NullTpDocType_slots - Modules/_threadmodule.c - local_dummy_type_slots - @@ -1363,12 +1672,12 @@ Modules/_sqlite/cursor.c - cursor_spec - Modules/_sqlite/prepare_protocol.c - type_spec - Modules/_sqlite/row.c - row_spec - Modules/_sqlite/statement.c - stmt_spec - -Modules/_sre/sre.c - pattern_spec - -Modules/_sre/sre.c - match_spec - -Modules/_sre/sre.c - scanner_spec - Modules/_sre.c - match_spec - Modules/_sre.c - pattern_spec - Modules/_sre.c - scanner_spec - +Modules/_sre/sre.c - match_spec - +Modules/_sre/sre.c - pattern_spec - +Modules/_sre/sre.c - scanner_spec - Modules/_ssl.c - PySSLContext_spec - Modules/_ssl.c - PySSLMemoryBIO_spec - Modules/_ssl.c - PySSLSession_spec - @@ -1377,25 +1686,26 @@ Modules/_ssl.c - sslerror_type_spec - Modules/_ssl/cert.c - PySSLCertificate_spec - Modules/_struct.c - PyStructType_spec - Modules/_struct.c - unpackiter_type_spec - -Modules/_testcapi/heaptype.c - MinimalMetaclass_spec - -Modules/_testcapi/heaptype.c - MinimalType_spec - -Modules/_testcapi/heaptype.c - repeated_doc_slots_spec - -Modules/_testcapi/heaptype.c - repeated_members_slots_spec - -Modules/_testcapi/heaptype.c - HeapDocCType_spec - -Modules/_testcapi/heaptype.c - NullTpDocType_spec - -Modules/_testcapi/heaptype.c - HeapGcCType_spec - -Modules/_testcapi/heaptype.c - HeapCType_spec - +Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_spec - +Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_spec - +Modules/_testcapi/heaptype.c - HeapCTypeSetattr_spec - +Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_spec - Modules/_testcapi/heaptype.c - HeapCTypeSubclass_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithBuffer_spec - -Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_spec - -Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_spec - -Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithDict_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithDict2_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithDict_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithNegativeDict_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_spec - Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref2_spec - -Modules/_testcapi/heaptype.c - HeapCTypeSetattr_spec - +Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_spec - +Modules/_testcapi/heaptype.c - HeapCType_spec - +Modules/_testcapi/heaptype.c - HeapDocCType_spec - +Modules/_testcapi/heaptype.c - HeapGcCType_spec - +Modules/_testcapi/heaptype.c - MinimalMetaclass_spec - +Modules/_testcapi/heaptype.c - MinimalType_spec - +Modules/_testcapi/heaptype.c - NullTpDocType_spec - +Modules/_testcapi/heaptype.c - repeated_doc_slots_spec - +Modules/_testcapi/heaptype.c - repeated_members_slots_spec - +Modules/_testcapi/vectorcall_limited.c - LimitedVectorCallClass_spec - Modules/_testcapimodule.c - HeapTypeNameType_Spec - Modules/_testcapimodule.c - NullTpDocType_spec - Modules/_threadmodule.c - local_dummy_type_spec - @@ -1603,6 +1913,7 @@ Python/ast_opt.c fold_unaryop ops - Python/codecs.c - Py_hexdigits - Python/codecs.c - ucnhash_capi - Python/codecs.c _PyCodecRegistry_Init methods - +Python/compile.c - NO_LABEL - Python/compile.c - NO_LOCATION - Python/dynload_shlib.c - _PyImport_DynLoadFiletab - Python/dynload_stub.c - _PyImport_DynLoadFiletab - From webhook-mailer at python.org Wed Aug 17 18:55:18 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Wed, 17 Aug 2022 22:55:18 -0000 Subject: [Python-checkins] gh-90110: Update the c-analyzer Tool (gh-96058) Message-ID: <mailman.704.1660776919.3313.python-checkins@python.org> https://github.com/python/cpython/commit/586fc02be5b3e103bfddd49654034a898a8d6dfc commit: 586fc02be5b3e103bfddd49654034a898a8d6dfc branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-17T16:54:59-06:00 summary: gh-90110: Update the c-analyzer Tool (gh-96058) files: M Tools/c-analyzer/c_parser/info.py M Tools/c-analyzer/c_parser/parser/_common.py M Tools/c-analyzer/cpython/_parser.py M Tools/c-analyzer/cpython/ignored.tsv diff --git a/Tools/c-analyzer/c_parser/info.py b/Tools/c-analyzer/c_parser/info.py index a1d349dc0b0d..e9783ccc9535 100644 --- a/Tools/c-analyzer/c_parser/info.py +++ b/Tools/c-analyzer/c_parser/info.py @@ -385,6 +385,9 @@ def get_parsed_vartype(decl): elif isinstance(decl, Variable): storage = decl.storage typequal, typespec, abstract = decl.vartype + elif isinstance(decl, Signature): + storage = None + typequal, typespec, abstract = decl.returntype elif isinstance(decl, Function): storage = decl.storage typequal, typespec, abstract = decl.signature.returntype @@ -1012,6 +1015,18 @@ def __str__(self): def returns(self): return self.returntype + @property + def typequal(self): + return self.returntype.typequal + + @property + def typespec(self): + return self.returntype.typespec + + @property + def abstract(self): + return self.returntype.abstract + class Function(Declaration): kind = KIND.FUNCTION @@ -1106,9 +1121,16 @@ class TypeDef(TypeDeclaration): def _resolve_data(cls, data): if not data: raise NotImplementedError(data) - vartype = dict(data) - del vartype['storage'] - return VarType(**vartype), None + kwargs = dict(data) + del kwargs['storage'] + if 'returntype' in kwargs: + vartype = kwargs['returntype'] + del vartype['storage'] + kwargs['returntype'] = VarType(**vartype) + datacls = Signature + else: + datacls = VarType + return datacls(**kwargs), None @classmethod def _raw_data(self, data): diff --git a/Tools/c-analyzer/c_parser/parser/_common.py b/Tools/c-analyzer/c_parser/parser/_common.py index 40c36039f3f4..d468d5442a93 100644 --- a/Tools/c-analyzer/c_parser/parser/_common.py +++ b/Tools/c-analyzer/c_parser/parser/_common.py @@ -9,7 +9,11 @@ def log_match(group, m): from . import _logger - _logger.debug(f'matched <{group}> ({m.group(0)})') + text = m.group(0) + if text.startswith(('(', ')')) or text.endswith(('(', ')')): + _logger.debug(f'matched <{group}> ({text!r})') + else: + _logger.debug(f'matched <{group}> ({text})') ############################# diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index 14ab6198ff25..992d2e5a7c3d 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -86,8 +86,6 @@ def clean_lines(text): # generated Python/deepfreeze/*.c Python/frozen_modules/*.h -Python/opcode_targets.h -Python/stdlib_module_names.h # @end=conf@ ''') @@ -109,9 +107,7 @@ def clean_lines(text): Modules/_dbmmodule.c Modules/cjkcodecs/_codecs_*.c -Modules/expat/xmlrole.c Modules/expat/xmlparse.c -Python/initconfig.c ''') INCL_DIRS = clean_lines(''' @@ -308,8 +304,12 @@ def clean_lines(text): _abs('Objects/stringlib/unicode_format.h'): (10_000, 400), _abs('Objects/typeobject.c'): (20_000, 200), _abs('Python/compile.c'): (20_000, 500), + _abs('Python/deepfreeze/*.c'): (20_000, 500), + _abs('Python/frozen_modules/*.h'): (20_000, 500), _abs('Python/pylifecycle.c'): (500_000, 5000), _abs('Python/pystate.c'): (500_000, 5000), + _abs('Python/opcode_targets.h'): (10_000, 500), + _abs('Python/stdlib_module_names.h'): (5_000, 500), } diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index bc3b37dd7da0..04c540f8864d 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -307,6 +307,58 @@ Objects/object.c - _PyLineIterator - Objects/object.c - _PyPositionsIterator - Python/importdl.h - _PyImport_DynLoadFiletab - +Modules/expat/xmlrole.c - prolog0 - +Modules/expat/xmlrole.c - prolog1 - +Modules/expat/xmlrole.c - prolog2 - +Modules/expat/xmlrole.c - doctype0 - +Modules/expat/xmlrole.c - doctype1 - +Modules/expat/xmlrole.c - doctype2 - +Modules/expat/xmlrole.c - doctype3 - +Modules/expat/xmlrole.c - doctype4 - +Modules/expat/xmlrole.c - doctype5 - +Modules/expat/xmlrole.c - internalSubset - +Modules/expat/xmlrole.c - entity0 - +Modules/expat/xmlrole.c - entity1 - +Modules/expat/xmlrole.c - entity2 - +Modules/expat/xmlrole.c - entity3 - +Modules/expat/xmlrole.c - entity4 - +Modules/expat/xmlrole.c - entity5 - +Modules/expat/xmlrole.c - entity6 - +Modules/expat/xmlrole.c - entity7 - +Modules/expat/xmlrole.c - entity8 - +Modules/expat/xmlrole.c - entity9 - +Modules/expat/xmlrole.c - entity10 - +Modules/expat/xmlrole.c - notation0 - +Modules/expat/xmlrole.c - notation1 - +Modules/expat/xmlrole.c - notation2 - +Modules/expat/xmlrole.c - notation3 - +Modules/expat/xmlrole.c - notation4 - +Modules/expat/xmlrole.c - attlist0 - +Modules/expat/xmlrole.c - attlist1 - +Modules/expat/xmlrole.c - attlist2 - +Modules/expat/xmlrole.c - attlist3 - +Modules/expat/xmlrole.c - attlist4 - +Modules/expat/xmlrole.c - attlist5 - +Modules/expat/xmlrole.c - attlist6 - +Modules/expat/xmlrole.c - attlist7 - +Modules/expat/xmlrole.c - attlist8 - +Modules/expat/xmlrole.c - attlist9 - +Modules/expat/xmlrole.c - element0 - +Modules/expat/xmlrole.c - element1 - +Modules/expat/xmlrole.c - element2 - +Modules/expat/xmlrole.c - element3 - +Modules/expat/xmlrole.c - element4 - +Modules/expat/xmlrole.c - element5 - +Modules/expat/xmlrole.c - element6 - +Modules/expat/xmlrole.c - element7 - +Modules/expat/xmlrole.c - externalSubset0 - +Modules/expat/xmlrole.c - externalSubset1 - +Modules/expat/xmlrole.c - condSect0 - +Modules/expat/xmlrole.c - condSect1 - +Modules/expat/xmlrole.c - condSect2 - +Modules/expat/xmlrole.c - declClose - +Modules/expat/xmlrole.c - error - + ################################## # test code @@ -1933,4 +1985,5 @@ Python/specialize.c - adaptive_opcodes - Python/specialize.c - cache_requirements - Python/specialize.c - compare_masks - Python/specialize.c - _PyOpcode_Adaptive - +Python/stdlib_module_names.h - _Py_stdlib_module_names - Python/sysmodule.c - whatstrings - From webhook-mailer at python.org Thu Aug 18 05:19:30 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 18 Aug 2022 09:19:30 -0000 Subject: [Python-checkins] Remove dead code in _PyDict_GetItemHint and rename to _PyDict_LookupIndex (GH-95948) Message-ID: <mailman.705.1660814371.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4a6fa894650cfd08da172b798a745961d4d0f398 commit: 4a6fa894650cfd08da172b798a745961d4d0f398 branch: main author: Matthias G?rgens <matthias.goergens at gmail.com> committer: markshannon <mark at hotpy.org> date: 2022-08-18T10:19:21+01:00 summary: Remove dead code in _PyDict_GetItemHint and rename to _PyDict_LookupIndex (GH-95948) files: M Include/internal/pycore_dict.h M Objects/dictobject.c M Python/specialize.c diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index c831c4ccbd0..5370106d529 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -62,7 +62,7 @@ extern Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); */ extern Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); -extern Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **); +extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *); extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key); extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index d8203486d76..0cb95d52360 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1686,50 +1686,12 @@ PyDict_GetItem(PyObject *op, PyObject *key) } Py_ssize_t -_PyDict_GetItemHint(PyDictObject *mp, PyObject *key, - Py_ssize_t hint, PyObject **value) +_PyDict_LookupIndex(PyDictObject *mp, PyObject *key) { - assert(*value == NULL); + PyObject *value; assert(PyDict_CheckExact((PyObject*)mp)); assert(PyUnicode_CheckExact(key)); - if (hint >= 0 && hint < mp->ma_keys->dk_nentries) { - PyObject *res = NULL; - - if (DK_IS_UNICODE(mp->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - } - Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyObject_Hash(key); @@ -1738,7 +1700,7 @@ _PyDict_GetItemHint(PyDictObject *mp, PyObject *key, } } - return _Py_dict_lookup(mp, key, hash, value); + return _Py_dict_lookup(mp, key, hash, &value); } /* Same as PyDict_GetItemWithError() but with hash supplied by caller. diff --git a/Python/specialize.c b/Python/specialize.c index 2dc7495ec79..8a2f9054cad 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -511,7 +511,6 @@ specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, { _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyModuleObject *m = (PyModuleObject *)owner; - PyObject *value = NULL; assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); PyDictObject *dict = (PyDictObject *)m->md_dict; if (dict == NULL) { @@ -522,14 +521,13 @@ specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, SPECIALIZATION_FAIL(opcode, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); return -1; } - Py_ssize_t index = _PyDict_GetItemHint(dict, &_Py_ID(__getattr__), -1, - &value); + Py_ssize_t index = _PyDict_LookupIndex(dict, &_Py_ID(__getattr__)); assert(index != DKIX_ERROR); if (index != DKIX_EMPTY) { SPECIALIZATION_FAIL(opcode, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND); return -1; } - index = _PyDict_GetItemHint(dict, name, -1, &value); + index = _PyDict_LookupIndex(dict, name); assert (index != DKIX_ERROR); if (index != (uint16_t)index) { SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_RANGE); @@ -703,14 +701,13 @@ specialize_dict_access( return 0; } // We found an instance with a __dict__. - PyObject *value = NULL; - Py_ssize_t hint = - _PyDict_GetItemHint(dict, name, -1, &value); - if (hint != (uint16_t)hint) { + Py_ssize_t index = + _PyDict_LookupIndex(dict, name); + if (index != (uint16_t)index) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); return 0; } - cache->index = (uint16_t)hint; + cache->index = (uint16_t)index; write_u32(cache->version, type->tp_version_tag); _Py_SET_OPCODE(*instr, hint_op); } From webhook-mailer at python.org Thu Aug 18 06:16:44 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 18 Aug 2022 10:16:44 -0000 Subject: [Python-checkins] gh-95913: make the new internal classes pdb.ModuleTarget/ScriptTarget private (GH-96053) Message-ID: <mailman.706.1660817805.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1a720c600391f4076097f2ab667e9521c8e521fa commit: 1a720c600391f4076097f2ab667e9521c8e521fa branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-18T11:16:07+01:00 summary: gh-95913: make the new internal classes pdb.ModuleTarget/ScriptTarget private (GH-96053) files: M Lib/pdb.py M Lib/test/test_pyclbr.py diff --git a/Lib/pdb.py b/Lib/pdb.py index e6ed814acbe..b0acb1f571d 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -131,7 +131,7 @@ def __repr__(self): return self -class ScriptTarget(str): +class _ScriptTarget(str): def __new__(cls, val): # Mutate self to be the "real path". res = super().__new__(cls, os.path.realpath(val)) @@ -167,7 +167,7 @@ def code(self): return f"exec(compile({fp.read()!r}, {self!r}, 'exec'))" -class ModuleTarget(str): +class _ModuleTarget(str): def check(self): try: self._details @@ -1625,7 +1625,7 @@ def lookupmodule(self, filename): return fullname return None - def _run(self, target: Union[ModuleTarget, ScriptTarget]): + def _run(self, target: Union[_ModuleTarget, _ScriptTarget]): # When bdb sets tracing, a number of call and line events happen # BEFORE debugger even reaches user's code (and the exact sequence of # events depends on python version). Take special measures to @@ -1789,7 +1789,7 @@ def main(): commands = [optarg for opt, optarg in opts if opt in ['-c', '--command']] module_indicated = any(opt in ['-m'] for opt, optarg in opts) - cls = ModuleTarget if module_indicated else ScriptTarget + cls = _ModuleTarget if module_indicated else _ScriptTarget target = cls(args[0]) target.check() diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index b2de4e8397d..23453e34015 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -229,7 +229,7 @@ def test_others(self): cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties - ignore=('Union', 'ModuleTarget', 'ScriptTarget'), + ignore=('Union', '_ModuleTarget', '_ScriptTarget'), ) cm('pydoc', ignore=('input', 'output',)) # properties From webhook-mailer at python.org Thu Aug 18 06:37:52 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 18 Aug 2022 10:37:52 -0000 Subject: [Python-checkins] gh-95913: Add traceback module additions to what's new in 3.11 (GH-95980) Message-ID: <mailman.707.1660819073.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c5bc67b2a17d9053be9d0079eb7de948626d33c3 commit: c5bc67b2a17d9053be9d0079eb7de948626d33c3 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-18T11:37:41+01:00 summary: gh-95913: Add traceback module additions to what's new in 3.11 (GH-95980) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 3832fdfbe82..27a038292f9 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -825,6 +825,20 @@ time it had a resolution of 1 millisecond (10\ :sup:`-3` seconds). (Contributed by Benjamin Sz?ke, Dong-hee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) + +traceback +--------- + +* Add :func:`traceback.StackSummary.format_frame_summary` to allow users + to override which frames appear in the traceback, and how they are + formatted. + (Contributed by Ammar Askar in :issue:`44569`.) + +* Add :func:`traceback.TracebackException.print`, which prints the + formatted :exc:`~traceback.TracebackException` instance to a file. + (Contributed by Irit Katriel in :issue:`33809`.) + + typing ------ From webhook-mailer at python.org Thu Aug 18 07:16:52 2022 From: webhook-mailer at python.org (ezio-melotti) Date: Thu, 18 Aug 2022 11:16:52 -0000 Subject: [Python-checkins] gh-95813: Improve HTMLParser from the view of inheritance (#95874) Message-ID: <mailman.708.1660821414.3313.python-checkins@python.org> https://github.com/python/cpython/commit/157aef79b07e07bf115e49cdf5ff25e74c66354e commit: 157aef79b07e07bf115e49cdf5ff25e74c66354e branch: main author: Dong-hee Na <donghee.na at python.org> committer: ezio-melotti <ezio.melotti at gmail.com> date: 2022-08-18T13:16:33+02:00 summary: gh-95813: Improve HTMLParser from the view of inheritance (#95874) * gh-95813: Improve HTMLParser from the view of inheritance * gh-95813: Add unittest * Address code review files: M Lib/html/parser.py M Lib/test/test_htmlparser.py diff --git a/Lib/html/parser.py b/Lib/html/parser.py index bef0f4fe4bf7..13c95c34e505 100644 --- a/Lib/html/parser.py +++ b/Lib/html/parser.py @@ -89,6 +89,7 @@ def __init__(self, *, convert_charrefs=True): If convert_charrefs is True (the default), all character references are automatically converted to the corresponding Unicode characters. """ + super().__init__() self.convert_charrefs = convert_charrefs self.reset() @@ -98,7 +99,7 @@ def reset(self): self.lasttag = '???' self.interesting = interesting_normal self.cdata_elem = None - _markupbase.ParserBase.reset(self) + super().reset() def feed(self, data): r"""Feed data to the parser. diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index 12917755a560..b42a611c62c0 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -4,6 +4,8 @@ import pprint import unittest +from unittest.mock import patch + class EventCollector(html.parser.HTMLParser): @@ -787,5 +789,17 @@ def test_weird_chars_in_unquoted_attribute_values(self): ('starttag', 'form', [('action', 'bogus|&#()value')])]) + +class TestInheritance(unittest.TestCase): + + @patch("_markupbase.ParserBase.__init__") + @patch("_markupbase.ParserBase.reset") + def test_base_class_methods_called(self, super_reset_method, super_init_method): + with patch('_markupbase.ParserBase') as parser_base: + EventCollector() + super_init_method.assert_called_once() + super_reset_method.assert_called_once() + + if __name__ == "__main__": unittest.main() From webhook-mailer at python.org Thu Aug 18 09:32:42 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 18 Aug 2022 13:32:42 -0000 Subject: [Python-checkins] gh-95957: Add instructions for Tcl/Tk and OpenSSL on RHEL/CentOS 7 (GH-95964) Message-ID: <mailman.709.1660829563.3313.python-checkins@python.org> https://github.com/python/cpython/commit/504da3ce8025a94c14d31cc8df74fb801852a7be commit: 504da3ce8025a94c14d31cc8df74fb801852a7be branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T06:32:30-07:00 summary: gh-95957: Add instructions for Tcl/Tk and OpenSSL on RHEL/CentOS 7 (GH-95964) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> (cherry picked from commit ab4d72954f3c3fe4bdf51dc6a9cf0ed38f210a68) Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst A Misc/rhel7/README.md A Misc/rhel7/openssl.pc A Misc/rhel7/tcl.pc A Misc/rhel7/tk.pc M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 2fd8ee31f859..cda9e97d8981 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1631,16 +1631,23 @@ Build Changes * Build dependencies, compiler flags, and linker flags for most stdlib extension modules are now detected by :program:`configure`. libffi, libnsl, - libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk libs, and uuid flags - are detected by ``pkg-config`` (when available). + libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk, and uuid flags + are detected by ``pkg-config`` (when available). :mod:`tkinter` now + requires ``pkg-config`` command to detect development settings for Tcl/Tk + headers and libraries. (Contributed by Christian Heimes and Erlend Egeberg Aasland in :issue:`45847`, :issue:`45747`, and :issue:`45763`.) .. note:: - Use the environment variables ``TCLTK_CFLAGS`` and ``TCLTK_LIBS`` to - manually specify the location of Tcl/Tk headers and libraries. - The :program:`configure` options ``--with-tcltk-includes`` and - ``--with-tcltk-libs`` have been removed. + Use the environment variables :envvar:`TCLTK_CFLAGS` and + :envvar:`TCLTK_LIBS` to manually specify the location of Tcl/Tk headers + and libraries. The :program:`configure` options ``--with-tcltk-includes`` + and ``--with-tcltk-libs`` have been removed. + + On RHEL 7 and CentOS 7 the development packages do not provide ``tcl.pc`` + and ``tk.pc``, use :envvar:`TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5"`. + The directory ``Misc/rhel7`` contains ``.pc`` files and instructions + how to build Python with RHEL 7's and CentOS 7's Tcl/Tk and OpenSSL. * CPython now has :pep:`11` tier 3 support for cross compiling to WebAssembly platform ``wasm32-unknown-emscripten`` (Python in the browser). The effort diff --git a/Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst b/Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst new file mode 100644 index 000000000000..c617bd42abd9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-13-20-34-51.gh-issue-95957.W9ZZAx.rst @@ -0,0 +1,2 @@ +What's New 3.11 now has instructions for how to provide compiler and +linker flags for Tcl/Tk and OpenSSL on RHEL 7 and CentOS 7. diff --git a/Misc/rhel7/README.md b/Misc/rhel7/README.md new file mode 100644 index 000000000000..8642e7c678f2 --- /dev/null +++ b/Misc/rhel7/README.md @@ -0,0 +1,19 @@ +# pkg-config overrides for RHEL 7 and CentOS 7 + +RHEL 7 and CentOS 7 do not provide pkg-config `.pc` files for Tcl/Tk. The + OpenSSL 1.1.1 pkg-config file is named `openssl11.pc` and not picked up + by Python's `configure` script. + +To build Python with system Tcl/Tk libs and OpenSSL 1.1 package, first +install the developer packages and the `pkgconfig` package with `pkg-config` +command. + +```shell +sudo yum install pkgconfig 'tcl-devel >= 8.5.12' 'tk-devel >= 8.5.12' openssl11-devel +``` + +The run `configure` with `PKG_CONFIG_PATH` environment variable. + +```shell +PKG_CONFIG_PATH=Misc/rhel7 ./configure -C +``` diff --git a/Misc/rhel7/openssl.pc b/Misc/rhel7/openssl.pc new file mode 100644 index 000000000000..ffccd36cc30d --- /dev/null +++ b/Misc/rhel7/openssl.pc @@ -0,0 +1,3 @@ +Name: OpenSSL +Version: 1.1.1k +Requires: libssl11 libcrypto11 diff --git a/Misc/rhel7/tcl.pc b/Misc/rhel7/tcl.pc new file mode 100644 index 000000000000..922eb5126403 --- /dev/null +++ b/Misc/rhel7/tcl.pc @@ -0,0 +1,4 @@ +Name: Tool Command Language +Version: 8.5.12 +Libs: -ltcl8.5 -ltclstub8.5 +# Libs.private: -ldl -lz -lpthread -lm diff --git a/Misc/rhel7/tk.pc b/Misc/rhel7/tk.pc new file mode 100644 index 000000000000..67cebb27f791 --- /dev/null +++ b/Misc/rhel7/tk.pc @@ -0,0 +1,5 @@ +Name: The Tk Toolkit +Version: 8.5.12 +Requires: tcl >= 8.5.12 +Libs: -ltk8.5 -ltkstub8.5 +# Libs.private: -lXft -lfontconfig -lfreetype -lfontconfig -lX11 From webhook-mailer at python.org Thu Aug 18 09:33:21 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 18 Aug 2022 13:33:21 -0000 Subject: [Python-checkins] gh-95913: Add traceback module additions to what's new in 3.11 (GH-95980) (GH-96064) Message-ID: <mailman.710.1660829601.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7c334a3382acedec903b58d9b2c63fecd82f3748 commit: 7c334a3382acedec903b58d9b2c63fecd82f3748 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-18T14:33:15+01:00 summary: gh-95913: Add traceback module additions to what's new in 3.11 (GH-95980) (GH-96064) (cherry picked from commit c5bc67b2a17d9053be9d0079eb7de948626d33c3) Co-authored-by: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> Co-authored-by: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index cda9e97d898..92c66ebf2f8 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -808,6 +808,20 @@ time it had a resolution of 1 millisecond (10\ :sup:`-3` seconds). (Contributed by Benjamin Sz?ke, Dong-hee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) + +traceback +--------- + +* Add :func:`traceback.StackSummary.format_frame_summary` to allow users + to override which frames appear in the traceback, and how they are + formatted. + (Contributed by Ammar Askar in :issue:`44569`.) + +* Add :func:`traceback.TracebackException.print`, which prints the + formatted :exc:`~traceback.TracebackException` instance to a file. + (Contributed by Irit Katriel in :issue:`33809`.) + + typing ------ From webhook-mailer at python.org Thu Aug 18 09:39:29 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 18 Aug 2022 13:39:29 -0000 Subject: [Python-checkins] [3.11] gh-95913: make the new internal classes pdb.ModuleTarget/ScriptTarget private (GH-96053) (#96063) Message-ID: <mailman.711.1660829970.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1b9b4856c86f3895445d8bd57a7ab18fc5cc9b20 commit: 1b9b4856c86f3895445d8bd57a7ab18fc5cc9b20 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-18T14:39:16+01:00 summary: [3.11] gh-95913: make the new internal classes pdb.ModuleTarget/ScriptTarget private (GH-96053) (#96063) Co-authored-by: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> files: M Lib/pdb.py M Lib/test/test_pyclbr.py diff --git a/Lib/pdb.py b/Lib/pdb.py index 58bc720275a..fe8ddd1abb1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -131,7 +131,7 @@ def __repr__(self): return self -class ScriptTarget(str): +class _ScriptTarget(str): def __new__(cls, val): # Mutate self to be the "real path". res = super().__new__(cls, os.path.realpath(val)) @@ -167,7 +167,7 @@ def code(self): return f"exec(compile({fp.read()!r}, {self!r}, 'exec'))" -class ModuleTarget(str): +class _ModuleTarget(str): def check(self): try: self._details @@ -1625,7 +1625,7 @@ def lookupmodule(self, filename): return fullname return None - def _run(self, target: Union[ModuleTarget, ScriptTarget]): + def _run(self, target: Union[_ModuleTarget, _ScriptTarget]): # When bdb sets tracing, a number of call and line events happen # BEFORE debugger even reaches user's code (and the exact sequence of # events depends on python version). Take special measures to @@ -1750,7 +1750,7 @@ def main(): commands = [optarg for opt, optarg in opts if opt in ['-c', '--command']] module_indicated = any(opt in ['-m'] for opt, optarg in opts) - cls = ModuleTarget if module_indicated else ScriptTarget + cls = _ModuleTarget if module_indicated else _ScriptTarget target = cls(args[0]) target.check() diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index b2de4e8397d..23453e34015 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -229,7 +229,7 @@ def test_others(self): cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties - ignore=('Union', 'ModuleTarget', 'ScriptTarget'), + ignore=('Union', '_ModuleTarget', '_ScriptTarget'), ) cm('pydoc', ignore=('input', 'output',)) # properties From webhook-mailer at python.org Thu Aug 18 09:42:24 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 18 Aug 2022 13:42:24 -0000 Subject: [Python-checkins] =?utf-8?q?=5B3=2E11=5D_GH-95736=3A_fix_Isolate?= =?utf-8?q?dAsyncioTestCase_to_initialize_Runner_bef=E2=80=A6_=28=2396042?= =?utf-8?q?=29?= Message-ID: <mailman.712.1660830145.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b68ea2a3e4ae6872e5bb69a0deded21f98c1eecc commit: b68ea2a3e4ae6872e5bb69a0deded21f98c1eecc branch: 3.11 author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-18T14:42:16+01:00 summary: [3.11] GH-95736: fix IsolatedAsyncioTestCase to initialize Runner bef? (#96042) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: A Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst M Lib/unittest/async_case.py M Lib/unittest/test/test_async_case.py diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index a90eed98f871..3457e92e5da2 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -79,6 +79,10 @@ async def enterAsyncContext(self, cm): return result def _callSetUp(self): + # Force loop to be initialized and set as the current loop + # so that setUp functions can use get_event_loop() and get the + # correct loop instance. + self._asyncioRunner.get_loop() self._asyncioTestContext.run(self.setUp) self._callAsync(self.asyncSetUp) diff --git a/Lib/unittest/test/test_async_case.py b/Lib/unittest/test/test_async_case.py index beadcac070b4..f59fc760d381 100644 --- a/Lib/unittest/test/test_async_case.py +++ b/Lib/unittest/test/test_async_case.py @@ -434,6 +434,21 @@ async def cleanup(self, fut): test.doCleanups() self.assertEqual(events, ['asyncSetUp', 'test', 'cleanup']) + def test_setup_get_event_loop(self): + # See https://github.com/python/cpython/issues/95736 + # Make sure the default event loop is not used + asyncio.set_event_loop(None) + + class TestCase1(unittest.IsolatedAsyncioTestCase): + def setUp(self): + asyncio.get_event_loop_policy().get_event_loop() + + async def test_demo1(self): + pass + + test = TestCase1('test_demo1') + result = test.run() + self.assertTrue(result.wasSuccessful()) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst b/Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst new file mode 100644 index 000000000000..abc270fe35ca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-11-18-22-29.gh-issue-95736.LzRZXe.rst @@ -0,0 +1 @@ +Fix :class:`unittest.IsolatedAsyncioTestCase` to set event loop before calling setup functions. Patch by Kumar Aditya. From webhook-mailer at python.org Thu Aug 18 10:58:48 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 18 Aug 2022 14:58:48 -0000 Subject: [Python-checkins] gh-93103: Doc uses PyConfig rather than deprecated vars (#96070) Message-ID: <mailman.713.1660834729.3313.python-checkins@python.org> https://github.com/python/cpython/commit/cfaa79aac088284c1eeacddc19ddebe06b55dcf7 commit: cfaa79aac088284c1eeacddc19ddebe06b55dcf7 branch: main author: Victor Stinner <vstinner at python.org> committer: vstinner <vstinner at python.org> date: 2022-08-18T16:58:38+02:00 summary: gh-93103: Doc uses PyConfig rather than deprecated vars (#96070) The C API documentation now uses the new PyConfig API, rather than deprecated global configuration variables. files: M Doc/c-api/intro.rst M Doc/c-api/sys.rst M Doc/c-api/veryhigh.rst M Doc/library/ctypes.rst diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index d9fcd0de1fec..557ccfc05234 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -153,7 +153,7 @@ complete listing. .. c:macro:: Py_GETENV(s) Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the - command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set). + command line (see :c:member:`PyConfig.use_environment`). .. c:macro:: Py_MAX(x, y) diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 32c2bc8a0880..11d5e0e03ec0 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -167,7 +167,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero; + :c:member:`PyConfig.legacy_windows_fs_encoding` is zero; .. c:function:: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos) @@ -209,7 +209,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero. + :c:member:`PyConfig.legacy_windows_fs_encoding` is zero. .. _systemfunctions: diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 7bd47bb9c660..b17818e35ed9 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -39,7 +39,7 @@ the same library that the Python runtime is using. Note that if an otherwise unhandled :exc:`SystemExit` is raised, this function will not return ``1``, but exit the process, as long as - ``Py_InspectFlag`` is not set. + :c:member:`PyConfig.inspect` is zero. .. c:function:: int Py_BytesMain(int argc, char **argv) @@ -95,7 +95,7 @@ the same library that the Python runtime is using. Note that if an otherwise unhandled :exc:`SystemExit` is raised, this function will not return ``-1``, but exit the process, as long as - ``Py_InspectFlag`` is not set. + :c:member:`PyConfig.inspect` is zero. .. c:function:: int PyRun_SimpleFile(FILE *fp, const char *filename) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 475737144d40..9546696e1c3d 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1068,18 +1068,16 @@ Accessing values exported from dlls ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some shared libraries not only export functions, they also export variables. An -example in the Python library itself is the :c:data:`Py_OptimizeFlag`, an integer -set to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on -startup. +example in the Python library itself is the :c:data:`Py_Version`, Python +runtime version number encoded in a single constant integer. :mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: - >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") - >>> print(opt_flag) - c_long(0) - >>> + >>> version = ctypes.c_int.in_dll(ctypes.pythonapi, "Py_Version") + >>> print(hex(version.value)) + 0x30c00a0 If the interpreter would have been started with :option:`-O`, the sample would have printed ``c_long(1)``, or ``c_long(2)`` if :option:`-OO` would have been From webhook-mailer at python.org Thu Aug 18 14:36:25 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 18 Aug 2022 18:36:25 -0000 Subject: [Python-checkins] gh-95271: Rework sqlite3 tutorial (#95749) Message-ID: <mailman.714.1660847786.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c87ea10fc91f040822ab3eed2d08b073861360f6 commit: c87ea10fc91f040822ab3eed2d08b073861360f6 branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-18T20:36:20+02:00 summary: gh-95271: Rework sqlite3 tutorial (#95749) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 67f8b31f11f..32f4188aae5 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -47,85 +47,173 @@ This document includes four main sections: PEP written by Marc-Andr? Lemburg. +.. We use the following practises for SQL code: + - UPPERCASE for keywords + - snake_case for schema + - single quotes for string literals + - singular for table names + - if needed, use double quotes for table and column names + .. _sqlite3-tutorial: Tutorial -------- -To use the module, start by creating a :class:`Connection` object that -represents the database. Here the data will be stored in the -:file:`example.db` file:: +In this tutorial, you will create a database of Monty Python movies +using basic :mod:`!sqlite3` functionality. +It assumes a fundamental understanding of database concepts, +including `cursors`_ and `transactions`_. + +First, we need to create a new database and open +a database connection to allow :mod:`!sqlite3` to work with it. +Call :func:`sqlite3.connect` to to create a connection to +the database :file:`tutorial.db` in the current working directory, +implicitly creating it if it does not exist:: import sqlite3 - con = sqlite3.connect('example.db') + con = sqlite3.connect("tutorial.db") -The special path name ``:memory:`` can be provided to create a temporary -database in RAM. +The returned :class:`Connection` object ``con`` +represents the connection to the on-disk database. -Once a :class:`Connection` has been established, create a :class:`Cursor` object -and call its :meth:`~Cursor.execute` method to perform SQL commands:: +In order to execute SQL statements and fetch results from SQL queries, +we will need to use a database cursor. +Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:: cur = con.cursor() - # Create table - cur.execute('''CREATE TABLE stocks - (date text, trans text, symbol text, qty real, price real)''') - - # Insert a row of data - cur.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") +Now that we've got a database connection and a cursor, +we can create a database table ``movie`` with columns for title, +release year, and review score. +For simplicity, we can just use column names in the table declaration -- +thanks to the `flexible typing`_ feature of SQLite, +specifying the data types is optional. +Execute the ``CREATE TABLE`` statement +by calling :meth:`cur.execute(...) <Cursor.execute>`:: + + cur.execute("CREATE TABLE movie(title, year, score)") + +.. Ideally, we'd use sqlite_schema instead of sqlite_master below, + but SQLite versions older than 3.33.0 do not recognise that variant. + +We can verify that the new table has been created by querying +the ``sqlite_master`` table built-in to SQLite, +which should now contain an entry for the ``movie`` table definition +(see `The Schema Table`_ for details). +Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`, +assign the result to ``res``, +and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: + + >>> res = cur.execute("SELECT name FROM sqlite_master") + >>> res.fetchone() + ('movie',) + +We can see that the table has been created, +as the query returns a :class:`tuple` containing the table's name. +If we query ``sqlite_master`` for a non-existent table ``spam``, +:meth:`!res.fetchone()` will return ``None``:: + + >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") + >>> res.fetchone() is None + True + +Now, add two rows of data supplied as SQL literals +by executing an ``INSERT`` statement, +once again by calling :meth:`cur.execute(...) <Cursor.execute>`:: + + cur.execute(""" + INSERT INTO movie VALUES + ('Monty Python and the Holy Grail', 1975, 8.2), + ('And Now for Something Completely Different', 1971, 7.5) + """) + +The ``INSERT`` statement implicitly opens a transaction, +which needs to be committed before changes are saved in the database +(see :ref:`sqlite3-controlling-transactions` for details). +Call :meth:`con.commit() <Connection.commit>` on the connection object +to commit the transaction:: - # Save (commit) the changes con.commit() - # We can also close the connection if we are done with it. - # Just be sure any changes have been committed or they will be lost. - con.close() - -The saved data is persistent: it can be reloaded in a subsequent session even -after restarting the Python interpreter:: - - import sqlite3 - con = sqlite3.connect('example.db') - cur = con.cursor() +We can verify that the data was inserted correctly +by executing a ``SELECT`` query. +Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to +assign the result to ``res``, +and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:: -At this point, our database only contains one row:: + >>> res = cur.execute("SELECT score FROM movie") + >>> res.fetchall() + [(8.2,), (7.5,)] - >>> res = cur.execute('SELECT count(rowid) FROM stocks') - >>> print(res.fetchone()) - (1,) +The result is a :class:`list` of two :class:`!tuple`\s, one per row, +each containing that row's ``score`` value. -The result is a one-item :class:`tuple`: -one row, with one column. -Now, let us insert three more rows of data, -using :meth:`~Cursor.executemany`:: +Now, insert three more rows by calling +:meth:`cur.executemany(...) <Cursor.executemany>`:: - >>> data = [ - ... ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), - ... ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0), - ... ('2006-04-06', 'SELL', 'IBM', 500, 53.0), - ... ] - >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data) + data = [ + ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), + ("Monty Python's The Meaning of Life", 1983, 7.5), + ("Monty Python's Life of Brian", 1979, 8.0), + ] + cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data) + con.commit() # Remember to commit the transaction after executing INSERT. -Notice that we used ``?`` placeholders to bind *data* to the query. +Notice that ``?`` placeholders are used to bind ``data`` to the query. Always use placeholders instead of :ref:`string formatting <tut-formatting>` to bind Python values to SQL statements, -to avoid `SQL injection attacks`_. -See the :ref:`placeholders how-to <sqlite3-placeholders>` for more details. +to avoid `SQL injection attacks`_ +(see :ref:`sqlite3-placeholders` for more details). -Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: +We can verify that the new rows were inserted +by executing a ``SELECT`` query, +this time iterating over the results of the query:: - >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): + >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): ... print(row) + (1971, "And Now for Something Completely Different") + (1975, "Monty Python and the Holy Grail") + (1979, "Monty Python's Life of Brian") + (1982, "Monty Python Live at the Hollywood Bowl") + (1983, "Monty Python's The Meaning of Life") + +Each row is a two-item :class:`tuple` of ``(year, title)``, +matching the columns selected in the query. + +Finally, verify that the database has been written to disk +by calling :meth:`con.close() <Connection.close>` +to close the existing connection, opening a new one, +creating a new cursor, then querying the database:: + + >>> con.close() + >>> new_con = sqlite3.connect("tutorial.db") + >>> new_cur = new_con.cursor() + >>> res = new_cur.execute("SELECT year, title FROM movie ORDER BY score DESC"): + >>> title, year = res.fetchone() + >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') + 'The highest scoring Monty Python movie is "Monty Python and the Holy Grail", released in 1975' + +You've now created an SQLite database using the :mod:`!sqlite3` module, +inserted data and retrieved values from it in multiple ways. + +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection +.. _The Schema Table: https://www.sqlite.org/schematab.html +.. _cursors: https://en.wikipedia.org/wiki/Cursor_(databases) +.. _flexible typing: https://www.sqlite.org/flextypegood.html +.. _sqlite_master: https://www.sqlite.org/schematab.html +.. _transactions: https://en.wikipedia.org/wiki/Database_transaction - ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) - ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) - ('2006-04-06', 'SELL', 'IBM', 500, 53.0) - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) +.. seealso:: -You've now created an SQLite database using the :mod:`!sqlite3` module. + * :ref:`sqlite3-howtos` for further reading: -.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection + * :ref:`sqlite3-placeholders` + * :ref:`sqlite3-adapters` + * :ref:`sqlite3-converters` + * :ref:`sqlite3-columns-by-name` + * :ref:`sqlite3-connection-context-manager` + * :ref:`sqlite3-explanation` for in-depth background on transaction control. .. _sqlite3-reference: From webhook-mailer at python.org Thu Aug 18 14:39:42 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 18 Aug 2022 18:39:42 -0000 Subject: [Python-checkins] Docs: Escape lone stars in sqlite3 docs (#96081) Message-ID: <mailman.715.1660847983.3313.python-checkins@python.org> https://github.com/python/cpython/commit/91afe66707237558d808aeca4683d0822aa0511e commit: 91afe66707237558d808aeca4683d0822aa0511e branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-18T20:39:36+02:00 summary: Docs: Escape lone stars in sqlite3 docs (#96081) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 32f4188aae5..540302437e7 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -555,7 +555,7 @@ Connection objects supplied, this must be a callable returning an instance of :class:`Cursor` or its subclasses. - .. method:: blobopen(table, column, row, /, *, readonly=False, name="main") + .. method:: blobopen(table, column, row, /, \*, readonly=False, name="main") Open a :class:`Blob` handle to an existing :abbr:`BLOB (Binary Large OBject)`. @@ -625,7 +625,7 @@ Connection objects :meth:`~Cursor.executescript` on it with the given *sql_script*. Return the new cursor object. - .. method:: create_function(name, narg, func, *, deterministic=False) + .. method:: create_function(name, narg, func, \*, deterministic=False) Create or remove a user-defined SQL function. @@ -916,7 +916,7 @@ Connection objects con.close() - .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) + .. method:: backup(target, \*, pages=-1, progress=None, name="main", sleep=0.250) Create a backup of an SQLite database. @@ -1028,7 +1028,7 @@ Connection objects .. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html - .. method:: serialize(*, name="main") + .. method:: serialize(\*, name="main") Serialize a database into a :class:`bytes` object. For an ordinary on-disk database file, the serialization is just a copy of the @@ -1050,7 +1050,7 @@ Connection objects .. versionadded:: 3.11 - .. method:: deserialize(data, /, *, name="main") + .. method:: deserialize(data, /, \*, name="main") Deserialize a :meth:`serialized <serialize>` database into a :class:`Connection`. From webhook-mailer at python.org Thu Aug 18 14:44:32 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 18 Aug 2022 18:44:32 -0000 Subject: [Python-checkins] gh-95271: Rework sqlite3 tutorial (GH-95749) Message-ID: <mailman.716.1660848273.3313.python-checkins@python.org> https://github.com/python/cpython/commit/972150b8e3bedf5d30c3111707edeaa96f9a8412 commit: 972150b8e3bedf5d30c3111707edeaa96f9a8412 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T11:44:27-07:00 summary: gh-95271: Rework sqlite3 tutorial (GH-95749) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit c87ea10fc91f040822ab3eed2d08b073861360f6) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index b4b98a50d8b7..dee935bcac0b 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -47,85 +47,173 @@ This document includes four main sections: PEP written by Marc-Andr? Lemburg. +.. We use the following practises for SQL code: + - UPPERCASE for keywords + - snake_case for schema + - single quotes for string literals + - singular for table names + - if needed, use double quotes for table and column names + .. _sqlite3-tutorial: Tutorial -------- -To use the module, start by creating a :class:`Connection` object that -represents the database. Here the data will be stored in the -:file:`example.db` file:: +In this tutorial, you will create a database of Monty Python movies +using basic :mod:`!sqlite3` functionality. +It assumes a fundamental understanding of database concepts, +including `cursors`_ and `transactions`_. + +First, we need to create a new database and open +a database connection to allow :mod:`!sqlite3` to work with it. +Call :func:`sqlite3.connect` to to create a connection to +the database :file:`tutorial.db` in the current working directory, +implicitly creating it if it does not exist:: import sqlite3 - con = sqlite3.connect('example.db') + con = sqlite3.connect("tutorial.db") -The special path name ``:memory:`` can be provided to create a temporary -database in RAM. +The returned :class:`Connection` object ``con`` +represents the connection to the on-disk database. -Once a :class:`Connection` has been established, create a :class:`Cursor` object -and call its :meth:`~Cursor.execute` method to perform SQL commands:: +In order to execute SQL statements and fetch results from SQL queries, +we will need to use a database cursor. +Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:: cur = con.cursor() - # Create table - cur.execute('''CREATE TABLE stocks - (date text, trans text, symbol text, qty real, price real)''') - - # Insert a row of data - cur.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") +Now that we've got a database connection and a cursor, +we can create a database table ``movie`` with columns for title, +release year, and review score. +For simplicity, we can just use column names in the table declaration -- +thanks to the `flexible typing`_ feature of SQLite, +specifying the data types is optional. +Execute the ``CREATE TABLE`` statement +by calling :meth:`cur.execute(...) <Cursor.execute>`:: + + cur.execute("CREATE TABLE movie(title, year, score)") + +.. Ideally, we'd use sqlite_schema instead of sqlite_master below, + but SQLite versions older than 3.33.0 do not recognise that variant. + +We can verify that the new table has been created by querying +the ``sqlite_master`` table built-in to SQLite, +which should now contain an entry for the ``movie`` table definition +(see `The Schema Table`_ for details). +Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`, +assign the result to ``res``, +and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: + + >>> res = cur.execute("SELECT name FROM sqlite_master") + >>> res.fetchone() + ('movie',) + +We can see that the table has been created, +as the query returns a :class:`tuple` containing the table's name. +If we query ``sqlite_master`` for a non-existent table ``spam``, +:meth:`!res.fetchone()` will return ``None``:: + + >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") + >>> res.fetchone() is None + True + +Now, add two rows of data supplied as SQL literals +by executing an ``INSERT`` statement, +once again by calling :meth:`cur.execute(...) <Cursor.execute>`:: + + cur.execute(""" + INSERT INTO movie VALUES + ('Monty Python and the Holy Grail', 1975, 8.2), + ('And Now for Something Completely Different', 1971, 7.5) + """) + +The ``INSERT`` statement implicitly opens a transaction, +which needs to be committed before changes are saved in the database +(see :ref:`sqlite3-controlling-transactions` for details). +Call :meth:`con.commit() <Connection.commit>` on the connection object +to commit the transaction:: - # Save (commit) the changes con.commit() - # We can also close the connection if we are done with it. - # Just be sure any changes have been committed or they will be lost. - con.close() - -The saved data is persistent: it can be reloaded in a subsequent session even -after restarting the Python interpreter:: - - import sqlite3 - con = sqlite3.connect('example.db') - cur = con.cursor() +We can verify that the data was inserted correctly +by executing a ``SELECT`` query. +Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to +assign the result to ``res``, +and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:: -At this point, our database only contains one row:: + >>> res = cur.execute("SELECT score FROM movie") + >>> res.fetchall() + [(8.2,), (7.5,)] - >>> res = cur.execute('SELECT count(rowid) FROM stocks') - >>> print(res.fetchone()) - (1,) +The result is a :class:`list` of two :class:`!tuple`\s, one per row, +each containing that row's ``score`` value. -The result is a one-item :class:`tuple`: -one row, with one column. -Now, let us insert three more rows of data, -using :meth:`~Cursor.executemany`:: +Now, insert three more rows by calling +:meth:`cur.executemany(...) <Cursor.executemany>`:: - >>> data = [ - ... ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), - ... ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0), - ... ('2006-04-06', 'SELL', 'IBM', 500, 53.0), - ... ] - >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data) + data = [ + ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), + ("Monty Python's The Meaning of Life", 1983, 7.5), + ("Monty Python's Life of Brian", 1979, 8.0), + ] + cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data) + con.commit() # Remember to commit the transaction after executing INSERT. -Notice that we used ``?`` placeholders to bind *data* to the query. +Notice that ``?`` placeholders are used to bind ``data`` to the query. Always use placeholders instead of :ref:`string formatting <tut-formatting>` to bind Python values to SQL statements, -to avoid `SQL injection attacks`_. -See the :ref:`placeholders how-to <sqlite3-placeholders>` for more details. +to avoid `SQL injection attacks`_ +(see :ref:`sqlite3-placeholders` for more details). -Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: +We can verify that the new rows were inserted +by executing a ``SELECT`` query, +this time iterating over the results of the query:: - >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): + >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): ... print(row) + (1971, "And Now for Something Completely Different") + (1975, "Monty Python and the Holy Grail") + (1979, "Monty Python's Life of Brian") + (1982, "Monty Python Live at the Hollywood Bowl") + (1983, "Monty Python's The Meaning of Life") + +Each row is a two-item :class:`tuple` of ``(year, title)``, +matching the columns selected in the query. + +Finally, verify that the database has been written to disk +by calling :meth:`con.close() <Connection.close>` +to close the existing connection, opening a new one, +creating a new cursor, then querying the database:: + + >>> con.close() + >>> new_con = sqlite3.connect("tutorial.db") + >>> new_cur = new_con.cursor() + >>> res = new_cur.execute("SELECT year, title FROM movie ORDER BY score DESC"): + >>> title, year = res.fetchone() + >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') + 'The highest scoring Monty Python movie is "Monty Python and the Holy Grail", released in 1975' + +You've now created an SQLite database using the :mod:`!sqlite3` module, +inserted data and retrieved values from it in multiple ways. + +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection +.. _The Schema Table: https://www.sqlite.org/schematab.html +.. _cursors: https://en.wikipedia.org/wiki/Cursor_(databases) +.. _flexible typing: https://www.sqlite.org/flextypegood.html +.. _sqlite_master: https://www.sqlite.org/schematab.html +.. _transactions: https://en.wikipedia.org/wiki/Database_transaction - ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) - ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) - ('2006-04-06', 'SELL', 'IBM', 500, 53.0) - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) +.. seealso:: -You've now created an SQLite database using the :mod:`!sqlite3` module. + * :ref:`sqlite3-howtos` for further reading: -.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection + * :ref:`sqlite3-placeholders` + * :ref:`sqlite3-adapters` + * :ref:`sqlite3-converters` + * :ref:`sqlite3-columns-by-name` + * :ref:`sqlite3-connection-context-manager` + * :ref:`sqlite3-explanation` for in-depth background on transaction control. .. _sqlite3-reference: From webhook-mailer at python.org Thu Aug 18 14:45:02 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 18 Aug 2022 18:45:02 -0000 Subject: [Python-checkins] gh-95271: Rework sqlite3 tutorial (GH-95749) Message-ID: <mailman.717.1660848303.3313.python-checkins@python.org> https://github.com/python/cpython/commit/882dd9fe0da726bb01627dc215352ba94551f3c9 commit: 882dd9fe0da726bb01627dc215352ba94551f3c9 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T11:44:58-07:00 summary: gh-95271: Rework sqlite3 tutorial (GH-95749) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit c87ea10fc91f040822ab3eed2d08b073861360f6) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index ff90feb471c3..10a7d39fd0e1 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -47,85 +47,173 @@ This document includes four main sections: PEP written by Marc-Andr? Lemburg. +.. We use the following practises for SQL code: + - UPPERCASE for keywords + - snake_case for schema + - single quotes for string literals + - singular for table names + - if needed, use double quotes for table and column names + .. _sqlite3-tutorial: Tutorial -------- -To use the module, start by creating a :class:`Connection` object that -represents the database. Here the data will be stored in the -:file:`example.db` file:: +In this tutorial, you will create a database of Monty Python movies +using basic :mod:`!sqlite3` functionality. +It assumes a fundamental understanding of database concepts, +including `cursors`_ and `transactions`_. + +First, we need to create a new database and open +a database connection to allow :mod:`!sqlite3` to work with it. +Call :func:`sqlite3.connect` to to create a connection to +the database :file:`tutorial.db` in the current working directory, +implicitly creating it if it does not exist:: import sqlite3 - con = sqlite3.connect('example.db') + con = sqlite3.connect("tutorial.db") -The special path name ``:memory:`` can be provided to create a temporary -database in RAM. +The returned :class:`Connection` object ``con`` +represents the connection to the on-disk database. -Once a :class:`Connection` has been established, create a :class:`Cursor` object -and call its :meth:`~Cursor.execute` method to perform SQL commands:: +In order to execute SQL statements and fetch results from SQL queries, +we will need to use a database cursor. +Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:: cur = con.cursor() - # Create table - cur.execute('''CREATE TABLE stocks - (date text, trans text, symbol text, qty real, price real)''') - - # Insert a row of data - cur.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") +Now that we've got a database connection and a cursor, +we can create a database table ``movie`` with columns for title, +release year, and review score. +For simplicity, we can just use column names in the table declaration -- +thanks to the `flexible typing`_ feature of SQLite, +specifying the data types is optional. +Execute the ``CREATE TABLE`` statement +by calling :meth:`cur.execute(...) <Cursor.execute>`:: + + cur.execute("CREATE TABLE movie(title, year, score)") + +.. Ideally, we'd use sqlite_schema instead of sqlite_master below, + but SQLite versions older than 3.33.0 do not recognise that variant. + +We can verify that the new table has been created by querying +the ``sqlite_master`` table built-in to SQLite, +which should now contain an entry for the ``movie`` table definition +(see `The Schema Table`_ for details). +Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`, +assign the result to ``res``, +and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: + + >>> res = cur.execute("SELECT name FROM sqlite_master") + >>> res.fetchone() + ('movie',) + +We can see that the table has been created, +as the query returns a :class:`tuple` containing the table's name. +If we query ``sqlite_master`` for a non-existent table ``spam``, +:meth:`!res.fetchone()` will return ``None``:: + + >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") + >>> res.fetchone() is None + True + +Now, add two rows of data supplied as SQL literals +by executing an ``INSERT`` statement, +once again by calling :meth:`cur.execute(...) <Cursor.execute>`:: + + cur.execute(""" + INSERT INTO movie VALUES + ('Monty Python and the Holy Grail', 1975, 8.2), + ('And Now for Something Completely Different', 1971, 7.5) + """) + +The ``INSERT`` statement implicitly opens a transaction, +which needs to be committed before changes are saved in the database +(see :ref:`sqlite3-controlling-transactions` for details). +Call :meth:`con.commit() <Connection.commit>` on the connection object +to commit the transaction:: - # Save (commit) the changes con.commit() - # We can also close the connection if we are done with it. - # Just be sure any changes have been committed or they will be lost. - con.close() - -The saved data is persistent: it can be reloaded in a subsequent session even -after restarting the Python interpreter:: - - import sqlite3 - con = sqlite3.connect('example.db') - cur = con.cursor() +We can verify that the data was inserted correctly +by executing a ``SELECT`` query. +Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to +assign the result to ``res``, +and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:: -At this point, our database only contains one row:: + >>> res = cur.execute("SELECT score FROM movie") + >>> res.fetchall() + [(8.2,), (7.5,)] - >>> res = cur.execute('SELECT count(rowid) FROM stocks') - >>> print(res.fetchone()) - (1,) +The result is a :class:`list` of two :class:`!tuple`\s, one per row, +each containing that row's ``score`` value. -The result is a one-item :class:`tuple`: -one row, with one column. -Now, let us insert three more rows of data, -using :meth:`~Cursor.executemany`:: +Now, insert three more rows by calling +:meth:`cur.executemany(...) <Cursor.executemany>`:: - >>> data = [ - ... ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), - ... ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0), - ... ('2006-04-06', 'SELL', 'IBM', 500, 53.0), - ... ] - >>> cur.executemany('INSERT INTO stocks VALUES(?, ?, ?, ?, ?)', data) + data = [ + ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), + ("Monty Python's The Meaning of Life", 1983, 7.5), + ("Monty Python's Life of Brian", 1979, 8.0), + ] + cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data) + con.commit() # Remember to commit the transaction after executing INSERT. -Notice that we used ``?`` placeholders to bind *data* to the query. +Notice that ``?`` placeholders are used to bind ``data`` to the query. Always use placeholders instead of :ref:`string formatting <tut-formatting>` to bind Python values to SQL statements, -to avoid `SQL injection attacks`_. -See the :ref:`placeholders how-to <sqlite3-placeholders>` for more details. +to avoid `SQL injection attacks`_ +(see :ref:`sqlite3-placeholders` for more details). -Then, retrieve the data by iterating over the result of a ``SELECT`` statement:: +We can verify that the new rows were inserted +by executing a ``SELECT`` query, +this time iterating over the results of the query:: - >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): + >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): ... print(row) + (1971, "And Now for Something Completely Different") + (1975, "Monty Python and the Holy Grail") + (1979, "Monty Python's Life of Brian") + (1982, "Monty Python Live at the Hollywood Bowl") + (1983, "Monty Python's The Meaning of Life") + +Each row is a two-item :class:`tuple` of ``(year, title)``, +matching the columns selected in the query. + +Finally, verify that the database has been written to disk +by calling :meth:`con.close() <Connection.close>` +to close the existing connection, opening a new one, +creating a new cursor, then querying the database:: + + >>> con.close() + >>> new_con = sqlite3.connect("tutorial.db") + >>> new_cur = new_con.cursor() + >>> res = new_cur.execute("SELECT year, title FROM movie ORDER BY score DESC"): + >>> title, year = res.fetchone() + >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') + 'The highest scoring Monty Python movie is "Monty Python and the Holy Grail", released in 1975' + +You've now created an SQLite database using the :mod:`!sqlite3` module, +inserted data and retrieved values from it in multiple ways. + +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection +.. _The Schema Table: https://www.sqlite.org/schematab.html +.. _cursors: https://en.wikipedia.org/wiki/Cursor_(databases) +.. _flexible typing: https://www.sqlite.org/flextypegood.html +.. _sqlite_master: https://www.sqlite.org/schematab.html +.. _transactions: https://en.wikipedia.org/wiki/Database_transaction - ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) - ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) - ('2006-04-06', 'SELL', 'IBM', 500, 53.0) - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) +.. seealso:: -You've now created an SQLite database using the :mod:`!sqlite3` module. + * :ref:`sqlite3-howtos` for further reading: -.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection + * :ref:`sqlite3-placeholders` + * :ref:`sqlite3-adapters` + * :ref:`sqlite3-converters` + * :ref:`sqlite3-columns-by-name` + * :ref:`sqlite3-connection-context-manager` + * :ref:`sqlite3-explanation` for in-depth background on transaction control. .. _sqlite3-reference: From webhook-mailer at python.org Thu Aug 18 14:47:46 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 18 Aug 2022 18:47:46 -0000 Subject: [Python-checkins] Docs: Escape lone stars in sqlite3 docs (GH-96081) Message-ID: <mailman.718.1660848468.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e8e3fe9931eb277d40777623427074131031d8a5 commit: e8e3fe9931eb277d40777623427074131031d8a5 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T11:47:42-07:00 summary: Docs: Escape lone stars in sqlite3 docs (GH-96081) (cherry picked from commit 91afe66707237558d808aeca4683d0822aa0511e) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index dee935bcac0..64bab60ebe4 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -542,7 +542,7 @@ Connection objects supplied, this must be a callable returning an instance of :class:`Cursor` or its subclasses. - .. method:: blobopen(table, column, row, /, *, readonly=False, name="main") + .. method:: blobopen(table, column, row, /, \*, readonly=False, name="main") Open a :class:`Blob` handle to an existing :abbr:`BLOB (Binary Large OBject)`. @@ -612,7 +612,7 @@ Connection objects :meth:`~Cursor.executescript` on it with the given *sql_script*. Return the new cursor object. - .. method:: create_function(name, narg, func, *, deterministic=False) + .. method:: create_function(name, narg, func, \*, deterministic=False) Create or remove a user-defined SQL function. @@ -903,7 +903,7 @@ Connection objects con.close() - .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) + .. method:: backup(target, \*, pages=-1, progress=None, name="main", sleep=0.250) Create a backup of an SQLite database. @@ -1015,7 +1015,7 @@ Connection objects .. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html - .. method:: serialize(*, name="main") + .. method:: serialize(\*, name="main") Serialize a database into a :class:`bytes` object. For an ordinary on-disk database file, the serialization is just a copy of the @@ -1037,7 +1037,7 @@ Connection objects .. versionadded:: 3.11 - .. method:: deserialize(data, /, *, name="main") + .. method:: deserialize(data, /, \*, name="main") Deserialize a :meth:`serialized <serialize>` database into a :class:`Connection`. From webhook-mailer at python.org Thu Aug 18 14:48:32 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 18 Aug 2022 18:48:32 -0000 Subject: [Python-checkins] GH-95861: Add support for Spearman's rank correlation coefficient (GH-95863) Message-ID: <mailman.719.1660848512.3313.python-checkins@python.org> https://github.com/python/cpython/commit/29c8f80760869018aa0d7b1d42ab737dc325cfa2 commit: 29c8f80760869018aa0d7b1d42ab737dc325cfa2 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-18T13:48:27-05:00 summary: GH-95861: Add support for Spearman's rank correlation coefficient (GH-95863) files: A Misc/NEWS.d/next/Library/2022-08-10-17-34-07.gh-issue-95861.qv-T5s.rst M Doc/library/statistics.rst M Lib/statistics.py M Lib/test/test_statistics.py diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index bf869903c0f..c3f9c1f5239 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -104,7 +104,7 @@ These functions calculate statistics regarding relations between two inputs. ========================= ===================================================== :func:`covariance` Sample covariance for two variables. -:func:`correlation` Pearson's correlation coefficient for two variables. +:func:`correlation` Pearson and Spearman's correlation coefficients. :func:`linear_regression` Slope and intercept for simple linear regression. ========================= ===================================================== @@ -648,31 +648,57 @@ However, for reading convenience, most of the examples show sorted sequences. .. versionadded:: 3.10 -.. function:: correlation(x, y, /) +.. function:: correlation(x, y, /, *, method='linear') Return the `Pearson's correlation coefficient <https://en.wikipedia.org/wiki/Pearson_correlation_coefficient>`_ for two inputs. Pearson's correlation coefficient *r* takes values - between -1 and +1. It measures the strength and direction of the linear - relationship, where +1 means very strong, positive linear relationship, - -1 very strong, negative linear relationship, and 0 no linear relationship. + between -1 and +1. It measures the strength and direction of a linear + relationship. + + If *method* is "ranked", computes `Spearman's rank correlation coefficient + <https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient>`_ + for two inputs. The data is replaced by ranks. Ties are averaged so that + equal values receive the same rank. The resulting coefficient measures the + strength of a monotonic relationship. + + Spearman's correlation coefficient is appropriate for ordinal data or for + continuous data that doesn't meet the linear proportion requirement for + Pearson's correlation coefficient. Both inputs must be of the same length (no less than two), and need not to be constant, otherwise :exc:`StatisticsError` is raised. - Examples: + Example with `Kepler's laws of planetary motion + <https://en.wikipedia.org/wiki/Kepler's_laws_of_planetary_motion>`_: .. doctest:: - >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] - >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] - >>> correlation(x, x) + >>> # Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune + >>> orbital_period = [88, 225, 365, 687, 4331, 10_756, 30_687, 60_190] # days + >>> dist_from_sun = [58, 108, 150, 228, 778, 1_400, 2_900, 4_500] # million km + + >>> # Show that a perfect monotonic relationship exists + >>> correlation(orbital_period, dist_from_sun, method='ranked') + 1.0 + + >>> # Observe that a linear relationship is imperfect + >>> round(correlation(orbital_period, dist_from_sun), 4) + 0.9882 + + >>> # Demonstrate Kepler's third law: There is a linear correlation + >>> # between the square of the orbital period and the cube of the + >>> # distance from the sun. + >>> period_squared = [p * p for p in orbital_period] + >>> dist_cubed = [d * d * d for d in dist_from_sun] + >>> round(correlation(period_squared, dist_cubed), 4) 1.0 - >>> correlation(x, y) - -1.0 .. versionadded:: 3.10 + .. versionchanged:: 3.12 + Added support for Spearman's rank correlation coefficient. + .. function:: linear_regression(x, y, /, *, proportional=False) Return the slope and intercept of `simple linear regression diff --git a/Lib/statistics.py b/Lib/statistics.py index c78d6451885..a3f915c1302 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -134,11 +134,11 @@ from fractions import Fraction from decimal import Decimal -from itertools import groupby, repeat +from itertools import count, groupby, repeat from bisect import bisect_left, bisect_right from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum from functools import reduce -from operator import mul +from operator import mul, itemgetter from collections import Counter, namedtuple, defaultdict _SQRT2 = sqrt(2.0) @@ -355,6 +355,50 @@ def _fail_neg(values, errmsg='negative value'): raise StatisticsError(errmsg) yield x +def _rank(data, /, *, key=None, reverse=False, ties='average') -> list[float]: + """Rank order a dataset. The lowest value has rank 1. + + Ties are averaged so that equal values receive the same rank: + + >>> data = [31, 56, 31, 25, 75, 18] + >>> _rank(data) + [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] + + The operation is idempotent: + + >>> _rank([3.5, 5.0, 3.5, 2.0, 6.0, 1.0]) + [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] + + It is possible to rank the data in reverse order so that + the highest value has rank 1. Also, a key-function can + extract the field to be ranked: + + >>> goals = [('eagles', 45), ('bears', 48), ('lions', 44)] + >>> _rank(goals, key=itemgetter(1), reverse=True) + [2.0, 1.0, 3.0] + + """ + # If this function becomes public at some point, more thought + # needs to be given to the signature. A list of ints is + # plausible when ties is "min" or "max". When ties is "average", + # either list[float] or list[Fraction] is plausible. + + # Default handling of ties matches scipy.stats.mstats.spearmanr. + if ties != 'average': + raise ValueError(f'Unknown tie resolution method: {ties!r}') + if key is not None: + data = map(key, data) + val_pos = sorted(zip(data, count()), reverse=reverse) + i = 0 # To rank starting at 0 instead of 1, set i = -1. + result = [0] * len(val_pos) + for _, g in groupby(val_pos, key=itemgetter(0)): + group = list(g) + size = len(group) + rank = i + (size + 1) / 2 + for value, orig_pos in group: + result[orig_pos] = rank + i += size + return result def _integer_sqrt_of_frac_rto(n: int, m: int) -> int: """Square root of n/m, rounded to the nearest integer using round-to-odd.""" @@ -988,14 +1032,12 @@ def covariance(x, y, /): return sxy / (n - 1) -def correlation(x, y, /): +def correlation(x, y, /, *, method='linear'): """Pearson's correlation coefficient Return the Pearson's correlation coefficient for two inputs. Pearson's - correlation coefficient *r* takes values between -1 and +1. It measures the - strength and direction of the linear relationship, where +1 means very - strong, positive linear relationship, -1 very strong, negative linear - relationship, and 0 no linear relationship. + correlation coefficient *r* takes values between -1 and +1. It measures + the strength and direction of a linear relationship. >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] @@ -1004,12 +1046,25 @@ def correlation(x, y, /): >>> correlation(x, y) -1.0 + If *method* is "ranked", computes Spearman's rank correlation coefficient + for two inputs. The data is replaced by ranks. Ties are averaged + so that equal values receive the same rank. The resulting coefficient + measures the strength of a monotonic relationship. + + Spearman's rank correlation coefficient is appropriate for ordinal + data or for continuous data that doesn't meet the linear proportion + requirement for Pearson's correlation coefficient. """ n = len(x) if len(y) != n: raise StatisticsError('correlation requires that both inputs have same number of data points') if n < 2: raise StatisticsError('correlation requires at least two data points') + if method not in {'linear', 'ranked'}: + raise ValueError(f'Unknown method: {method!r}') + if method == 'ranked': + x = _rank(x) + y = _rank(y) xbar = fsum(x) / n ybar = fsum(y) / n sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index bf85525dd12..05ce79f1265 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -2565,6 +2565,22 @@ def test_different_scales(self): self.assertAlmostEqual(statistics.covariance(x, y), 0.1) + def test_correlation_spearman(self): + # https://statistics.laerd.com/statistical-guides/spearmans-rank-order-correlation-statistical-guide-2.php + # Compare with: + # >>> import scipy.stats.mstats + # >>> scipy.stats.mstats.spearmanr(reading, mathematics) + # SpearmanrResult(correlation=0.6686960980480712, pvalue=0.03450954165178532) + # And Wolfram Alpha gives: 0.668696 + # https://www.wolframalpha.com/input?i=SpearmanRho%5B%7B56%2C+75%2C+45%2C+71%2C+61%2C+64%2C+58%2C+80%2C+76%2C+61%7D%2C+%7B66%2C+70%2C+40%2C+60%2C+65%2C+56%2C+59%2C+77%2C+67%2C+63%7D%5D + reading = [56, 75, 45, 71, 61, 64, 58, 80, 76, 61] + mathematics = [66, 70, 40, 60, 65, 56, 59, 77, 67, 63] + self.assertAlmostEqual(statistics.correlation(reading, mathematics, method='ranked'), + 0.6686960980480712) + + with self.assertRaises(ValueError): + statistics.correlation(reading, mathematics, method='bad_method') + class TestLinearRegression(unittest.TestCase): def test_constant_input_error(self): diff --git a/Misc/NEWS.d/next/Library/2022-08-10-17-34-07.gh-issue-95861.qv-T5s.rst b/Misc/NEWS.d/next/Library/2022-08-10-17-34-07.gh-issue-95861.qv-T5s.rst new file mode 100644 index 00000000000..aae76c74e2f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-10-17-34-07.gh-issue-95861.qv-T5s.rst @@ -0,0 +1,2 @@ +Add support for computing Spearman's correlation coefficient to the existing +statistics.correlation() function. From webhook-mailer at python.org Thu Aug 18 16:28:07 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Thu, 18 Aug 2022 20:28:07 -0000 Subject: [Python-checkins] [3.10] Docs: Escape lone stars in sqlite3 docs (GH-96081). (#96085) Message-ID: <mailman.720.1660854488.3313.python-checkins@python.org> https://github.com/python/cpython/commit/eb182fe9eb171fd01ab59deaa9f1e4bfcce57748 commit: eb182fe9eb171fd01ab59deaa9f1e4bfcce57748 branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-18T22:27:51+02:00 summary: [3.10] Docs: Escape lone stars in sqlite3 docs (GH-96081). (#96085) (cherry picked from commit 91afe66707237558d808aeca4683d0822aa0511e) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 10a7d39fd0e..e5ddf61f7ad 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -540,7 +540,7 @@ Connection objects :meth:`~Cursor.executescript` on it with the given *sql_script*. Return the new cursor object. - .. method:: create_function(name, narg, func, *, deterministic=False) + .. method:: create_function(name, narg, func, \*, deterministic=False) Create or remove a user-defined SQL function. @@ -784,7 +784,7 @@ Connection objects con.close() - .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) + .. method:: backup(target, \*, pages=-1, progress=None, name="main", sleep=0.250) Create a backup of an SQLite database. From webhook-mailer at python.org Thu Aug 18 16:48:20 2022 From: webhook-mailer at python.org (zooba) Date: Thu, 18 Aug 2022 20:48:20 -0000 Subject: [Python-checkins] Remove manual build scripts for Windows dependencies and put them in the release-tools repository instead (GH-96088) Message-ID: <mailman.721.1660855701.3313.python-checkins@python.org> https://github.com/python/cpython/commit/22a95cb5114891e87f6933482dc6eaa00e6a11ad commit: 22a95cb5114891e87f6933482dc6eaa00e6a11ad branch: main author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-18T21:48:09+01:00 summary: Remove manual build scripts for Windows dependencies and put them in the release-tools repository instead (GH-96088) files: D .azure-pipelines/find-tools.yml D .azure-pipelines/libffi-build.yml D .azure-pipelines/openssl-build.yml D .azure-pipelines/tcltk-build.yml diff --git a/.azure-pipelines/find-tools.yml b/.azure-pipelines/find-tools.yml deleted file mode 100644 index 9ad0f5622bb3..000000000000 --- a/.azure-pipelines/find-tools.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Locate a set of the tools used for builds - -steps: - - template: windows-release/find-sdk.yml - parameters: - toolname: 'signtool.exe' - - - powershell: | - $vcvarsall = (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" ` - -prerelease ` - -latest ` - -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` - -find VC\Auxiliary\Build\vcvarsall.bat) - Write-Host "Found vcvarsall at $vcvarsall" - Write-Host "##vso[task.setVariable variable=vcvarsall]$vcvarsall" - displayName: 'Find vcvarsall.bat' - - - powershell: | - $msbuild = (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" ` - -prerelease ` - -latest ` - -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` - -find MSBuild\Current\Bin\msbuild.exe) - Write-Host "Found MSBuild at $msbuild" - Write-Host "##vso[task.setVariable variable=msbuild]$msbuild" - displayName: 'Find MSBuild' diff --git a/.azure-pipelines/libffi-build.yml b/.azure-pipelines/libffi-build.yml deleted file mode 100644 index dd26ff215a80..000000000000 --- a/.azure-pipelines/libffi-build.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: $(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr) - -variables: - IntDir: '$(Build.BinariesDirectory)' - OutDir: '$(Build.ArtifactStagingDirectory)' - - # MUST BE SET AT QUEUE TIME - # SigningCertificate: 'Python Software Foundation' - # SourcesRepo: 'https://github.com/python/cpython-source-deps' - # SourceTag: 'libffi-3.4.2' - -jobs: -- job: Build_LibFFI - displayName: LibFFI - pool: - vmImage: windows-latest - - workspace: - clean: all - - steps: - - checkout: none - - - template: ./find-tools.yml - - - powershell: | - mkdir -Force "$(IntDir)\script" - iwr "https://github.com/python/cpython/raw/main/PCbuild/prepare_libffi.bat" ` - -outfile "$(IntDir)\script\prepare_libffi.bat" - displayName: 'Download build script' - - - powershell: | - git clone $(SourcesRepo) -b $(SourceTag) --depth 1 -c core.autocrlf=false -c core.eol=lf . - displayName: 'Check out LibFFI sources' - - - script: 'prepare_libffi.bat --install-cygwin' - workingDirectory: '$(IntDir)\script' - displayName: 'Install Cygwin and build' - env: - VCVARSALL: '$(vcvarsall)' - LIBFFI_SOURCE: '$(Build.SourcesDirectory)' - LIBFFI_OUT: '$(OutDir)' - - - powershell: | - if ((gci *\*.dll).Count -lt 4) { - Write-Error "Did not generate enough DLL files" - } - if ((gci *\Include\ffi.h).Count -lt 4) { - Write-Error "Did not generate enough include files" - } - failOnStderr: true - workingDirectory: '$(OutDir)' - displayName: 'Verify files were created' - - - publish: '$(OutDir)' - artifact: 'unsigned' - displayName: 'Publish unsigned build' - -- job: Sign_LibFFI - displayName: Sign LibFFI - dependsOn: Build_LibFFI - pool: - name: 'Windows Release' - - workspace: - clean: all - - steps: - - checkout: none - - download: current - artifact: unsigned - - - template: ./find-tools.yml - - - powershell: | - signtool sign /q /a ` - /n "Python Software Foundation" ` - /fd sha256 ` - /tr http://timestamp.digicert.com/ /td sha256 ` - /d "LibFFI for Python" ` - (gci "$(Pipeline.Workspace)\unsigned\*.dll" -r) - displayName: 'Sign files' - - - publish: '$(Pipeline.Workspace)\unsigned' - artifact: 'libffi' - displayName: 'Publish libffi' diff --git a/.azure-pipelines/openssl-build.yml b/.azure-pipelines/openssl-build.yml deleted file mode 100644 index 8aab7ea0b941..000000000000 --- a/.azure-pipelines/openssl-build.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: $(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr) - -variables: - IntDir: '$(Build.BinariesDirectory)' - OutDir: '$(Build.ArtifactStagingDirectory)' - - # MUST BE SET AT QUEUE TIME - # SigningCertificate: 'Python Software Foundation' - # SourcesRepo: 'https://github.com/python/cpython-source-deps' - # SourceTag: 'openssl-1.1.1k' - -jobs: -- job: Build_SSL - displayName: OpenSSL - pool: - name: 'Windows Release' - #vmImage: windows-latest - - strategy: - matrix: - win32: - Platform: 'win32' - VCPlatform: 'amd64_x86' - OpenSSLPlatform: 'VC-WIN32 no-asm' - amd64: - Platform: 'amd64' - VCPlatform: 'amd64' - OpenSSLPlatform: 'VC-WIN64A-masm' - arm32: - Platform: 'arm32' - VCPlatform: 'amd64_arm' - OpenSSLPlatform: 'VC-WIN32-ARM' - arm64: - Platform: 'arm64' - VCPlatform: 'amd64_arm64' - OpenSSLPlatform: 'VC-WIN64-ARM' - - workspace: - clean: all - - steps: - - checkout: none - - - template: ./find-tools.yml - - - powershell: | - git clone $(SourcesRepo) -b $(SourceTag) --depth 1 . - displayName: 'Check out OpenSSL sources' - - - powershell: | - $f = gi ms\uplink.c - $c1 = gc $f - $c2 = $c1 -replace '\(\(h = GetModuleHandle\(NULL\)\) == NULL\)', '((h = GetModuleHandleA("_ssl.pyd")) == NULL) if ((h = GetModuleHandleA("_ssl_d.pyd")) == NULL) if ((h = GetModuleHandle(NULL)) == NULL /*patched*/)' - if ($c2 -ne $c1) { - $c2 | Out-File $f -Encoding ASCII - } else { - Write-Host '##warning Failed to patch uplink.c' - } - displayName: 'Apply uplink.c patch' - - - script: | - call "$(vcvarsall)" $(VCPlatform) - perl "$(Build.SourcesDirectory)\Configure" $(OpenSSLPlatform) - nmake - workingDirectory: '$(IntDir)' - displayName: 'Build OpenSSL' - - - script: | - call "$(vcvarsall)" $(VCPlatform) - signtool sign /q /a /n "$(SigningCertificate)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "OpenSSL for Python" *.dll - workingDirectory: '$(IntDir)' - displayName: 'Sign OpenSSL Build' - condition: and(succeeded(), variables['SigningCertificate']) - - - task: CopyFiles at 2 - displayName: 'Copy built libraries for upload' - inputs: - SourceFolder: '$(IntDir)' - Contents: | - lib*.dll - lib*.pdb - lib*.lib - include\openssl\*.h - TargetFolder: '$(OutDir)' - - - task: CopyFiles at 2 - displayName: 'Copy header files for upload' - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - include\openssl\* - TargetFolder: '$(OutDir)' - - - task: CopyFiles at 2 - displayName: 'Copy applink files for upload' - inputs: - SourceFolder: '$(Build.SourcesDirectory)\ms' - Contents: applink.c - TargetFolder: '$(OutDir)\include' - - - task: CopyFiles at 2 - displayName: 'Copy LICENSE for upload' - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: LICENSE - TargetFolder: '$(OutDir)' - - - publish: '$(OutDir)' - artifact: '$(Platform)' - displayName: 'Publishing $(Platform)' diff --git a/.azure-pipelines/tcltk-build.yml b/.azure-pipelines/tcltk-build.yml deleted file mode 100644 index f9e50d3711a4..000000000000 --- a/.azure-pipelines/tcltk-build.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: tcl$(TkSourceTag)_$(Date:yyyyMMdd)$(Rev:.rr) - -variables: - IntDir: '$(Build.BinariesDirectory)\obj' - ExternalsDir: '$(Build.BinariesDirectory)\externals' - OutDir: '$(Build.ArtifactStagingDirectory)' - Configuration: 'Release' - - # MUST BE SET AT QUEUE TIME - # SigningCertificate: 'Python Software Foundation' - # SourcesRepo: 'https://github.com/python/cpython-source-deps' - # TclSourceTag: 'tcl-core-8.6.12.0' - # TkSourceTag: 'tk-8.6.12.0' - # TixSourceTag: 'tix-8.4.3.6' - -jobs: -- job: Build_TclTk - displayName: 'Tcl/Tk' - pool: - name: 'Windows Release' - #vmImage: windows-latest - - workspace: - clean: all - - steps: - - template: ./find-tools.yml - - - powershell: | - git clone $(SourcesRepo) -b $(TclSourceTag) --depth 1 "$(ExternalsDir)\$(TclSourceTag)" - displayName: 'Check out Tcl sources' - - - powershell: | - git clone $(SourcesRepo) -b $(TkSourceTag) --depth 1 "$(ExternalsDir)\$(TkSourceTag)" - displayName: 'Check out Tk sources' - - - powershell: | - git clone $(SourcesRepo) -b $(TixSourceTag) --depth 1 "$(ExternalsDir)\$(TixSourceTag)" - displayName: 'Check out Tix sources' - - # This msbuild.rsp file will be used by the build to forcibly override these variables - - powershell: | - del -Force -EA 0 msbuild.rsp - "/p:IntDir=$(IntDir)\" >> msbuild.rsp - "/p:ExternalsDir=$(ExternalsDir)\" >> msbuild.rsp - "/p:tclDir=$(ExternalsDir)\$(TclSourceTag)\" >> msbuild.rsp - "/p:tkDir=$(ExternalsDir)\$(TkSourceTag)\" >> msbuild.rsp - "/p:tixDir=$(ExternalsDir)\$(TixSourceTag)\" >> msbuild.rsp - displayName: 'Generate msbuild.rsp' - - - powershell: | - & "$(msbuild)" PCbuild\tcl.vcxproj "@msbuild.rsp" /p:Platform=Win32 /p:tcltkDir="$(OutDir)\win32" - & "$(msbuild)" PCbuild\tk.vcxproj "@msbuild.rsp" /p:Platform=Win32 /p:tcltkDir="$(OutDir)\win32" - & "$(msbuild)" PCbuild\tix.vcxproj "@msbuild.rsp" /p:Platform=Win32 /p:tcltkDir="$(OutDir)\win32" - displayName: 'Build for win32' - - - powershell: | - & "$(msbuild)" PCbuild\tcl.vcxproj "@msbuild.rsp" /p:Platform=x64 /p:tcltkDir="$(OutDir)\amd64" - & "$(msbuild)" PCbuild\tk.vcxproj "@msbuild.rsp" /p:Platform=x64 /p:tcltkDir="$(OutDir)\amd64" - & "$(msbuild)" PCbuild\tix.vcxproj "@msbuild.rsp" /p:Platform=x64 /p:tcltkDir="$(OutDir)\amd64" - displayName: 'Build for amd64' - - - powershell: | - & "$(msbuild)" PCbuild\tcl.vcxproj "@msbuild.rsp" /p:Platform=ARM64 /p:tcltkDir="$(OutDir)\arm64" - & "$(msbuild)" PCbuild\tk.vcxproj "@msbuild.rsp" /p:Platform=ARM64 /p:tcltkDir="$(OutDir)\arm64" - & "$(msbuild)" PCbuild\tix.vcxproj "@msbuild.rsp" /p:Platform=ARM64 /p:tcltkDir="$(OutDir)\arm64" - displayName: 'Build for arm64' - - - publish: '$(OutDir)' - artifact: 'tcltk' - displayName: 'Publishing tcltk' From webhook-mailer at python.org Thu Aug 18 17:34:03 2022 From: webhook-mailer at python.org (corona10) Date: Thu, 18 Aug 2022 21:34:03 -0000 Subject: [Python-checkins] gh-90536: Add support for the BOLT post-link binary optimizer (gh-95908) Message-ID: <mailman.722.1660858444.3313.python-checkins@python.org> https://github.com/python/cpython/commit/214eb2cce5caa99f476ae8abd406077e2c293a3c commit: 214eb2cce5caa99f476ae8abd406077e2c293a3c branch: main author: Kevin Modzelewski <kmod at users.noreply.github.com> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-19T06:33:54+09:00 summary: gh-90536: Add support for the BOLT post-link binary optimizer (gh-95908) * Add support for the BOLT post-link binary optimizer Using [bolt](https://github.com/llvm/llvm-project/tree/main/bolt) provides a fairly large speedup without any code or functionality changes. It provides roughly a 1% speedup on pyperformance, and a 4% improvement on the Pyston web macrobenchmarks. It is gated behind an `--enable-bolt` configure arg because not all toolchains and environments are supported. It has been tested on a Linux x86_64 toolchain, using llvm-bolt built from the LLVM 14.0.6 sources (their binary distribution of this version did not include bolt). Compared to [a previous attempt](https://github.com/faster-cpython/ideas/issues/224), this commit uses bolt's preferred "instrumentation" approach, as well as adds some non-PIE flags which enable much better optimizations from bolt. The effects of this change are a bit more dependent on CPU microarchitecture than other changes, since it optimizes i-cache behavior which seems to be a bit more variable between architectures. The 1%/4% numbers were collected on an Intel Skylake CPU, and on an AMD Zen 3 CPU I got a slightly larger speedup (2%/4%), and on a c6i.xlarge EC2 instance I got a slightly lower speedup (1%/3%). The low speedup on pyperformance is not entirely unexpected, because BOLT improves i-cache behavior, and the benchmarks in the pyperformance suite are small and tend to fit in i-cache. This change uses the existing pgo profiling task (`python -m test --pgo`), though I was able to measure about a 1% macrobenchmark improvement by using the macrobenchmarks as the training task. I personally think that both the PGO and BOLT tasks should be updated to use macrobenchmarks, but for the sake of splitting up the work this PR uses the existing pgo task. * Simplify the build flags * Add a NEWS entry * Update Makefile.pre.in Co-authored-by: Dong-hee Na <donghee.na92 at gmail.com> * Update configure.ac Co-authored-by: Dong-hee Na <donghee.na92 at gmail.com> * Add myself to ACKS * Add docs * Other review comments * fix tab/space issue * Make it more clear that --enable-bolt is experimental * Add link to bolt's github page Co-authored-by: Dong-hee Na <donghee.na92 at gmail.com> files: A Misc/NEWS.d/next/Build/2022-08-12-13-06-03.gh-issue-90536.qMpF6p.rst M Doc/using/configure.rst M Doc/whatsnew/3.12.rst M Makefile.pre.in M Misc/ACKS M configure M configure.ac diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 4e50e73a11b8..ef770d7747c3 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -191,7 +191,8 @@ Performance options ------------------- Configuring Python using ``--enable-optimizations --with-lto`` (PGO + LTO) is -recommended for best performance. +recommended for best performance. The experimental ``--enable-bolt`` flag can +also be used to improve performance. .. cmdoption:: --enable-optimizations @@ -231,6 +232,24 @@ recommended for best performance. .. versionadded:: 3.11 To use ThinLTO feature, use ``--with-lto=thin`` on Clang. +.. cmdoption:: --enable-bolt + + Enable usage of the `BOLT post-link binary optimizer + <https://github.com/llvm/llvm-project/tree/main/bolt>` (disabled by + default). + + BOLT is part of the LLVM project but is not always included in their binary + distributions. This flag requires that ``llvm-bolt`` and ``merge-fdata`` + are available. + + BOLT is still a fairly new project so this flag should be considered + experimental for now. Because this tool operates on machine code its success + is dependent on a combination of the build environment + the other + optimization configure args + the CPU architecture, and not all combinations + are supported. + + .. versionadded:: 3.12 + .. cmdoption:: --with-computed-gotos Enable computed gotos in evaluation loop (enabled by default on supported diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 9689d9df9dfc..f9fa8ac31231 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -133,6 +133,10 @@ Optimizations It reduces object size by 8 or 16 bytes on 64bit platform. (:pep:`623`) (Contributed by Inada Naoki in :gh:`92536`.) +* Added experimental support for using the BOLT binary optimizer in the build + process, which improves performance by 1-5%. + (Contributed by Kevin Modzelewski in :gh:`90536`.) + CPython bytecode changes ======================== diff --git a/Makefile.pre.in b/Makefile.pre.in index c647853c2238..ae7735cf69ad 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -640,6 +640,16 @@ profile-opt: profile-run-stamp -rm -f profile-clean-stamp $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)" +bolt-opt: @PREBOLT_RULE@ + rm -f *.fdata + @LLVM_BOLT@ ./$(BUILDPYTHON) -instrument -instrumentation-file-append-pid -instrumentation-file=$(abspath $(BUILDPYTHON).bolt) -o $(BUILDPYTHON).bolt_inst + ./$(BUILDPYTHON).bolt_inst $(PROFILE_TASK) || true + @MERGE_FDATA@ $(BUILDPYTHON).*.fdata > $(BUILDPYTHON).fdata + @LLVM_BOLT@ ./$(BUILDPYTHON) -o $(BUILDPYTHON).bolt -data=$(BUILDPYTHON).fdata -update-debug-sections -reorder-blocks=ext-tsp -reorder-functions=hfsort+ -split-functions=3 -icf=1 -inline-all -split-eh -reorder-functions-use-hot-size -peepholes=all -jump-tables=aggressive -inline-ap -indirect-call-promotion=all -dyno-stats -use-gnu-stack -frame-opt=hot + rm -f *.fdata + rm -f $(BUILDPYTHON).bolt_inst + mv $(BUILDPYTHON).bolt $(BUILDPYTHON) + # Compile and run with gcov .PHONY=coverage coverage-lcov coverage-report coverage: diff --git a/Misc/ACKS b/Misc/ACKS index c1f570acaaf8..16a482e40a51 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1212,6 +1212,7 @@ Gideon Mitchell Tim Mitchell Zubin Mithra Florian Mladitsch +Kevin Modzelewski Doug Moen Jakub Molinski Juliette Monsel diff --git a/Misc/NEWS.d/next/Build/2022-08-12-13-06-03.gh-issue-90536.qMpF6p.rst b/Misc/NEWS.d/next/Build/2022-08-12-13-06-03.gh-issue-90536.qMpF6p.rst new file mode 100644 index 000000000000..4605e03915ee --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-08-12-13-06-03.gh-issue-90536.qMpF6p.rst @@ -0,0 +1,2 @@ +Use the BOLT post-link optimizer to improve performance, particularly on +medium-to-large applications. diff --git a/configure b/configure index 82b55a3745d5..fb3a3c3fc8fc 100755 --- a/configure +++ b/configure @@ -887,6 +887,9 @@ LLVM_PROF_FILE LLVM_PROF_MERGER PGO_PROF_USE_FLAG PGO_PROF_GEN_FLAG +MERGE_FDATA +LLVM_BOLT +PREBOLT_RULE LLVM_AR_FOUND LLVM_AR PROFILE_TASK @@ -1049,6 +1052,7 @@ enable_pystats with_assertions enable_optimizations with_lto +enable_bolt with_address_sanitizer with_memory_sanitizer with_undefined_behavior_sanitizer @@ -1774,6 +1778,8 @@ Optional Features: --enable-pystats enable internal statistics gathering (default is no) --enable-optimizations enable expensive, stable optimizations (PGO, etc.) (default is no) + --enable-bolt enable usage of the llvm-bolt post-link optimizer + (default is no) --enable-loadable-sqlite-extensions support loadable extensions in the sqlite3 module, see Doc/library/sqlite3.rst (default is no) @@ -7878,6 +7884,261 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" fi +# Enable bolt flags +Py_BOLT='false' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-bolt" >&5 +$as_echo_n "checking for --enable-bolt... " >&6; } +# Check whether --enable-bolt was given. +if test "${enable_bolt+set}" = set; then : + enableval=$enable_bolt; +if test "$enableval" != no +then + Py_BOLT='true' + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; +else + Py_BOLT='false' + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # These flags are required for bolt to work: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + # Designate the DWARF version into 4 since the LLVM-BOLT does not support DWARF5 yet. + CFLAGS="$CFLAGS -gdwarf-4" + LDFLAGS="$LDFLAGS -gdwarf-4" + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-bolt", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-bolt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LLVM_BOLT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_BOLT="$LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_BOLT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +LLVM_BOLT=$ac_cv_path_LLVM_BOLT +if test -n "$LLVM_BOLT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_BOLT" >&5 +$as_echo "$LLVM_BOLT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LLVM_BOLT"; then + ac_pt_LLVM_BOLT=$LLVM_BOLT + # Extract the first word of "llvm-bolt", so it can be a program name with args. +set dummy llvm-bolt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_LLVM_BOLT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_BOLT="$ac_pt_LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_BOLT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_LLVM_BOLT=$ac_cv_path_ac_pt_LLVM_BOLT +if test -n "$ac_pt_LLVM_BOLT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_BOLT" >&5 +$as_echo "$ac_pt_LLVM_BOLT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_LLVM_BOLT" = x; then + LLVM_BOLT="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LLVM_BOLT=$ac_pt_LLVM_BOLT + fi +else + LLVM_BOLT="$ac_cv_path_LLVM_BOLT" +fi + + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Found llvm-bolt\"" >&5 +$as_echo "\"Found llvm-bolt\"" >&6; } + else + as_fn_error $? "llvm-bolt is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi + + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}merge-fdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}merge-fdata; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MERGE_FDATA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_MERGE_FDATA="$MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MERGE_FDATA="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MERGE_FDATA=$ac_cv_path_MERGE_FDATA +if test -n "$MERGE_FDATA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MERGE_FDATA" >&5 +$as_echo "$MERGE_FDATA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_MERGE_FDATA"; then + ac_pt_MERGE_FDATA=$MERGE_FDATA + # Extract the first word of "merge-fdata", so it can be a program name with args. +set dummy merge-fdata; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_MERGE_FDATA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_MERGE_FDATA="$ac_pt_MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_MERGE_FDATA="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_MERGE_FDATA=$ac_cv_path_ac_pt_MERGE_FDATA +if test -n "$ac_pt_MERGE_FDATA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_MERGE_FDATA" >&5 +$as_echo "$ac_pt_MERGE_FDATA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_MERGE_FDATA" = x; then + MERGE_FDATA="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MERGE_FDATA=$ac_pt_MERGE_FDATA + fi +else + MERGE_FDATA="$ac_cv_path_MERGE_FDATA" +fi + + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Found merge-fdata\"" >&5 +$as_echo "\"Found merge-fdata\"" >&6; } + else + as_fn_error $? "merge-fdata is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi +fi + # Enable PGO flags. diff --git a/configure.ac b/configure.ac index 85d9e8011835..bab405e6ed3c 100644 --- a/configure.ac +++ b/configure.ac @@ -1917,6 +1917,59 @@ if test "$Py_LTO" = 'true' ; then LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" fi +# Enable bolt flags +Py_BOLT='false' +AC_MSG_CHECKING(for --enable-bolt) +AC_ARG_ENABLE(bolt, AS_HELP_STRING( + [--enable-bolt], + [enable usage of the llvm-bolt post-link optimizer (default is no)]), +[ +if test "$enableval" != no +then + Py_BOLT='true' + AC_MSG_RESULT(yes); +else + Py_BOLT='false' + AC_MSG_RESULT(no); +fi], +[AC_MSG_RESULT(no)]) + +AC_SUBST(PREBOLT_RULE) +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # These flags are required for bolt to work: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + # Designate the DWARF version into 4 since the LLVM-BOLT does not support DWARF5 yet. + CFLAGS="$CFLAGS -gdwarf-4" + LDFLAGS="$LDFLAGS -gdwarf-4" + AC_SUBST(LLVM_BOLT) + AC_PATH_TOOL(LLVM_BOLT, llvm-bolt, '', ${llvm_path}) + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + AC_MSG_RESULT("Found llvm-bolt") + else + AC_MSG_ERROR([llvm-bolt is required for a --enable-bolt build but could not be found.]) + fi + + AC_SUBST(MERGE_FDATA) + AC_PATH_TOOL(MERGE_FDATA, merge-fdata, '', ${llvm_path}) + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + AC_MSG_RESULT("Found merge-fdata") + else + AC_MSG_ERROR([merge-fdata is required for a --enable-bolt build but could not be found.]) + fi +fi + # Enable PGO flags. AC_SUBST(PGO_PROF_GEN_FLAG) AC_SUBST(PGO_PROF_USE_FLAG) From webhook-mailer at python.org Thu Aug 18 18:38:57 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 18 Aug 2022 22:38:57 -0000 Subject: [Python-checkins] GH-93179: Document the thread safety of functools.lru_cache (GH-95970) Message-ID: <mailman.723.1660862338.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ba4bb7e4649be99d5d6b4151a1bd2eac89ef97f2 commit: ba4bb7e4649be99d5d6b4151a1bd2eac89ef97f2 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-18T17:38:49-05:00 summary: GH-93179: Document the thread safety of functools.lru_cache (GH-95970) files: M Doc/library/functools.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 00aca09bc7a..47cbe59fa49 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -49,6 +49,9 @@ The :mod:`functools` module defines the following functions: >>> factorial(12) # makes two new recursive calls, the other 10 are cached 479001600 + The cache is threadsafe so the wrapped function can be used in multiple + threads. + .. versionadded:: 3.9 @@ -140,6 +143,9 @@ The :mod:`functools` module defines the following functions: *maxsize* most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments. + The cache is threadsafe so the wrapped function can be used in multiple + threads. + Since a dictionary is used to cache results, the positional and keyword arguments to the function must be hashable. From webhook-mailer at python.org Thu Aug 18 19:46:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 18 Aug 2022 23:46:21 -0000 Subject: [Python-checkins] gh-95463: Remove backwards incompatible change regarding the _MASK_UTF_FILENAME flags in bpo-28080 (GH-96072) Message-ID: <mailman.724.1660866382.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9d066e2aa621125cd141b14df79955d74b7f258e commit: 9d066e2aa621125cd141b14df79955d74b7f258e branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T16:45:55-07:00 summary: gh-95463: Remove backwards incompatible change regarding the _MASK_UTF_FILENAME flags in bpo-28080 (GH-96072) Automerge-Triggered-By: GH:pablogsal files: A Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst M Lib/zipfile.py diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 981560082ca..903d09dc023 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -480,7 +480,7 @@ def FileHeader(self, zip64=None): def _encodeFilenameFlags(self): try: - return self.filename.encode('ascii'), self.flag_bits & ~_MASK_UTF_FILENAME + return self.filename.encode('ascii'), self.flag_bits except UnicodeEncodeError: return self.filename.encode('utf-8'), self.flag_bits | _MASK_UTF_FILENAME diff --git a/Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst b/Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst new file mode 100644 index 00000000000..553c55436aa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst @@ -0,0 +1,2 @@ +Remove an incompatible change from :issue:`28080` that caused a regression +that ignored the utf8 in ``ZipInfo.flag_bits``. Patch by Pablo Galindo. From webhook-mailer at python.org Thu Aug 18 19:53:08 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 18 Aug 2022 23:53:08 -0000 Subject: [Python-checkins] gh-95914: Add Py_UNICODE encode APIs removed in PEP 624 to 3.11 What's New (#96016) Message-ID: <mailman.725.1660866789.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b6d88b7225c36821845d4ba1312a6d6b2f7f65c8 commit: b6d88b7225c36821845d4ba1312a6d6b2f7f65c8 branch: main author: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-19T00:52:59+01:00 summary: gh-95914: Add Py_UNICODE encode APIs removed in PEP 624 to 3.11 What's New (#96016) * 3.11 Whatsnew: Add Py_UNICODE encode functions removed in PEP 624 * Just use :func: instead of :c:func: for non-resolved funcs so ! works files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 27a038292f9..2159a3175b9 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -2136,5 +2136,30 @@ Removed API). (Contributed by Victor Stinner in :issue:`45412`.) +* Remove the :c:type:`Py_UNICODE` encoder APIs, + as they have been deprecated since Python 3.3, + are little used + and are inefficient relative to the recommended alternatives. + + The removed functions are: + + * :func:`!PyUnicode_Encode` + * :func:`!PyUnicode_EncodeASCII` + * :func:`!PyUnicode_EncodeLatin1` + * :func:`!PyUnicode_EncodeUTF7` + * :func:`!PyUnicode_EncodeUTF8` + * :func:`!PyUnicode_EncodeUTF16` + * :func:`!PyUnicode_EncodeUTF32` + * :func:`!PyUnicode_EncodeUnicodeEscape` + * :func:`!PyUnicode_EncodeRawUnicodeEscape` + * :func:`!PyUnicode_EncodeCharmap` + * :func:`!PyUnicode_TranslateCharmap` + * :func:`!PyUnicode_EncodeDecimal` + * :func:`!PyUnicode_TransformDecimalToASCII` + + See :pep:`624` for details and + :pep:`migration guidance <624#alternative-apis>`. + (Contributed by Inada Naoki in :issue:`44029`.) + .. _libb2: https://www.blake2.net/ From webhook-mailer at python.org Thu Aug 18 20:00:44 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 00:00:44 -0000 Subject: [Python-checkins] gh-95914: Add Py_UNICODE encode APIs removed in PEP 624 to 3.11 What's New (GH-96016) Message-ID: <mailman.726.1660867244.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bb37d29576428f31e0b5a20ed8fd7b77d1168e95 commit: bb37d29576428f31e0b5a20ed8fd7b77d1168e95 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T17:00:38-07:00 summary: gh-95914: Add Py_UNICODE encode APIs removed in PEP 624 to 3.11 What's New (GH-96016) * 3.11 Whatsnew: Add Py_UNICODE encode functions removed in PEP 624 * Just use :func: instead of :c:func: for non-resolved funcs so ! works (cherry picked from commit b6d88b7225c36821845d4ba1312a6d6b2f7f65c8) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 92c66ebf2f8..51ce7da47ae 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -2124,5 +2124,30 @@ Removed API). (Contributed by Victor Stinner in :issue:`45412`.) +* Remove the :c:type:`Py_UNICODE` encoder APIs, + as they have been deprecated since Python 3.3, + are little used + and are inefficient relative to the recommended alternatives. + + The removed functions are: + + * :func:`!PyUnicode_Encode` + * :func:`!PyUnicode_EncodeASCII` + * :func:`!PyUnicode_EncodeLatin1` + * :func:`!PyUnicode_EncodeUTF7` + * :func:`!PyUnicode_EncodeUTF8` + * :func:`!PyUnicode_EncodeUTF16` + * :func:`!PyUnicode_EncodeUTF32` + * :func:`!PyUnicode_EncodeUnicodeEscape` + * :func:`!PyUnicode_EncodeRawUnicodeEscape` + * :func:`!PyUnicode_EncodeCharmap` + * :func:`!PyUnicode_TranslateCharmap` + * :func:`!PyUnicode_EncodeDecimal` + * :func:`!PyUnicode_TransformDecimalToASCII` + + See :pep:`624` for details and + :pep:`migration guidance <624#alternative-apis>`. + (Contributed by Inada Naoki in :issue:`44029`.) + .. _libb2: https://www.blake2.net/ From webhook-mailer at python.org Thu Aug 18 20:12:19 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 00:12:19 -0000 Subject: [Python-checkins] gh-95463: Remove backwards incompatible change regarding the _MASK_UTF_FILENAME flags in bpo-28080 (GH-96072) Message-ID: <mailman.727.1660867941.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7a84ce5c44845066628ea7be01a09bed70acbeae commit: 7a84ce5c44845066628ea7be01a09bed70acbeae branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-18T17:12:15-07:00 summary: gh-95463: Remove backwards incompatible change regarding the _MASK_UTF_FILENAME flags in bpo-28080 (GH-96072) Automerge-Triggered-By: GH:pablogsal (cherry picked from commit 9d066e2aa621125cd141b14df79955d74b7f258e) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: A Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst M Lib/zipfile.py diff --git a/Lib/zipfile.py b/Lib/zipfile.py index fe5c186deff..de667a7efee 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -480,7 +480,7 @@ def FileHeader(self, zip64=None): def _encodeFilenameFlags(self): try: - return self.filename.encode('ascii'), self.flag_bits & ~_MASK_UTF_FILENAME + return self.filename.encode('ascii'), self.flag_bits except UnicodeEncodeError: return self.filename.encode('utf-8'), self.flag_bits | _MASK_UTF_FILENAME diff --git a/Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst b/Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst new file mode 100644 index 00000000000..553c55436aa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-18-14-53-53.gh-issue-95463.GpP05c.rst @@ -0,0 +1,2 @@ +Remove an incompatible change from :issue:`28080` that caused a regression +that ignored the utf8 in ``ZipInfo.flag_bits``. Patch by Pablo Galindo. From webhook-mailer at python.org Fri Aug 19 00:57:12 2022 From: webhook-mailer at python.org (rhettinger) Date: Fri, 19 Aug 2022 04:57:12 -0000 Subject: [Python-checkins] GH-95822: Need _PyType_Lookup() in descriptor howto code equivalent. (GH-95967) Message-ID: <mailman.728.1660885033.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6740680b575249e498e3ca2b55d262baf9db6521 commit: 6740680b575249e498e3ca2b55d262baf9db6521 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-18T23:56:58-05:00 summary: GH-95822: Need _PyType_Lookup() in descriptor howto code equivalent. (GH-95967) files: M Doc/howto/descriptor.rst diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 5e9b110f0fe2..91a6c31c33b8 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -582,11 +582,18 @@ a pure Python equivalent: .. testcode:: + def find_name_in_mro(cls, name, default): + "Emulate _PyType_Lookup() in Objects/typeobject.c" + for base in cls.__mro__: + if name in vars(base): + return vars(base)[name] + return default + def object_getattribute(obj, name): "Emulate PyObject_GenericGetAttr() in Objects/object.c" null = object() objtype = type(obj) - cls_var = getattr(objtype, name, null) + cls_var = find_name_in_mro(objtype, name, null) descr_get = getattr(type(cls_var), '__get__', null) if descr_get is not null: if (hasattr(type(cls_var), '__set__') @@ -663,6 +670,15 @@ a pure Python equivalent: def __getattr__(self, name): return ('getattr_hook', self, name) + class D1: + def __get__(self, obj, objtype=None): + return type(self), obj, objtype + + class U1: + x = D1() + + class U2(U1): + pass .. doctest:: :hide: @@ -696,6 +712,10 @@ a pure Python equivalent: >>> b.g == b['g'] == ('getattr_hook', b, 'g') True + >>> u2 = U2() + >>> object_getattribute(u2, 'x') == u2.x == (D1, u2, U2) + True + Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__` code. That is why calling :meth:`__getattribute__` directly or with ``super().__getattribute__`` will bypass :meth:`__getattr__` entirely. From webhook-mailer at python.org Fri Aug 19 01:19:09 2022 From: webhook-mailer at python.org (rhettinger) Date: Fri, 19 Aug 2022 05:19:09 -0000 Subject: [Python-checkins] GH-95822: Need _PyType_Lookup() in descriptor howto code equivalent. (GH-95967) (#96100) Message-ID: <mailman.729.1660886350.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b6e8304b25e3a83e33b280405f6e37516cad1522 commit: b6e8304b25e3a83e33b280405f6e37516cad1522 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-19T00:18:59-05:00 summary: GH-95822: Need _PyType_Lookup() in descriptor howto code equivalent. (GH-95967) (#96100) files: M Doc/howto/descriptor.rst diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index f2e2f7ee68c2..6e7719e03f07 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -582,11 +582,18 @@ a pure Python equivalent: .. testcode:: + def find_name_in_mro(cls, name, default): + "Emulate _PyType_Lookup() in Objects/typeobject.c" + for base in cls.__mro__: + if name in vars(base): + return vars(base)[name] + return default + def object_getattribute(obj, name): "Emulate PyObject_GenericGetAttr() in Objects/object.c" null = object() objtype = type(obj) - cls_var = getattr(objtype, name, null) + cls_var = find_name_in_mro(objtype, name, null) descr_get = getattr(type(cls_var), '__get__', null) if descr_get is not null: if (hasattr(type(cls_var), '__set__') @@ -663,6 +670,15 @@ a pure Python equivalent: def __getattr__(self, name): return ('getattr_hook', self, name) + class D1: + def __get__(self, obj, objtype=None): + return type(self), obj, objtype + + class U1: + x = D1() + + class U2(U1): + pass .. doctest:: :hide: @@ -696,6 +712,10 @@ a pure Python equivalent: >>> b.g == b['g'] == ('getattr_hook', b, 'g') True + >>> u2 = U2() + >>> object_getattribute(u2, 'x') == u2.x == (D1, u2, U2) + True + Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__` code. That is why calling :meth:`__getattribute__` directly or with ``super().__getattribute__`` will bypass :meth:`__getattr__` entirely. From webhook-mailer at python.org Fri Aug 19 01:19:09 2022 From: webhook-mailer at python.org (rhettinger) Date: Fri, 19 Aug 2022 05:19:09 -0000 Subject: [Python-checkins] GH-95822: Need _PyType_Lookup() in descriptor howto code equivalent. (GH-95967) (#96099) Message-ID: <mailman.730.1660886350.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d6990681b66af2cb004deba51ffcd2f4dce0a9eb commit: d6990681b66af2cb004deba51ffcd2f4dce0a9eb branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-19T00:18:44-05:00 summary: GH-95822: Need _PyType_Lookup() in descriptor howto code equivalent. (GH-95967) (#96099) files: M Doc/howto/descriptor.rst diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 5e9b110f0fe2..91a6c31c33b8 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -582,11 +582,18 @@ a pure Python equivalent: .. testcode:: + def find_name_in_mro(cls, name, default): + "Emulate _PyType_Lookup() in Objects/typeobject.c" + for base in cls.__mro__: + if name in vars(base): + return vars(base)[name] + return default + def object_getattribute(obj, name): "Emulate PyObject_GenericGetAttr() in Objects/object.c" null = object() objtype = type(obj) - cls_var = getattr(objtype, name, null) + cls_var = find_name_in_mro(objtype, name, null) descr_get = getattr(type(cls_var), '__get__', null) if descr_get is not null: if (hasattr(type(cls_var), '__set__') @@ -663,6 +670,15 @@ a pure Python equivalent: def __getattr__(self, name): return ('getattr_hook', self, name) + class D1: + def __get__(self, obj, objtype=None): + return type(self), obj, objtype + + class U1: + x = D1() + + class U2(U1): + pass .. doctest:: :hide: @@ -696,6 +712,10 @@ a pure Python equivalent: >>> b.g == b['g'] == ('getattr_hook', b, 'g') True + >>> u2 = U2() + >>> object_getattribute(u2, 'x') == u2.x == (D1, u2, U2) + True + Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__` code. That is why calling :meth:`__getattribute__` directly or with ``super().__getattribute__`` will bypass :meth:`__getattr__` entirely. From webhook-mailer at python.org Fri Aug 19 02:08:50 2022 From: webhook-mailer at python.org (tiran) Date: Fri, 19 Aug 2022 06:08:50 -0000 Subject: [Python-checkins] gh-96017: Fix some compiler warnings (GH-96018) Message-ID: <mailman.731.1660889331.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d9c1b746b5013f81d1724757bb3c6a1c87c4a8dc commit: d9c1b746b5013f81d1724757bb3c6a1c87c4a8dc branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-19T08:08:43+02:00 summary: gh-96017: Fix some compiler warnings (GH-96018) - "comparison of integers of different signs" in typeobject.c - only define static_builtin_index_is_set in DEBUG builds - only define recreate_gil with ifdef HAVE_FORK files: M Objects/typeobject.c M Python/ceval_gil.h diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e8c36cf1539..e61acd295ac 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -70,11 +70,13 @@ static inline PyTypeObject * subclass_from_ref(PyObject *ref); /* helpers for for static builtin types */ +#ifndef NDEBUG static inline int static_builtin_index_is_set(PyTypeObject *self) { return self->tp_subclasses != NULL; } +#endif static inline size_t static_builtin_index_get(PyTypeObject *self) diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h index 1b2dc7f8e1d..4c71edd682b 100644 --- a/Python/ceval_gil.h +++ b/Python/ceval_gil.h @@ -133,12 +133,14 @@ static void destroy_gil(struct _gil_runtime_state *gil) _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); } +#ifdef HAVE_FORK static void recreate_gil(struct _gil_runtime_state *gil) { _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); /* XXX should we destroy the old OS resources here? */ create_gil(gil); } +#endif static void drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, From webhook-mailer at python.org Fri Aug 19 02:20:57 2022 From: webhook-mailer at python.org (rhettinger) Date: Fri, 19 Aug 2022 06:20:57 -0000 Subject: [Python-checkins] gh-96039: Corrected wording error in itertools doc (GH-96105) Message-ID: <mailman.732.1660890058.3313.python-checkins@python.org> https://github.com/python/cpython/commit/757c383d2465ce87f546f01568ec911bd226a084 commit: 757c383d2465ce87f546f01568ec911bd226a084 branch: main author: MrSuspicious <40614250+MrSuspicious0 at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-19T01:20:45-05:00 summary: gh-96039: Corrected wording error in itertools doc (GH-96105) files: M Doc/library/itertools.rst diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 416c4eca5eb..55a4c90137f 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -668,7 +668,7 @@ loops that truncate the stream. the tee objects being informed. ``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be - raised when using simultaneously iterators returned by the same :func:`tee` + raised when simultaneously using iterators returned by the same :func:`tee` call, even if the original *iterable* is threadsafe. This itertool may require significant auxiliary storage (depending on how From webhook-mailer at python.org Fri Aug 19 02:36:28 2022 From: webhook-mailer at python.org (tiran) Date: Fri, 19 Aug 2022 06:36:28 -0000 Subject: [Python-checkins] gh-95853: WASM: better version and asset handling in scripts (GH-96045) Message-ID: <mailman.733.1660890989.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6087f491ea1e4c8c115bb02d95e391399c0d6fe7 commit: 6087f491ea1e4c8c115bb02d95e391399c0d6fe7 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-19T08:36:12+02:00 summary: gh-95853: WASM: better version and asset handling in scripts (GH-96045) - support EMSDK tot-upstream and git releases - allow WASM assents for wasm64-emscripten and WASI. This makes single file distributions on WASI easier. - decouple WASM assets from browser builds files: M Makefile.pre.in M Tools/wasm/wasm_assets.py M Tools/wasm/wasm_build.py M configure M configure.ac diff --git a/Makefile.pre.in b/Makefile.pre.in index ae7735cf69a..414e6045b4d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -803,10 +803,11 @@ $(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) # wasm assets directory is relative to current build dir, e.g. "./usr/local". # --preload-file turns a relative asset path into an absolute path. +.PHONY: wasm_stdlib +wasm_stdlib: $(WASM_STDLIB) $(WASM_STDLIB): $(srcdir)/Lib/*.py $(srcdir)/Lib/*/*.py \ $(srcdir)/Tools/wasm/wasm_assets.py \ - Makefile pybuilddir.txt Modules/Setup.local \ - python.html python.worker.js + Makefile pybuilddir.txt Modules/Setup.local $(PYTHON_FOR_BUILD) $(srcdir)/Tools/wasm/wasm_assets.py \ --buildroot . --prefix $(prefix) diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py index 695e6ffc31f..a300d594414 100755 --- a/Tools/wasm/wasm_assets.py +++ b/Tools/wasm/wasm_assets.py @@ -108,6 +108,14 @@ "_zoneinfo": ["zoneinfo/"], } +SYSCONFIG_NAMES = ( + "_sysconfigdata__emscripten_wasm32-emscripten", + "_sysconfigdata__emscripten_wasm32-emscripten", + "_sysconfigdata__wasi_wasm32-wasi", + "_sysconfigdata__wasi_wasm64-wasi", +) + + def get_builddir(args: argparse.Namespace) -> pathlib.Path: """Get builddir path from pybuilddir.txt """ @@ -120,7 +128,11 @@ def get_sysconfigdata(args: argparse.Namespace) -> pathlib.Path: """Get path to sysconfigdata relative to build root """ data_name = sysconfig._get_sysconfigdata_name() - assert "emscripten_wasm32" in data_name + if not data_name.startswith(SYSCONFIG_NAMES): + raise ValueError( + f"Invalid sysconfig data name '{data_name}'.", + SYSCONFIG_NAMES + ) filename = data_name + ".py" return args.builddir / filename diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py index df90f01a27b..5ccf88cbc44 100755 --- a/Tools/wasm/wasm_build.py +++ b/Tools/wasm/wasm_build.py @@ -20,6 +20,7 @@ import dataclasses import os import pathlib +import re import shlex import shutil import subprocess @@ -99,6 +100,24 @@ def get_emscripten_root(emconfig: pathlib.Path = EM_CONFIG) -> pathlib.PurePath: EMSCRIPTEN_ROOT = get_emscripten_root() +def read_python_version(configure: pathlib.Path = CONFIGURE) -> str: + """Read PACKAGE_VERSION from configure script + + configure and configure.ac are the canonical source for major and + minor version number. + """ + version_re = re.compile("^PACKAGE_VERSION='(\d\.\d+)'") + with configure.open(encoding="utf-8") as f: + for line in f: + mo = version_re.match(line) + if mo: + return mo.group(1) + raise ValueError(f"PACKAGE_VERSION not found in {configure}") + + +PYTHON_VERSION = read_python_version() + + class ConditionError(ValueError): def __init__(self, info: str, text: str): self.info = info @@ -174,6 +193,9 @@ def _check_emscripten(): raise MissingDependency(os.fspath(version_txt), INSTALL_EMSDK) with open(version_txt) as f: version = f.read().strip().strip('"') + if version.endswith("-git"): + # git / upstream / tot-upstream installation + version = version[:-4] version_tuple = tuple(int(v) for v in version.split(".")) if version_tuple < EMSDK_MIN_VERSION: raise MissingDependency( @@ -221,7 +243,7 @@ def _check_wasi(): # workaround for https://github.com/python/cpython/issues/95952 "HOSTRUNNER": ( "wasmtime run " - "--env PYTHONPATH=/{relbuilddir}/build/lib.wasi-wasm32-$(VERSION):/Lib " + "--env PYTHONPATH=/{relbuilddir}/build/lib.wasi-wasm32-{version}:/Lib " "--mapdir /::{srcdir} --" ), }, @@ -362,6 +384,7 @@ def getenv(self) -> dict: env[key] = value.format( relbuilddir=self.builddir.relative_to(SRCDIR), srcdir=SRCDIR, + version=PYTHON_VERSION, ) else: env[key] = value diff --git a/configure b/configure index fb3a3c3fc8f..1801f806ae1 100755 --- a/configure +++ b/configure @@ -7038,7 +7038,7 @@ $as_echo "$LDLIBRARY" >&6; } # LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/browser*) : - LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB)' ;; #( + LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB) python.html python.worker.js' ;; #( *) : LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)' ;; diff --git a/configure.ac b/configure.ac index bab405e6ed3..bb9fec07242 100644 --- a/configure.ac +++ b/configure.ac @@ -1581,7 +1581,7 @@ AC_MSG_RESULT($LDLIBRARY) # LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], - [Emscripten/browser*], [LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB)'], + [Emscripten/browser*], [LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB) python.html python.worker.js'], [LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)'] ) LINK_PYTHON_DEPS='$(LIBRARY_DEPS)' From webhook-mailer at python.org Fri Aug 19 03:21:19 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 19 Aug 2022 07:21:19 -0000 Subject: [Python-checkins] gh-94635: Remove sqlite3 doc introduction heading (#96089) Message-ID: <mailman.734.1660893681.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ede771cdf90431d4db22f98e35f43888842f231e commit: ede771cdf90431d4db22f98e35f43888842f231e branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-19T09:21:11+02:00 summary: gh-94635: Remove sqlite3 doc introduction heading (#96089) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 540302437e7..7989bf9e0fc 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -11,9 +11,6 @@ .. _sqlite3-intro: -Introduction ------------- - SQLite is a C library that provides a lightweight disk-based database that doesn't require a separate server process and allows accessing the database using a nonstandard variant of the SQL query language. Some applications can use From webhook-mailer at python.org Fri Aug 19 03:28:43 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 07:28:43 -0000 Subject: [Python-checkins] gh-94635: Remove sqlite3 doc introduction heading (GH-96089) Message-ID: <mailman.735.1660894123.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c097fe0f09a775293f8508a47034cb5720ad58a9 commit: c097fe0f09a775293f8508a47034cb5720ad58a9 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T00:28:33-07:00 summary: gh-94635: Remove sqlite3 doc introduction heading (GH-96089) (cherry picked from commit ede771cdf90431d4db22f98e35f43888842f231e) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 64bab60ebe4..d503ec42f43 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -11,9 +11,6 @@ .. _sqlite3-intro: -Introduction ------------- - SQLite is a C library that provides a lightweight disk-based database that doesn't require a separate server process and allows accessing the database using a nonstandard variant of the SQL query language. Some applications can use From webhook-mailer at python.org Fri Aug 19 03:28:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 07:28:54 -0000 Subject: [Python-checkins] gh-94635: Remove sqlite3 doc introduction heading (GH-96089) Message-ID: <mailman.736.1660894135.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5e28ec54ff00473a048cb4430fe7724697010a1b commit: 5e28ec54ff00473a048cb4430fe7724697010a1b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T00:28:49-07:00 summary: gh-94635: Remove sqlite3 doc introduction heading (GH-96089) (cherry picked from commit ede771cdf90431d4db22f98e35f43888842f231e) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e5ddf61f7ad..7f9c737660a 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -11,9 +11,6 @@ .. _sqlite3-intro: -Introduction ------------- - SQLite is a C library that provides a lightweight disk-based database that doesn't require a separate server process and allows accessing the database using a nonstandard variant of the SQL query language. Some applications can use From webhook-mailer at python.org Fri Aug 19 03:30:56 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 19 Aug 2022 07:30:56 -0000 Subject: [Python-checkins] Docs: group sqlite3.Connection attributes and methods (#96090) Message-ID: <mailman.737.1660894257.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1a140af40b7204faf7896b67b8ef5af200427565 commit: 1a140af40b7204faf7896b67b8ef5af200427565 branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-19T09:30:41+02:00 summary: Docs: group sqlite3.Connection attributes and methods (#96090) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 7989bf9e0fc..a06b9f78065 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -545,6 +545,43 @@ Connection objects .. versionadded:: 3.2 + .. attribute:: row_factory + + A callable that accepts two arguments, + a :class:`Cursor` object and the raw row results as a :class:`tuple`, + and returns a custom object representing an SQLite row. + + Example: + + .. literalinclude:: ../includes/sqlite3/row_factory.py + + If returning a tuple doesn't suffice and you want name-based access to + columns, you should consider setting :attr:`row_factory` to the + highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both + index-based and case-insensitive name-based access to columns with almost no + memory overhead. It will probably be better than your own custom + dictionary-based approach or even a db_row based solution. + + .. XXX what's a db_row-based solution? + + .. attribute:: text_factory + + A callable that accepts a :class:`bytes` parameter and returns a text + representation of it. + The callable is invoked for SQLite values with the ``TEXT`` data type. + By default, this attribute is set to :class:`str`. + If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. + + Example: + + .. literalinclude:: ../includes/sqlite3/text_factory.py + + .. attribute:: total_changes + + Return the total number of database rows that have been modified, inserted, or + deleted since the database connection was opened. + + .. method:: cursor(factory=Cursor) Create and return a :class:`Cursor` object. @@ -856,45 +893,6 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.load_extension`` auditing event. - .. attribute:: row_factory - - A callable that accepts two arguments, - a :class:`Cursor` object and the raw row results as a :class:`tuple`, - and returns a custom object representing an SQLite row. - - Example: - - .. literalinclude:: ../includes/sqlite3/row_factory.py - - If returning a tuple doesn't suffice and you want name-based access to - columns, you should consider setting :attr:`row_factory` to the - highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both - index-based and case-insensitive name-based access to columns with almost no - memory overhead. It will probably be better than your own custom - dictionary-based approach or even a db_row based solution. - - .. XXX what's a db_row-based solution? - - - .. attribute:: text_factory - - A callable that accepts a :class:`bytes` parameter and returns a text - representation of it. - The callable is invoked for SQLite values with the ``TEXT`` data type. - By default, this attribute is set to :class:`str`. - If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. - - Example: - - .. literalinclude:: ../includes/sqlite3/text_factory.py - - - .. attribute:: total_changes - - Return the total number of database rows that have been modified, inserted, or - deleted since the database connection was opened. - - .. method:: iterdump Return an :term:`iterator` to dump the database as SQL source code. From webhook-mailer at python.org Fri Aug 19 03:38:01 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 07:38:01 -0000 Subject: [Python-checkins] Docs: group sqlite3.Connection attributes and methods (GH-96090) Message-ID: <mailman.738.1660894683.3313.python-checkins@python.org> https://github.com/python/cpython/commit/eed771154715546abd4f01351df994940ec8258a commit: eed771154715546abd4f01351df994940ec8258a branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T00:37:51-07:00 summary: Docs: group sqlite3.Connection attributes and methods (GH-96090) (cherry picked from commit 1a140af40b7204faf7896b67b8ef5af200427565) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index d503ec42f43..3b0eef71bf2 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -532,6 +532,43 @@ Connection objects .. versionadded:: 3.2 + .. attribute:: row_factory + + A callable that accepts two arguments, + a :class:`Cursor` object and the raw row results as a :class:`tuple`, + and returns a custom object representing an SQLite row. + + Example: + + .. literalinclude:: ../includes/sqlite3/row_factory.py + + If returning a tuple doesn't suffice and you want name-based access to + columns, you should consider setting :attr:`row_factory` to the + highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both + index-based and case-insensitive name-based access to columns with almost no + memory overhead. It will probably be better than your own custom + dictionary-based approach or even a db_row based solution. + + .. XXX what's a db_row-based solution? + + .. attribute:: text_factory + + A callable that accepts a :class:`bytes` parameter and returns a text + representation of it. + The callable is invoked for SQLite values with the ``TEXT`` data type. + By default, this attribute is set to :class:`str`. + If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. + + Example: + + .. literalinclude:: ../includes/sqlite3/text_factory.py + + .. attribute:: total_changes + + Return the total number of database rows that have been modified, inserted, or + deleted since the database connection was opened. + + .. method:: cursor(factory=Cursor) Create and return a :class:`Cursor` object. @@ -843,45 +880,6 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.load_extension`` auditing event. - .. attribute:: row_factory - - A callable that accepts two arguments, - a :class:`Cursor` object and the raw row results as a :class:`tuple`, - and returns a custom object representing an SQLite row. - - Example: - - .. literalinclude:: ../includes/sqlite3/row_factory.py - - If returning a tuple doesn't suffice and you want name-based access to - columns, you should consider setting :attr:`row_factory` to the - highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both - index-based and case-insensitive name-based access to columns with almost no - memory overhead. It will probably be better than your own custom - dictionary-based approach or even a db_row based solution. - - .. XXX what's a db_row-based solution? - - - .. attribute:: text_factory - - A callable that accepts a :class:`bytes` parameter and returns a text - representation of it. - The callable is invoked for SQLite values with the ``TEXT`` data type. - By default, this attribute is set to :class:`str`. - If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. - - Example: - - .. literalinclude:: ../includes/sqlite3/text_factory.py - - - .. attribute:: total_changes - - Return the total number of database rows that have been modified, inserted, or - deleted since the database connection was opened. - - .. method:: iterdump Return an :term:`iterator` to dump the database as SQL source code. From webhook-mailer at python.org Fri Aug 19 03:38:25 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 07:38:25 -0000 Subject: [Python-checkins] Docs: group sqlite3.Connection attributes and methods (GH-96090) Message-ID: <mailman.739.1660894706.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8a6e651e20cc57a0cf35b6eeae26ad50907c1baa commit: 8a6e651e20cc57a0cf35b6eeae26ad50907c1baa branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T00:38:21-07:00 summary: Docs: group sqlite3.Connection attributes and methods (GH-96090) (cherry picked from commit 1a140af40b7204faf7896b67b8ef5af200427565) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 7f9c737660a..d11fb18add6 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -495,6 +495,43 @@ Connection objects .. versionadded:: 3.2 + .. attribute:: row_factory + + A callable that accepts two arguments, + a :class:`Cursor` object and the raw row results as a :class:`tuple`, + and returns a custom object representing an SQLite row. + + Example: + + .. literalinclude:: ../includes/sqlite3/row_factory.py + + If returning a tuple doesn't suffice and you want name-based access to + columns, you should consider setting :attr:`row_factory` to the + highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both + index-based and case-insensitive name-based access to columns with almost no + memory overhead. It will probably be better than your own custom + dictionary-based approach or even a db_row based solution. + + .. XXX what's a db_row-based solution? + + .. attribute:: text_factory + + A callable that accepts a :class:`bytes` parameter and returns a text + representation of it. + The callable is invoked for SQLite values with the ``TEXT`` data type. + By default, this attribute is set to :class:`str`. + If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. + + Example: + + .. literalinclude:: ../includes/sqlite3/text_factory.py + + .. attribute:: total_changes + + Return the total number of database rows that have been modified, inserted, or + deleted since the database connection was opened. + + .. method:: cursor(factory=Cursor) Create and return a :class:`Cursor` object. @@ -724,45 +761,6 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.load_extension`` auditing event. - .. attribute:: row_factory - - A callable that accepts two arguments, - a :class:`Cursor` object and the raw row results as a :class:`tuple`, - and returns a custom object representing an SQLite row. - - Example: - - .. literalinclude:: ../includes/sqlite3/row_factory.py - - If returning a tuple doesn't suffice and you want name-based access to - columns, you should consider setting :attr:`row_factory` to the - highly optimized :class:`sqlite3.Row` type. :class:`Row` provides both - index-based and case-insensitive name-based access to columns with almost no - memory overhead. It will probably be better than your own custom - dictionary-based approach or even a db_row based solution. - - .. XXX what's a db_row-based solution? - - - .. attribute:: text_factory - - A callable that accepts a :class:`bytes` parameter and returns a text - representation of it. - The callable is invoked for SQLite values with the ``TEXT`` data type. - By default, this attribute is set to :class:`str`. - If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. - - Example: - - .. literalinclude:: ../includes/sqlite3/text_factory.py - - - .. attribute:: total_changes - - Return the total number of database rows that have been modified, inserted, or - deleted since the database connection was opened. - - .. method:: iterdump Return an :term:`iterator` to dump the database as SQL source code. From webhook-mailer at python.org Fri Aug 19 03:41:40 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 19 Aug 2022 07:41:40 -0000 Subject: [Python-checkins] Doc: Use consistent markup for example Point class in sqlite3 (#96095) Message-ID: <mailman.740.1660894900.3313.python-checkins@python.org> https://github.com/python/cpython/commit/303ef0913e5b80adbe63def41829bff5effab6a0 commit: 303ef0913e5b80adbe63def41829bff5effab6a0 branch: main author: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-19T09:41:16+02:00 summary: Doc: Use consistent markup for example Point class in sqlite3 (#96095) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index a06b9f78065..508505ca050 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1606,7 +1606,7 @@ registering custom adapter functions. Letting your object adapt itself """""""""""""""""""""""""""""""" -Suppose we have a ``Point`` class that represents a pair of coordinates, +Suppose we have a :class:`!Point` class that represents a pair of coordinates, ``x`` and ``y``, in a Cartesian coordinate system. The coordinate pair will be stored as a text string in the database, using a semicolon to separate the coordinates. @@ -1637,11 +1637,11 @@ values. To be able to convert *from* SQLite values *to* custom Python types, we use *converters*. -Let's go back to the :class:`Point` class. We stored the x and y coordinates +Let's go back to the :class:`!Point` class. We stored the x and y coordinates separated via semicolons as strings in SQLite. First, we'll define a converter function that accepts the string as a parameter -and constructs a :class:`Point` object from it. +and constructs a :class:`!Point` object from it. .. note:: From webhook-mailer at python.org Fri Aug 19 03:48:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 07:48:18 -0000 Subject: [Python-checkins] Doc: Use consistent markup for example Point class in sqlite3 (GH-96095) Message-ID: <mailman.741.1660895299.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f21d7e5150894037405e21d3622d1ee8ea0d687f commit: f21d7e5150894037405e21d3622d1ee8ea0d687f branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T00:48:03-07:00 summary: Doc: Use consistent markup for example Point class in sqlite3 (GH-96095) (cherry picked from commit 303ef0913e5b80adbe63def41829bff5effab6a0) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3b0eef71bf2..320656a9234 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1571,7 +1571,7 @@ registering custom adapter functions. Letting your object adapt itself """""""""""""""""""""""""""""""" -Suppose we have a ``Point`` class that represents a pair of coordinates, +Suppose we have a :class:`!Point` class that represents a pair of coordinates, ``x`` and ``y``, in a Cartesian coordinate system. The coordinate pair will be stored as a text string in the database, using a semicolon to separate the coordinates. @@ -1602,11 +1602,11 @@ values. To be able to convert *from* SQLite values *to* custom Python types, we use *converters*. -Let's go back to the :class:`Point` class. We stored the x and y coordinates +Let's go back to the :class:`!Point` class. We stored the x and y coordinates separated via semicolons as strings in SQLite. First, we'll define a converter function that accepts the string as a parameter -and constructs a :class:`Point` object from it. +and constructs a :class:`!Point` object from it. .. note:: From webhook-mailer at python.org Fri Aug 19 03:49:44 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 07:49:44 -0000 Subject: [Python-checkins] Doc: Use consistent markup for example Point class in sqlite3 (GH-96095) Message-ID: <mailman.742.1660895385.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d52834d5f57a1b6ac3249fc237bb34c7b2f5ca3e commit: d52834d5f57a1b6ac3249fc237bb34c7b2f5ca3e branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T00:49:39-07:00 summary: Doc: Use consistent markup for example Point class in sqlite3 (GH-96095) (cherry picked from commit 303ef0913e5b80adbe63def41829bff5effab6a0) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index d11fb18add6..3dff0293bf2 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1274,7 +1274,7 @@ registering custom adapter functions. Letting your object adapt itself """""""""""""""""""""""""""""""" -Suppose we have a ``Point`` class that represents a pair of coordinates, +Suppose we have a :class:`!Point` class that represents a pair of coordinates, ``x`` and ``y``, in a Cartesian coordinate system. The coordinate pair will be stored as a text string in the database, using a semicolon to separate the coordinates. @@ -1305,11 +1305,11 @@ values. To be able to convert *from* SQLite values *to* custom Python types, we use *converters*. -Let's go back to the :class:`Point` class. We stored the x and y coordinates +Let's go back to the :class:`!Point` class. We stored the x and y coordinates separated via semicolons as strings in SQLite. First, we'll define a converter function that accepts the string as a parameter -and constructs a :class:`Point` object from it. +and constructs a :class:`!Point` object from it. .. note:: From webhook-mailer at python.org Fri Aug 19 04:18:16 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Fri, 19 Aug 2022 08:18:16 -0000 Subject: [Python-checkins] Docs: Fix markup of module name in sqlite3 docs (#96115) Message-ID: <mailman.743.1660897097.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ee9f22d3464308566c63e972133ebf71b7664baa commit: ee9f22d3464308566c63e972133ebf71b7664baa branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-19T10:18:08+02:00 summary: Docs: Fix markup of module name in sqlite3 docs (#96115) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 508505ca050..6413d885918 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -18,13 +18,13 @@ SQLite for internal data storage. It's also possible to prototype an 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 an SQL interface +The :mod:`!sqlite3` module was written by Gerhard H?ring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and requires SQLite 3.7.15 or newer. This document includes four main sections: -* :ref:`sqlite3-tutorial` teaches how to use the sqlite3 module. +* :ref:`sqlite3-tutorial` teaches how to use the :mod:`!sqlite3` module. * :ref:`sqlite3-reference` describes the classes and functions this module defines. * :ref:`sqlite3-howtos` details how to handle specific tasks. @@ -839,7 +839,7 @@ Connection objects ignored. Note that the backend does not only run statements passed to the :meth:`Cursor.execute` methods. Other sources include the :ref:`transaction management <sqlite3-controlling-transactions>` of the - sqlite3 module and the execution of triggers defined in the current + :mod:`!sqlite3` module and the execution of triggers defined in the current database. Passing ``None`` as *trace_callback* will disable the trace callback. From webhook-mailer at python.org Fri Aug 19 04:25:37 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 08:25:37 -0000 Subject: [Python-checkins] Docs: Fix markup of module name in sqlite3 docs (GH-96115) Message-ID: <mailman.744.1660897537.3313.python-checkins@python.org> https://github.com/python/cpython/commit/442674e37eb84f9da5701412f8ad94e4eb2774fd commit: 442674e37eb84f9da5701412f8ad94e4eb2774fd branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T01:25:27-07:00 summary: Docs: Fix markup of module name in sqlite3 docs (GH-96115) (cherry picked from commit ee9f22d3464308566c63e972133ebf71b7664baa) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3dff0293bf2..d01c7b554e9 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -18,13 +18,13 @@ SQLite for internal data storage. It's also possible to prototype an 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 an SQL interface +The :mod:`!sqlite3` module was written by Gerhard H?ring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and requires SQLite 3.7.15 or newer. This document includes four main sections: -* :ref:`sqlite3-tutorial` teaches how to use the sqlite3 module. +* :ref:`sqlite3-tutorial` teaches how to use the :mod:`!sqlite3` module. * :ref:`sqlite3-reference` describes the classes and functions this module defines. * :ref:`sqlite3-howtos` details how to handle specific tasks. @@ -707,7 +707,7 @@ Connection objects ignored. Note that the backend does not only run statements passed to the :meth:`Cursor.execute` methods. Other sources include the :ref:`transaction management <sqlite3-controlling-transactions>` of the - sqlite3 module and the execution of triggers defined in the current + :mod:`!sqlite3` module and the execution of triggers defined in the current database. Passing ``None`` as *trace_callback* will disable the trace callback. From webhook-mailer at python.org Fri Aug 19 04:26:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 08:26:13 -0000 Subject: [Python-checkins] Docs: Fix markup of module name in sqlite3 docs (GH-96115) Message-ID: <mailman.745.1660897574.3313.python-checkins@python.org> https://github.com/python/cpython/commit/fcf04217abcb1dd8bf6cb179a8e465b1971c0d45 commit: fcf04217abcb1dd8bf6cb179a8e465b1971c0d45 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T01:26:08-07:00 summary: Docs: Fix markup of module name in sqlite3 docs (GH-96115) (cherry picked from commit ee9f22d3464308566c63e972133ebf71b7664baa) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 320656a9234..20ad760ac4b 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -18,13 +18,13 @@ SQLite for internal data storage. It's also possible to prototype an 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 an SQL interface +The :mod:`!sqlite3` module was written by Gerhard H?ring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and requires SQLite 3.7.15 or newer. This document includes four main sections: -* :ref:`sqlite3-tutorial` teaches how to use the sqlite3 module. +* :ref:`sqlite3-tutorial` teaches how to use the :mod:`!sqlite3` module. * :ref:`sqlite3-reference` describes the classes and functions this module defines. * :ref:`sqlite3-howtos` details how to handle specific tasks. @@ -826,7 +826,7 @@ Connection objects ignored. Note that the backend does not only run statements passed to the :meth:`Cursor.execute` methods. Other sources include the :ref:`transaction management <sqlite3-controlling-transactions>` of the - sqlite3 module and the execution of triggers defined in the current + :mod:`!sqlite3` module and the execution of triggers defined in the current database. Passing ``None`` as *trace_callback* will disable the trace callback. From webhook-mailer at python.org Fri Aug 19 05:20:55 2022 From: webhook-mailer at python.org (isidentical) Date: Fri, 19 Aug 2022 09:20:55 -0000 Subject: [Python-checkins] gh-96019: Fix caching of decompositions in makeunicodedata (GH-96020) Message-ID: <mailman.746.1660900856.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2d9f252c0c08bce0e776b38906c3bbb59a3bd2c5 commit: 2d9f252c0c08bce0e776b38906c3bbb59a3bd2c5 branch: main author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de> committer: isidentical <isidentical at gmail.com> date: 2022-08-19T12:20:44+03:00 summary: gh-96019: Fix caching of decompositions in makeunicodedata (GH-96020) files: A Misc/NEWS.d/next/Library/2022-08-19-10-19-32.gh-issue-96019.b7uAVP.rst M Modules/unicodedata_db.h M Tools/unicode/makeunicodedata.py diff --git a/Misc/NEWS.d/next/Library/2022-08-19-10-19-32.gh-issue-96019.b7uAVP.rst b/Misc/NEWS.d/next/Library/2022-08-19-10-19-32.gh-issue-96019.b7uAVP.rst new file mode 100644 index 000000000000..296963fd8172 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-19-10-19-32.gh-issue-96019.b7uAVP.rst @@ -0,0 +1,3 @@ +Fix a bug in the ``makeunicodedata.py`` script leading to about 13 KiB of +space saving in the ``unicodedata`` module, specifically the character +decomposition data. diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index f56fa035b685..e76631e8e7b0 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -3420,121 +3420,120 @@ static const unsigned int decomp_data[] = { 259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, 32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, 256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, - 59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, - 512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, - 769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, - 949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, - 512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, - 258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, - 258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, - 768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, - 1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, - 768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, - 1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, - 774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, - 1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, - 776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, - 1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, - 776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, - 1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, - 776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, - 1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, - 1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, - 514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, - 1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, - 2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, - 512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, - 2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, - 2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, - 512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, - 2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, - 3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, - 512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, - 3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, - 3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, - 514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, - 4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, - 512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, - 4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, - 4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, - 512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, - 6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, - 512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, - 65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, - 73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, - 80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259, - 7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, - 103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259, - 7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259, - 7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261, - 114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261, - 967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259, - 102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259, - 7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259, - 626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259, - 427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259, - 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66, - 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98, - 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68, - 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100, - 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274, - 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101, - 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71, - 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104, - 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72, - 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239, - 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75, - 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512, - 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512, - 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512, - 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512, - 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512, - 245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768, - 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775, - 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803, - 512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83, - 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347, - 775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512, - 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512, - 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512, - 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512, - 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512, - 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512, - 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512, - 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512, - 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512, - 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512, - 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512, - 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512, - 226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777, - 512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258, - 769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512, - 259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774, - 512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771, - 512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234, - 768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512, - 7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803, - 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777, - 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212, - 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512, - 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768, - 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416, - 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117, - 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512, - 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803, - 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803, - 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787, - 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937, - 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512, - 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944, - 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512, - 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788, - 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951, - 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512, - 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788, - 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512, - 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768, - 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, + 59, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, 512, 919, 769, + 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, 769, 512, 970, + 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, 949, 769, 512, + 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, 512, 965, 776, + 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, 258, 952, 258, + 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, 258, 954, 258, + 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, 768, 512, 1045, + 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, 1048, 768, 512, + 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, 768, 512, 1077, + 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, 1080, 768, 512, + 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, 774, 512, 1078, + 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, 1072, 776, 512, + 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, 776, 512, 1046, + 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, 1048, 772, 512, + 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, 776, 512, 1086, + 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, 1101, 776, 512, + 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, 776, 512, 1059, + 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, 1067, 776, 512, + 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, 1620, 512, 1608, + 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, 514, 1608, 1652, + 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, 1729, 1620, 512, + 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, 2364, 512, 2325, + 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, 512, 2337, 2364, + 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, 2503, 2494, 512, + 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, 2492, 512, 2610, + 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, 512, 2588, 2620, + 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, 2887, 2903, 512, + 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, 3006, 512, 3015, + 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, 512, 3270, 3285, + 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, 3398, 3390, 512, + 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, 3535, 512, 3548, + 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, 514, 3755, 3737, + 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, 4023, 512, 3921, + 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, 512, 3953, 3954, + 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, 4019, 3968, 514, + 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, 4023, 512, 4001, + 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, 512, 4133, 4142, + 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, 6965, 512, 6923, + 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, 512, 6972, 6965, + 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, 65, 259, 198, + 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, 73, 259, 74, + 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, 80, 259, 82, + 259, 84, 259, 85, 259, 87, 259, 592, 259, 593, 259, 7426, 259, 98, 259, + 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, 103, 259, 107, 259, + 109, 259, 331, 259, 596, 259, 7446, 259, 7447, 259, 112, 259, 116, 259, + 117, 259, 7453, 259, 623, 259, 118, 259, 7461, 259, 946, 259, 947, 259, + 948, 259, 966, 259, 967, 261, 105, 261, 114, 261, 117, 261, 118, 261, + 946, 261, 947, 261, 961, 261, 966, 261, 967, 259, 1085, 259, 594, 259, + 99, 259, 597, 259, 240, 259, 102, 259, 607, 259, 609, 259, 613, 259, 616, + 259, 617, 259, 618, 259, 7547, 259, 669, 259, 621, 259, 7557, 259, 671, + 259, 625, 259, 624, 259, 626, 259, 627, 259, 628, 259, 629, 259, 632, + 259, 642, 259, 643, 259, 427, 259, 649, 259, 650, 259, 7452, 259, 651, + 259, 652, 259, 122, 259, 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, + 512, 97, 805, 512, 66, 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, + 512, 66, 817, 512, 98, 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, + 512, 100, 775, 512, 68, 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, + 512, 68, 807, 512, 100, 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, + 512, 275, 768, 512, 274, 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, + 512, 69, 816, 512, 101, 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, + 512, 102, 775, 512, 71, 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, + 512, 72, 803, 512, 104, 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, + 512, 104, 807, 512, 72, 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, + 512, 207, 769, 512, 239, 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, + 512, 107, 803, 512, 75, 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, + 512, 7734, 772, 512, 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, + 813, 512, 108, 813, 512, 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, + 775, 512, 77, 803, 512, 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, + 803, 512, 110, 803, 512, 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, + 813, 512, 213, 769, 512, 245, 769, 512, 213, 776, 512, 245, 776, 512, + 332, 768, 512, 333, 768, 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, + 112, 769, 512, 80, 775, 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, + 82, 803, 512, 114, 803, 512, 7770, 772, 512, 7771, 772, 512, 82, 817, + 512, 114, 817, 512, 83, 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, + 512, 346, 775, 512, 347, 775, 512, 352, 775, 512, 353, 775, 512, 7778, + 775, 512, 7779, 775, 512, 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, + 803, 512, 84, 817, 512, 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, + 804, 512, 117, 804, 512, 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, + 813, 512, 360, 769, 512, 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, + 771, 512, 118, 771, 512, 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, + 768, 512, 87, 769, 512, 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, + 775, 512, 119, 775, 512, 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, + 775, 512, 88, 776, 512, 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, + 770, 512, 122, 770, 512, 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, + 817, 512, 104, 817, 512, 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, + 702, 512, 383, 775, 512, 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, + 777, 512, 194, 769, 512, 226, 769, 512, 194, 768, 512, 226, 768, 512, + 194, 777, 512, 226, 777, 512, 194, 771, 512, 226, 771, 512, 7840, 770, + 512, 7841, 770, 512, 258, 769, 512, 259, 769, 512, 258, 768, 512, 259, + 768, 512, 258, 777, 512, 259, 777, 512, 258, 771, 512, 259, 771, 512, + 7840, 774, 512, 7841, 774, 512, 69, 803, 512, 101, 803, 512, 69, 777, + 512, 101, 777, 512, 69, 771, 512, 101, 771, 512, 202, 769, 512, 234, 769, + 512, 202, 768, 512, 234, 768, 512, 202, 777, 512, 234, 777, 512, 202, + 771, 512, 234, 771, 512, 7864, 770, 512, 7865, 770, 512, 73, 777, 512, + 105, 777, 512, 73, 803, 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, + 79, 777, 512, 111, 777, 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, + 244, 768, 512, 212, 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, + 512, 7884, 770, 512, 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, + 768, 512, 417, 768, 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, + 417, 771, 512, 416, 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, + 85, 777, 512, 117, 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, + 432, 768, 512, 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, + 512, 431, 803, 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, + 512, 121, 803, 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, + 512, 945, 787, 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, + 769, 512, 7937, 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, + 913, 788, 512, 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, + 512, 7944, 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, + 768, 512, 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, + 917, 788, 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, + 512, 951, 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, + 769, 512, 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, + 919, 788, 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, + 512, 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, + 768, 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768, 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959, 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512, @@ -3561,124 +3560,121 @@ static const unsigned int decomp_data[] = { 8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772, 512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118, 837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913, - 837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834, - 512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, - 837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, - 512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, - 772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, - 774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, - 769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, - 944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, - 933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, - 168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, - 837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, - 768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, - 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258, - 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, - 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, - 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, - 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259, - 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, - 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50, - 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43, - 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261, - 120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261, - 112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115, - 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514, - 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262, - 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81, - 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, - 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262, - 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258, - 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915, - 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106, - 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49, - 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772, - 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54, - 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260, - 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86, - 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88, - 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258, - 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118, - 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105, - 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258, - 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512, - 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707, - 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514, - 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750, - 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824, - 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824, - 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, - 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, - 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, - 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, - 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, - 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, - 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, - 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, - 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, - 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, - 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, - 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, - 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, - 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, - 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, - 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, - 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, - 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, - 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, - 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, - 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, - 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, - 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, - 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, - 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, - 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, - 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, - 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, - 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, - 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, - 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, - 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, - 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, - 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863, - 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, - 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, - 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, - 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, - 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, - 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, - 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, - 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, - 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, - 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, - 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, - 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, - 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, - 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, - 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, - 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, - 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, - 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, - 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, - 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, - 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, - 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, - 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, - 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, - 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, - 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, - 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, - 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, - 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, - 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, - 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, - 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, - 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, - 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, - 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, - 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, - 21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, + 837, 514, 32, 787, 256, 953, 514, 32, 834, 512, 168, 834, 512, 8052, 837, + 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, 837, 512, 917, + 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, 512, 8127, 768, + 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, 772, 512, 970, + 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, 774, 512, 921, + 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, 769, 512, 8190, + 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, 944, 512, 961, + 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, 933, 774, 512, + 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, 168, 768, 256, + 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, 837, 512, 969, + 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, 768, 256, 911, + 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, 8195, 258, 32, + 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, 46, 514, + 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, 770, 8245, 8245, + 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, 33, 514, 33, 63, + 1026, 8242, 8242, 8242, 8242, 259, 48, 259, 105, 259, 52, 259, 53, 259, + 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, 8722, 259, 61, 259, 40, 259, + 41, 259, 110, 261, 48, 261, 49, 261, 50, 261, 51, 261, 52, 261, 53, 261, + 54, 261, 55, 261, 56, 261, 57, 261, 43, 261, 8722, 261, 61, 261, 40, 261, + 41, 261, 97, 261, 101, 261, 111, 261, 120, 261, 601, 261, 104, 261, 107, + 261, 108, 261, 109, 261, 110, 261, 112, 261, 115, 261, 116, 514, 82, 115, + 770, 97, 47, 99, 770, 97, 47, 115, 262, 67, 514, 176, 67, 770, 99, 47, + 111, 770, 99, 47, 117, 258, 400, 514, 176, 70, 262, 103, 262, 72, 262, + 104, 262, 295, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, + 80, 262, 81, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, 262, 90, + 256, 937, 256, 75, 256, 197, 262, 66, 262, 101, 262, 69, 262, 70, 262, + 77, 262, 111, 258, 1488, 258, 1489, 258, 1490, 258, 1491, 262, 105, 770, + 70, 65, 88, 262, 960, 262, 947, 262, 915, 262, 928, 262, 8721, 262, 68, + 262, 100, 262, 106, 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, + 49, 48, 772, 49, 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, + 8260, 53, 772, 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, + 53, 8260, 54, 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, + 772, 55, 8260, 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, + 514, 73, 86, 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, + 514, 73, 88, 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, + 258, 68, 258, 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, + 118, 258, 118, 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, + 105, 514, 105, 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, + 108, 258, 99, 258, 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, + 8594, 824, 512, 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, + 824, 512, 8707, 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, + 8741, 824, 514, 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, + 8750, 8750, 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, + 8776, 824, 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, + 512, 62, 824, 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, + 824, 512, 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, + 8834, 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, + 824, 512, 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, + 8829, 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, + 824, 512, 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, + 263, 50, 263, 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, + 519, 49, 48, 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, + 53, 519, 49, 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, + 40, 49, 41, 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, + 53, 41, 770, 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, + 41, 1026, 40, 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, + 1026, 40, 49, 51, 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, + 40, 49, 54, 41, 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, + 57, 41, 1026, 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, + 52, 46, 514, 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, + 770, 49, 48, 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, + 49, 52, 46, 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, + 56, 46, 770, 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, + 41, 770, 40, 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, + 41, 770, 40, 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, + 41, 770, 40, 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, + 41, 770, 40, 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, + 41, 770, 40, 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, + 41, 770, 40, 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, + 41, 263, 65, 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, + 72, 263, 73, 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, + 80, 263, 81, 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, + 88, 263, 89, 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, + 102, 263, 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, + 109, 263, 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, + 116, 263, 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, + 1026, 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, + 61, 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, + 40863, 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, + 20101, 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, + 20843, 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, + 20992, 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, + 21313, 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, + 21475, 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, + 22805, 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, + 23567, 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, + 24037, 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, + 24308, 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, + 24435, 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, + 25908, 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, + 26085, 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, + 27513, 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, + 27668, 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, + 29247, 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, + 29577, 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, + 30000, 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, + 30399, 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, + 31160, 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, + 31992, 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, + 32780, 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, + 33258, 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, + 33390, 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, + 34892, 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, + 35895, 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, + 36208, 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, + 36789, 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, + 38263, 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, + 38737, 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, + 38899, 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, + 39321, 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, + 39727, 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, + 40575, 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, + 40697, 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, + 40778, 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, + 12306, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, 12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, 512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, 12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, @@ -3844,43 +3840,42 @@ static const unsigned int decomp_data[] = { 51, 49, 26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 67, 259, 70, 259, 81, 259, 294, 259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 259, 653, 256, 35912, 256, 26356, 256, 36554, 256, - 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 40860, 256, - 22865, 256, 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 256, - 32645, 256, 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 256, - 27931, 256, 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 256, - 20098, 256, 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 256, - 23888, 256, 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 256, - 34847, 256, 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 256, - 20358, 256, 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 256, - 30439, 256, 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 256, - 39791, 256, 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 256, - 37636, 256, 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 256, - 32894, 256, 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 256, - 23650, 256, 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 256, - 38475, 256, 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 256, - 32190, 256, 33777, 256, 38517, 256, 35712, 256, 25295, 256, 27138, 256, - 35582, 256, 20025, 256, 23527, 256, 24594, 256, 29575, 256, 30064, 256, - 21271, 256, 30971, 256, 20415, 256, 24489, 256, 19981, 256, 27852, 256, - 25976, 256, 32034, 256, 21443, 256, 22622, 256, 30465, 256, 33865, 256, - 35498, 256, 27578, 256, 36784, 256, 27784, 256, 25342, 256, 33509, 256, - 25504, 256, 30053, 256, 20142, 256, 20841, 256, 20937, 256, 26753, 256, - 31975, 256, 33391, 256, 35538, 256, 37327, 256, 21237, 256, 21570, 256, - 22899, 256, 24300, 256, 26053, 256, 28670, 256, 31018, 256, 38317, 256, - 39530, 256, 40599, 256, 40654, 256, 21147, 256, 26310, 256, 27511, 256, - 36706, 256, 24180, 256, 24976, 256, 25088, 256, 25754, 256, 28451, 256, - 29001, 256, 29833, 256, 31178, 256, 32244, 256, 32879, 256, 36646, 256, - 34030, 256, 36899, 256, 37706, 256, 21015, 256, 21155, 256, 21693, 256, - 28872, 256, 35010, 256, 35498, 256, 24265, 256, 24565, 256, 25467, 256, - 27566, 256, 31806, 256, 29557, 256, 20196, 256, 22265, 256, 23527, 256, - 23994, 256, 24604, 256, 29618, 256, 29801, 256, 32666, 256, 32838, 256, - 37428, 256, 38646, 256, 38728, 256, 38936, 256, 20363, 256, 31150, 256, - 37300, 256, 38584, 256, 24801, 256, 20102, 256, 20698, 256, 23534, 256, - 23615, 256, 26009, 256, 27138, 256, 29134, 256, 30274, 256, 34044, 256, - 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, 26491, 256, - 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, 30827, 256, - 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, 20523, 256, - 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, 26647, 256, - 29575, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 256, + 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 22865, 256, + 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 256, 32645, 256, + 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 256, 27931, 256, + 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 256, 20098, 256, + 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 256, 23888, 256, + 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 256, 34847, 256, + 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 256, 20358, 256, + 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 256, 30439, 256, + 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 256, 39791, 256, + 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 256, 37636, 256, + 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 256, 32894, 256, + 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 256, 23650, 256, + 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 256, 38475, 256, + 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 256, 32190, 256, + 33777, 256, 38517, 256, 35712, 256, 25295, 256, 35582, 256, 20025, 256, + 23527, 256, 24594, 256, 29575, 256, 30064, 256, 21271, 256, 30971, 256, + 20415, 256, 24489, 256, 19981, 256, 27852, 256, 25976, 256, 32034, 256, + 21443, 256, 22622, 256, 30465, 256, 33865, 256, 35498, 256, 27578, 256, + 36784, 256, 27784, 256, 25342, 256, 33509, 256, 25504, 256, 30053, 256, + 20142, 256, 20841, 256, 20937, 256, 26753, 256, 31975, 256, 33391, 256, + 35538, 256, 37327, 256, 21237, 256, 21570, 256, 22899, 256, 24300, 256, + 26053, 256, 28670, 256, 31018, 256, 38317, 256, 39530, 256, 40599, 256, + 40654, 256, 21147, 256, 26310, 256, 27511, 256, 36706, 256, 24180, 256, + 24976, 256, 25088, 256, 25754, 256, 28451, 256, 29001, 256, 29833, 256, + 31178, 256, 32244, 256, 32879, 256, 36646, 256, 34030, 256, 36899, 256, + 37706, 256, 21015, 256, 21155, 256, 21693, 256, 28872, 256, 35010, 256, + 24265, 256, 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, + 20196, 256, 22265, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, + 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, + 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, + 20698, 256, 23534, 256, 23615, 256, 26009, 256, 29134, 256, 30274, 256, + 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, + 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, + 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, + 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, + 26647, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, 38563, 256, 40023, 256, @@ -3898,65 +3893,60 @@ static const unsigned int decomp_data[] = { 25935, 256, 26082, 256, 26257, 256, 26757, 256, 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256, 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256, 31069, 256, 31117, 256, - 31118, 256, 31296, 256, 31361, 256, 31680, 256, 32244, 256, 32265, 256, - 32321, 256, 32626, 256, 32773, 256, 33261, 256, 33401, 256, 33401, 256, - 33879, 256, 35088, 256, 35222, 256, 35585, 256, 35641, 256, 36051, 256, - 36104, 256, 36790, 256, 36920, 256, 38627, 256, 38911, 256, 38971, 256, - 24693, 256, 148206, 256, 33304, 256, 20006, 256, 20917, 256, 20840, 256, - 20352, 256, 20805, 256, 20864, 256, 21191, 256, 21242, 256, 21917, 256, - 21845, 256, 21913, 256, 21986, 256, 22618, 256, 22707, 256, 22852, 256, - 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 256, 24425, 256, - 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24974, 256, 24928, 256, - 25074, 256, 25140, 256, 25540, 256, 25628, 256, 25682, 256, 25942, 256, - 26228, 256, 26391, 256, 26395, 256, 26454, 256, 27513, 256, 27578, 256, - 27969, 256, 28379, 256, 28363, 256, 28450, 256, 28702, 256, 29038, 256, - 30631, 256, 29237, 256, 29359, 256, 29482, 256, 29809, 256, 29958, 256, - 30011, 256, 30237, 256, 30239, 256, 30410, 256, 30427, 256, 30452, 256, - 30538, 256, 30528, 256, 30924, 256, 31409, 256, 31680, 256, 31867, 256, - 32091, 256, 32244, 256, 32574, 256, 32773, 256, 33618, 256, 33775, 256, - 34681, 256, 35137, 256, 35206, 256, 35222, 256, 35519, 256, 35576, 256, - 35531, 256, 35585, 256, 35582, 256, 35565, 256, 35641, 256, 35722, 256, - 36104, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 256, 38524, 256, - 38627, 256, 38742, 256, 38875, 256, 38911, 256, 38923, 256, 38971, 256, - 39698, 256, 40860, 256, 141386, 256, 141380, 256, 144341, 256, 15261, - 256, 16408, 256, 16441, 256, 152137, 256, 154832, 256, 163539, 256, - 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, 108, 770, 102, - 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, 116, 514, 1396, - 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, 514, 1396, 1389, - 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 1488, 262, 1491, 262, - 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 262, 1514, 262, 43, - 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 512, 64329, 1474, - 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, 1489, 1468, 512, - 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, 1468, 512, 1494, - 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, 512, 1499, 1468, - 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, 1505, 1468, 512, - 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, 1468, 512, 1512, - 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, 512, 1489, 1471, - 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, 1649, 268, 1649, - 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, 268, 1662, 269, - 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, 1664, 267, 1658, - 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, 269, 1663, 270, - 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, 1700, 268, 1700, - 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, 270, 1702, 267, - 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, 1667, 269, 1667, - 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, 267, 1671, 268, - 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, 1676, 268, 1676, - 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, 268, 1688, 267, - 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, 1705, 267, 1711, - 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, 269, 1715, 270, - 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, 1722, 268, 1722, - 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, 268, 1728, 267, - 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, 1726, 269, 1726, - 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, 267, 1709, 268, - 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, 1734, 268, 1734, - 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, 267, 1733, 268, - 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, 1744, 270, 1744, - 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, 523, 1574, 1749, - 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, 1574, 1735, 524, - 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, 1736, 524, 1574, - 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, 523, 1574, 1609, - 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, 269, 1740, 270, - 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1609, + 31118, 256, 31296, 256, 31361, 256, 31680, 256, 32265, 256, 32321, 256, + 32626, 256, 32773, 256, 33261, 256, 33401, 256, 33879, 256, 35088, 256, + 35222, 256, 35585, 256, 35641, 256, 36051, 256, 36104, 256, 36790, 256, + 38627, 256, 38911, 256, 38971, 256, 24693, 256, 148206, 256, 33304, 256, + 20006, 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, + 21191, 256, 21242, 256, 21845, 256, 21913, 256, 21986, 256, 22707, 256, + 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 256, + 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24928, 256, + 25140, 256, 25540, 256, 25628, 256, 25682, 256, 25942, 256, 26395, 256, + 26454, 256, 27513, 256, 28379, 256, 28363, 256, 28702, 256, 30631, 256, + 29237, 256, 29359, 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, + 30239, 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, + 31409, 256, 31867, 256, 32091, 256, 32574, 256, 33618, 256, 33775, 256, + 34681, 256, 35137, 256, 35206, 256, 35519, 256, 35531, 256, 35565, 256, + 35722, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 256, 38524, 256, + 38875, 256, 38923, 256, 39698, 256, 141386, 256, 141380, 256, 144341, + 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, 154832, 256, + 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, + 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, + 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, + 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 1488, + 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 262, + 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 512, + 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, + 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, + 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, + 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, + 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, + 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, + 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, + 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, + 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, + 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, + 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, + 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, + 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, + 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, + 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, + 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, + 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, + 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, + 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, + 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, + 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, + 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, + 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, + 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, + 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, + 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, + 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, + 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, + 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, + 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, + 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1610, 523, 1576, 1580, 523, 1576, 1581, 523, 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, 1610, 523, 1578, 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, 523, 1578, 1609, 523, 1578, 1610, @@ -3980,172 +3970,171 @@ static const unsigned int decomp_data[] = { 1610, 523, 1584, 1648, 523, 1585, 1648, 523, 1609, 1648, 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, 1574, 1585, 524, 1574, 1586, - 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1609, 524, 1574, 1610, 524, - 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, - 1609, 524, 1576, 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, - 524, 1578, 1606, 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, - 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, - 1610, 524, 1601, 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, - 524, 1603, 1575, 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, - 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, - 1575, 524, 1605, 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, - 524, 1606, 1606, 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, - 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, - 1609, 524, 1610, 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, - 525, 1574, 1605, 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, - 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, - 1581, 525, 1578, 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, - 525, 1580, 1581, 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, - 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, - 1582, 525, 1587, 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, - 525, 1590, 1580, 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, - 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, - 1580, 525, 1594, 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, - 525, 1601, 1605, 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, - 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, - 1580, 525, 1604, 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, - 525, 1605, 1580, 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, - 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, - 1607, 525, 1607, 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, - 525, 1610, 1581, 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, - 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, - 1605, 526, 1578, 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, - 526, 1587, 1607, 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, - 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, - 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, - 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, - 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, - 1610, 523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, - 523, 1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, - 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, - 1580, 523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, - 523, 1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, - 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, - 1610, 524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, - 524, 1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, - 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, - 1609, 524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, - 524, 1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, - 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, - 1605, 525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, - 526, 1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, - 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, - 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, - 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, - 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, - 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, - 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, - 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, - 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, - 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, - 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, - 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, - 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, - 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, - 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, - 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, - 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, - 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, - 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, - 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, - 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, - 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, - 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, - 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, - 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, - 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, - 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, - 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, - 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, - 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, - 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, - 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, - 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, - 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, - 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, - 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, - 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, - 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, - 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, - 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, - 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, - 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, - 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, - 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, - 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, - 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, - 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, - 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, - 265, 44, 265, 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, - 12310, 265, 12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, - 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, 265, 12308, 265, 12309, - 265, 12304, 265, 12305, 265, 12298, 265, 12299, 265, 12296, 265, 12297, - 265, 12300, 265, 12301, 265, 12302, 265, 12303, 265, 91, 265, 93, 258, - 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, 258, 95, 258, 95, 271, - 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, - 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, - 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, - 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, - 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, - 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, - 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, - 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, - 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, - 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, - 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, - 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, - 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, - 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, - 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, - 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, - 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, - 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, - 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, - 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, - 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, - 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, - 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, - 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, - 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, - 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, - 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, - 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, - 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, - 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, - 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, - 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, - 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, - 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, - 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, - 102, 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, - 109, 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, - 116, 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, - 123, 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, - 272, 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, - 272, 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, - 272, 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, - 272, 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, - 272, 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, - 272, 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, - 272, 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, - 272, 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, - 272, 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, - 272, 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, - 272, 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, - 272, 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, - 272, 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, - 272, 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, - 272, 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, - 272, 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, - 272, 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, - 272, 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, - 272, 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, - 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, - 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, - 9675, 259, 720, 259, 721, 259, 230, 259, 665, 259, 595, 259, 675, 259, - 43878, 259, 677, 259, 676, 259, 598, 259, 599, 259, 7569, 259, 600, 259, - 606, 259, 681, 259, 612, 259, 610, 259, 608, 259, 667, 259, 295, 259, - 668, 259, 615, 259, 644, 259, 682, 259, 683, 259, 620, 259, 122628, 259, + 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1610, 524, 1576, 1585, 524, + 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, 1609, 524, 1576, + 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, 524, 1578, 1606, + 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, 1579, 1586, 524, + 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, 1610, 524, 1601, + 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, 524, 1603, 1575, + 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, 1603, 1610, 524, + 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, 1575, 524, 1605, + 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, 524, 1606, 1606, + 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, 1610, 1585, 524, + 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, 1609, 524, 1610, + 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, 525, 1574, 1605, + 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, 1576, 1582, 525, + 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, 1581, 525, 1578, + 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, 525, 1580, 1581, + 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, 1582, 1580, 525, + 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, 1582, 525, 1587, + 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, 525, 1590, 1580, + 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, 1591, 1581, 525, + 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, 1580, 525, 1594, + 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, 525, 1601, 1605, + 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, 1603, 1581, 525, + 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, 1580, 525, 1604, + 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, 525, 1605, 1580, + 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, 1606, 1580, 525, + 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, 1607, 525, 1607, + 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, 525, 1610, 1581, + 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, 1574, 1605, 526, + 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, 1605, 526, 1578, + 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, 526, 1587, 1607, + 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, 1603, 1605, 526, + 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, 1605, 526, 1610, + 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, 1600, 1616, + 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, 1593, 1610, + 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, 1610, 523, + 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, 523, 1580, + 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, 1589, 1609, + 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, 1580, 523, + 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, 523, 1587, + 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, 1591, 1610, + 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, 1610, 524, + 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, 524, 1581, + 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, 1582, 1609, + 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, 1609, 524, + 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, 524, 1588, + 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, 1590, 1585, + 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, 1605, 525, + 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, 526, 1587, + 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, 1588, 1582, + 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, 1611, 781, + 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, 1580, 781, + 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, 1580, 781, + 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, 1581, 781, + 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, 1609, 781, + 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, 1609, 780, + 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, 1580, 780, + 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, 1581, 781, + 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, 1605, 781, + 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, 1582, 781, + 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, 1605, 780, + 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, 1605, 780, + 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, 1605, 780, + 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, 1605, 781, + 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, 1605, 780, + 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, 1605, 781, + 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, 1605, 780, + 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, 1609, 781, + 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, 1605, 781, + 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, 1581, 781, + 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, 1610, 781, + 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, 1580, 781, + 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, 1580, 781, + 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, 1609, 780, + 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, 1609, 780, + 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, 1605, 781, + 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, 1610, 780, + 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, 1609, 780, + 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, 1610, 780, + 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, 1609, 780, + 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, 1610, 780, + 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, 1610, 780, + 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, 1610, 780, + 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, 1581, 781, + 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, 1610, 781, + 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, 1605, 780, + 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, 1581, 780, + 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, 1610, 780, + 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, 1605, 781, + 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, 1610, 780, + 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, 1746, 1035, + 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, 1605, 1581, + 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, 1608, 1604, + 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, 779, 1589, + 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, + 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, 1604, 32, 1580, + 1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, 265, 44, 265, + 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, 12310, 265, + 12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, 265, 40, 265, + 41, 265, 123, 265, 125, 265, 12308, 265, 12309, 265, 12304, 265, 12305, + 265, 12298, 265, 12299, 265, 12296, 265, 12297, 265, 12300, 265, 12301, + 265, 12302, 265, 12303, 265, 91, 265, 93, 258, 8254, 258, 95, 271, 44, + 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, 271, + 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, 271, + 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, 271, + 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, 523, + 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, 1615, + 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, 523, 32, + 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, 1571, 268, + 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, 268, 1574, + 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, 1576, 269, + 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, 269, 1578, + 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, 1580, 268, + 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, 270, 1581, + 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, 1583, 267, + 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, 267, 1587, + 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, 1588, 270, + 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, 268, 1590, + 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, 1591, 267, + 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, 269, 1593, + 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, 1601, 268, + 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, 270, 1602, + 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, 1604, 269, + 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, 267, 1606, + 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, 1607, 270, + 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, 268, 1610, + 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, 1604, 1571, + 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, 1575, 524, + 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, 38, 264, + 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, 46, 264, + 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, 54, 264, + 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, 62, 264, + 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, 70, 264, + 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, 78, 264, + 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, 86, 264, + 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, 94, 264, + 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, 102, + 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, 109, + 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, 116, + 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, 123, + 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, 272, + 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, 272, + 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, 272, + 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, 272, + 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, 272, + 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, 272, + 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, 272, + 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, 272, + 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, 272, + 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, 272, + 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, 272, + 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, 272, + 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, 272, + 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, 272, + 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, 272, + 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, 272, + 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, 272, + 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, 272, + 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, 272, + 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, 264, + 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, 272, + 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, 9675, + 259, 720, 259, 721, 259, 230, 259, 665, 259, 595, 259, 675, 259, 43878, + 259, 677, 259, 676, 259, 598, 259, 599, 259, 7569, 259, 600, 259, 606, + 259, 681, 259, 612, 259, 610, 259, 608, 259, 667, 259, 295, 259, 668, + 259, 615, 259, 644, 259, 682, 259, 683, 259, 620, 259, 122628, 259, 42894, 259, 622, 259, 122629, 259, 654, 259, 122630, 259, 248, 259, 630, 259, 631, 259, 113, 259, 634, 259, 122632, 259, 637, 259, 638, 259, 640, 259, 680, 259, 678, 259, 43879, 259, 679, 259, 648, 259, 11377, 259, 655, @@ -4157,281 +4146,131 @@ static const unsigned int decomp_data[] = { 512, 119128, 119141, 512, 119135, 119150, 512, 119135, 119151, 512, 119135, 119152, 512, 119135, 119153, 512, 119135, 119154, 512, 119225, 119141, 512, 119226, 119141, 512, 119227, 119150, 512, 119228, 119150, - 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 66, 262, 67, 262, - 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, - 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, - 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, - 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, - 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, - 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, - 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, - 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, - 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, - 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, - 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 67, 262, 68, 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 102, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, - 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, - 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, - 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, - 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, - 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, - 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, - 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, - 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, - 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, - 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, - 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, - 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, - 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, - 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, - 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, - 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, - 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, - 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, - 305, 262, 567, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, - 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, - 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, - 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, - 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, - 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, - 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, - 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, - 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, - 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, - 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, - 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, - 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, - 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, - 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, - 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, - 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, - 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, - 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, - 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, - 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, - 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, - 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, - 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, - 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, - 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, - 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, - 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, - 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, - 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, - 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, - 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, - 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, - 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, - 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, - 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, - 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, - 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, - 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, - 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, - 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, - 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, - 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, - 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, - 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, + 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 71, 262, 74, 262, + 75, 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, + 89, 262, 97, 262, 98, 262, 99, 262, 102, 262, 107, 262, 109, 262, 110, + 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, + 262, 119, 262, 120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, + 262, 914, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, + 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 929, + 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, + 262, 937, 262, 8711, 262, 945, 262, 946, 262, 948, 262, 949, 262, 950, + 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, + 262, 958, 262, 959, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, + 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, + 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, 48, + 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, + 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1722, 262, 1697, 262, 1647, 262, - 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1610, 262, 1603, 262, 1604, - 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, - 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1594, - 262, 1580, 262, 1581, 262, 1610, 262, 1604, 262, 1606, 262, 1587, 262, - 1593, 262, 1589, 262, 1602, 262, 1588, 262, 1582, 262, 1590, 262, 1594, - 262, 1722, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, - 1591, 262, 1610, 262, 1603, 262, 1605, 262, 1606, 262, 1587, 262, 1593, - 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, - 1582, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1697, 262, 1575, - 262, 1576, 262, 1580, 262, 1583, 262, 1607, 262, 1608, 262, 1586, 262, - 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, - 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, - 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, - 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, - 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, - 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, - 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 514, 48, 46, - 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, - 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, - 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, - 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, - 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, - 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, - 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, - 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, - 12308, 83, 12309, 263, 67, 263, 82, 519, 67, 68, 519, 87, 90, 266, 65, + 1607, 514, 48, 46, 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, + 514, 52, 44, 514, 53, 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, + 44, 770, 40, 65, 41, 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, + 770, 40, 69, 41, 770, 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, + 40, 73, 41, 770, 40, 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, + 77, 41, 770, 40, 78, 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, + 41, 770, 40, 82, 41, 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, + 770, 40, 86, 41, 770, 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, + 40, 90, 41, 770, 12308, 83, 12309, 519, 67, 68, 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, 266, 70, 266, 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, 266, 78, 266, 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, 266, 86, 266, 87, 266, 88, 266, 89, - 266, 90, 522, 72, 86, 522, 77, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, - 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 515, 77, 82, 522, 68, 74, 522, - 12411, 12363, 522, 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, - 21452, 266, 12487, 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, - 20132, 266, 26144, 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, - 20877, 266, 26032, 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, - 22768, 266, 21561, 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, - 19977, 266, 36938, 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, - 36208, 266, 25171, 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, - 26377, 266, 26376, 266, 30003, 266, 21106, 266, 21942, 266, 37197, 770, - 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, 20108, 12309, - 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, 12308, 25171, - 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, 770, 12308, - 25943, 12309, 263, 24471, 263, 21487, 262, 48, 262, 49, 262, 50, 262, 51, - 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 256, 20029, 256, - 20024, 256, 20033, 256, 131362, 256, 20320, 256, 20398, 256, 20411, 256, - 20482, 256, 20602, 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256, - 132666, 256, 20813, 256, 20820, 256, 20836, 256, 20855, 256, 132380, 256, - 13497, 256, 20839, 256, 20877, 256, 132427, 256, 20887, 256, 20900, 256, - 20172, 256, 20908, 256, 20917, 256, 168415, 256, 20981, 256, 20995, 256, + 266, 90, 522, 72, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, 86, 522, 87, + 67, 515, 77, 67, 515, 77, 68, 515, 77, 82, 522, 68, 74, 522, 12411, + 12363, 522, 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, 21452, + 266, 12487, 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, 20132, + 266, 26144, 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, 20877, + 266, 26032, 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, 22768, + 266, 21561, 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, 19977, + 266, 36938, 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, 36208, + 266, 25171, 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, 26377, + 266, 26376, 266, 30003, 266, 21106, 266, 21942, 266, 37197, 770, 12308, + 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, 20108, 12309, 770, + 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, 12308, 25171, 12309, + 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, 770, 12308, 25943, + 12309, 263, 24471, 263, 21487, 256, 20029, 256, 20024, 256, 20033, 256, + 131362, 256, 20320, 256, 20411, 256, 20482, 256, 20602, 256, 20633, 256, + 20687, 256, 13470, 256, 132666, 256, 20820, 256, 20836, 256, 20855, 256, + 132380, 256, 13497, 256, 20839, 256, 20877, 256, 132427, 256, 20887, 256, + 20900, 256, 20172, 256, 20908, 256, 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, 256, 21106, 256, 21111, 256, 13589, 256, - 21191, 256, 21193, 256, 21220, 256, 21242, 256, 21253, 256, 21254, 256, - 21271, 256, 21321, 256, 21329, 256, 21338, 256, 21363, 256, 21373, 256, - 21375, 256, 21375, 256, 21375, 256, 133676, 256, 28784, 256, 21450, 256, - 21471, 256, 133987, 256, 21483, 256, 21489, 256, 21510, 256, 21662, 256, - 21560, 256, 21576, 256, 21608, 256, 21666, 256, 21750, 256, 21776, 256, - 21843, 256, 21859, 256, 21892, 256, 21892, 256, 21913, 256, 21931, 256, - 21939, 256, 21954, 256, 22294, 256, 22022, 256, 22295, 256, 22097, 256, - 22132, 256, 20999, 256, 22766, 256, 22478, 256, 22516, 256, 22541, 256, + 21253, 256, 21254, 256, 21321, 256, 21338, 256, 21363, 256, 21373, 256, + 21375, 256, 133676, 256, 28784, 256, 21450, 256, 21471, 256, 133987, 256, + 21483, 256, 21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, + 21608, 256, 21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, + 21892, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 256, 22295, 256, + 22097, 256, 22132, 256, 22766, 256, 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 256, 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810, 256, 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067, 256, 23079, 256, 23000, 256, 23142, 256, - 14062, 256, 14076, 256, 23304, 256, 23358, 256, 23358, 256, 137672, 256, - 23491, 256, 23512, 256, 23527, 256, 23539, 256, 138008, 256, 23551, 256, - 23558, 256, 24403, 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, - 23744, 256, 23693, 256, 138724, 256, 23875, 256, 138726, 256, 23918, 256, - 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, 256, - 24104, 256, 24125, 256, 24169, 256, 14434, 256, 139651, 256, 14460, 256, - 24240, 256, 24243, 256, 24246, 256, 24266, 256, 172946, 256, 24318, 256, - 140081, 256, 140081, 256, 33281, 256, 24354, 256, 24354, 256, 14535, 256, + 14062, 256, 14076, 256, 23304, 256, 23358, 256, 137672, 256, 23491, 256, + 23512, 256, 23539, 256, 138008, 256, 23551, 256, 23558, 256, 24403, 256, + 23586, 256, 14209, 256, 23648, 256, 23744, 256, 23693, 256, 138724, 256, + 23875, 256, 138726, 256, 23918, 256, 23915, 256, 23932, 256, 24033, 256, + 24034, 256, 14383, 256, 24061, 256, 24104, 256, 24125, 256, 24169, 256, + 14434, 256, 139651, 256, 14460, 256, 24240, 256, 24243, 256, 24246, 256, + 172946, 256, 24318, 256, 140081, 256, 33281, 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256, 24418, 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, 256, 24705, 256, 14650, 256, 14620, 256, - 24724, 256, 141012, 256, 24775, 256, 24904, 256, 24908, 256, 24910, 256, - 24908, 256, 24954, 256, 24974, 256, 25010, 256, 24996, 256, 25007, 256, - 25054, 256, 25074, 256, 25078, 256, 25104, 256, 25115, 256, 25181, 256, + 141012, 256, 24775, 256, 24904, 256, 24908, 256, 24954, 256, 25010, 256, + 24996, 256, 25007, 256, 25054, 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 25424, 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, 25572, 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, - 14956, 256, 25935, 256, 25964, 256, 143370, 256, 26083, 256, 26360, 256, - 26185, 256, 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, - 20885, 256, 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, - 26395, 256, 26401, 256, 26462, 256, 26451, 256, 144323, 256, 15177, 256, - 26618, 256, 26501, 256, 26706, 256, 26757, 256, 144493, 256, 26766, 256, - 26655, 256, 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114, 256, + 14956, 256, 25964, 256, 143370, 256, 26083, 256, 26360, 256, 26185, 256, + 15129, 256, 15112, 256, 15076, 256, 20882, 256, 20885, 256, 26368, 256, + 26268, 256, 32941, 256, 17369, 256, 26401, 256, 26462, 256, 26451, 256, + 144323, 256, 15177, 256, 26618, 256, 26501, 256, 26706, 256, 144493, 256, + 26766, 256, 26655, 256, 26900, 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256, 27355, 256, 15384, 256, 27425, 256, 145575, 256, - 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27578, 256, 27579, 256, - 146061, 256, 138507, 256, 146170, 256, 27726, 256, 146620, 256, 27839, - 256, 27853, 256, 27751, 256, 27926, 256, 27966, 256, 28023, 256, 27969, - 256, 28009, 256, 28024, 256, 28037, 256, 146718, 256, 27956, 256, 28207, - 256, 28270, 256, 15667, 256, 28363, 256, 28359, 256, 147153, 256, 28153, - 256, 28526, 256, 147294, 256, 147342, 256, 28614, 256, 28729, 256, 28702, - 256, 28699, 256, 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, - 256, 132389, 256, 28997, 256, 148067, 256, 29084, 256, 148395, 256, - 29224, 256, 29237, 256, 29264, 256, 149000, 256, 29312, 256, 29333, 256, + 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27579, 256, 146061, 256, + 138507, 256, 146170, 256, 27726, 256, 146620, 256, 27839, 256, 27853, + 256, 27751, 256, 27926, 256, 27966, 256, 28009, 256, 28024, 256, 28037, + 256, 146718, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256, 28359, + 256, 147153, 256, 28153, 256, 28526, 256, 147294, 256, 147342, 256, + 28614, 256, 28729, 256, 28699, 256, 15766, 256, 28746, 256, 28797, 256, + 28791, 256, 28845, 256, 132389, 256, 28997, 256, 148067, 256, 29084, 256, + 148395, 256, 29224, 256, 29264, 256, 149000, 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562, 256, 29579, 256, 16044, 256, 29605, 256, - 16056, 256, 16056, 256, 29767, 256, 29788, 256, 29809, 256, 29829, 256, - 29898, 256, 16155, 256, 29988, 256, 150582, 256, 30014, 256, 150674, 256, - 30064, 256, 139679, 256, 30224, 256, 151457, 256, 151480, 256, 151620, - 256, 16380, 256, 16392, 256, 30452, 256, 151795, 256, 151794, 256, - 151833, 256, 151859, 256, 30494, 256, 30495, 256, 30495, 256, 30538, 256, - 16441, 256, 30603, 256, 16454, 256, 16534, 256, 152605, 256, 30798, 256, - 30860, 256, 30924, 256, 16611, 256, 153126, 256, 31062, 256, 153242, 256, - 153285, 256, 31119, 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, - 31311, 256, 153980, 256, 154279, 256, 154279, 256, 31470, 256, 16898, - 256, 154539, 256, 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, - 256, 17056, 256, 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, - 256, 17153, 256, 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, - 256, 156231, 256, 17241, 256, 156377, 256, 32634, 256, 156478, 256, - 32661, 256, 32762, 256, 32773, 256, 156890, 256, 156963, 256, 32864, 256, - 157096, 256, 32880, 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, - 17419, 256, 33086, 256, 23221, 256, 157607, 256, 157621, 256, 144275, - 256, 144284, 256, 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, - 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, - 256, 33510, 256, 158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, - 256, 33571, 256, 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, - 256, 33740, 256, 33756, 256, 158774, 256, 159083, 256, 158933, 256, - 17707, 256, 34033, 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, - 159532, 256, 17757, 256, 17761, 256, 159665, 256, 159954, 256, 17771, - 256, 34384, 256, 34396, 256, 34407, 256, 34409, 256, 34473, 256, 34440, - 256, 34574, 256, 34530, 256, 34681, 256, 34600, 256, 34667, 256, 34694, - 256, 17879, 256, 34785, 256, 34817, 256, 17913, 256, 34912, 256, 34915, - 256, 161383, 256, 35031, 256, 35038, 256, 17973, 256, 35066, 256, 13499, - 256, 161966, 256, 162150, 256, 18110, 256, 18119, 256, 35488, 256, 35565, - 256, 35722, 256, 35925, 256, 162984, 256, 36011, 256, 36033, 256, 36123, - 256, 36215, 256, 163631, 256, 133124, 256, 36299, 256, 36284, 256, 36336, - 256, 133342, 256, 36564, 256, 36664, 256, 165330, 256, 165357, 256, - 37012, 256, 37105, 256, 37137, 256, 165678, 256, 37147, 256, 37432, 256, - 37591, 256, 37592, 256, 37500, 256, 37881, 256, 37909, 256, 166906, 256, - 38283, 256, 18837, 256, 38327, 256, 167287, 256, 18918, 256, 38595, 256, - 23986, 256, 38691, 256, 168261, 256, 168474, 256, 19054, 256, 19062, 256, - 38880, 256, 168970, 256, 19122, 256, 169110, 256, 38923, 256, 38923, 256, - 38953, 256, 169398, 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, - 39362, 256, 39422, 256, 19406, 256, 170800, 256, 39698, 256, 40000, 256, - 40189, 256, 19662, 256, 19693, 256, 40295, 256, 172238, 256, 19704, 256, - 172293, 256, 172558, 256, 172689, 256, 40635, 256, 19798, 256, 40697, - 256, 40702, 256, 40709, 256, 40719, 256, 40726, 256, 40763, 256, 173568, + 16056, 256, 29767, 256, 29788, 256, 29829, 256, 29898, 256, 16155, 256, + 29988, 256, 150582, 256, 30014, 256, 150674, 256, 139679, 256, 30224, + 256, 151457, 256, 151480, 256, 151620, 256, 16380, 256, 16392, 256, + 151795, 256, 151794, 256, 151833, 256, 151859, 256, 30494, 256, 30495, + 256, 30603, 256, 16454, 256, 16534, 256, 152605, 256, 30798, 256, 16611, + 256, 153126, 256, 153242, 256, 153285, 256, 31211, 256, 16687, 256, + 31306, 256, 31311, 256, 153980, 256, 154279, 256, 31470, 256, 16898, 256, + 154539, 256, 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, 256, + 17056, 256, 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, 256, + 17153, 256, 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, 256, + 156231, 256, 17241, 256, 156377, 256, 32634, 256, 156478, 256, 32661, + 256, 32762, 256, 156890, 256, 156963, 256, 32864, 256, 157096, 256, + 32880, 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, 17419, 256, + 33086, 256, 23221, 256, 157607, 256, 157621, 256, 144275, 256, 144284, + 256, 33284, 256, 36766, 256, 17515, 256, 33425, 256, 33419, 256, 33437, + 256, 21171, 256, 33457, 256, 33459, 256, 33469, 256, 33510, 256, 158524, + 256, 33565, 256, 33635, 256, 33709, 256, 33571, 256, 33725, 256, 33767, + 256, 33619, 256, 33738, 256, 33740, 256, 33756, 256, 158774, 256, 159083, + 256, 158933, 256, 17707, 256, 34033, 256, 34035, 256, 34070, 256, 160714, + 256, 34148, 256, 159532, 256, 17757, 256, 17761, 256, 159665, 256, + 159954, 256, 17771, 256, 34384, 256, 34407, 256, 34409, 256, 34473, 256, + 34440, 256, 34574, 256, 34530, 256, 34600, 256, 34667, 256, 34694, 256, + 17879, 256, 34785, 256, 34817, 256, 17913, 256, 34912, 256, 34915, 256, + 161383, 256, 35031, 256, 35038, 256, 17973, 256, 35066, 256, 13499, 256, + 161966, 256, 162150, 256, 18110, 256, 18119, 256, 35488, 256, 35925, 256, + 162984, 256, 36011, 256, 36033, 256, 36123, 256, 36215, 256, 163631, 256, + 133124, 256, 36299, 256, 36284, 256, 36336, 256, 133342, 256, 36564, 256, + 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137, 256, 165678, + 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, 256, 37881, + 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327, 256, 167287, + 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261, 256, 168474, + 256, 19054, 256, 19062, 256, 38880, 256, 168970, 256, 19122, 256, 169110, + 256, 38953, 256, 169398, 256, 39138, 256, 19251, 256, 39209, 256, 39335, + 256, 39362, 256, 39422, 256, 19406, 256, 170800, 256, 40000, 256, 40189, + 256, 19662, 256, 19693, 256, 40295, 256, 172238, 256, 19704, 256, 172293, + 256, 172558, 256, 172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, + 256, 40709, 256, 40719, 256, 40726, 256, 40763, 256, 173568, }; /* index tables for the decomposition data */ @@ -4849,116 +4688,116 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, - 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, - 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, - 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, - 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, - 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, - 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 15, 910, 913, 916, 918, 921, 924, 0, + 927, 0, 930, 933, 936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 939, 942, 945, 948, 951, 954, 957, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 960, 963, + 966, 969, 972, 0, 975, 977, 979, 981, 984, 987, 989, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 991, 993, 995, 0, + 997, 999, 0, 0, 0, 1001, 0, 0, 0, 0, 0, 0, 1003, 1006, 0, 1009, 0, 0, 0, + 1012, 0, 0, 0, 0, 1015, 1018, 1021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1030, 1033, 0, 1036, 0, 0, 0, 1039, 0, 0, 0, 0, + 1042, 1045, 1048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1051, 1054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, - 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, - 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, - 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1057, 1060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1063, 1066, 1069, 1072, 0, 0, 1075, 1078, 0, 0, 1081, 1084, + 1087, 1090, 1093, 1096, 0, 0, 1099, 1102, 1105, 1108, 1111, 1114, 0, 0, + 1117, 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, + 0, 0, 1153, 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1162, 1165, 1168, 1171, 1174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1177, 1180, 1183, 1186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1189, 0, 1192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, - 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, - 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, + 0, 0, 0, 0, 1201, 0, 0, 1204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1207, + 1210, 1213, 1216, 1219, 1222, 1225, 1228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, - 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1231, 1234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1237, 1240, + 0, 1243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1246, 0, 0, 1249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1252, 1255, 1258, 0, 0, 1261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1264, 0, 0, 1267, 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1273, 1276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 1285, 1288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 1309, 0, 0, 0, 0, + 0, 0, 0, 1294, 0, 0, 0, 0, 0, 0, 1297, 1300, 0, 1303, 1306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1309, 1312, 1315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1318, 0, 1321, 1324, 1327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1336, 1339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1347, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 0, 0, 1359, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, 0, - 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 1398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1344, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1347, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, + 1365, 1368, 1371, 1374, 1377, 0, 0, 0, 0, 0, 0, 0, 1380, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1386, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4967,676 +4806,669 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1407, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 1421, 0, 0, - 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, - 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1406, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 0, + 0, 1421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1424, 0, 1427, + 0, 0, 1430, 1433, 0, 1436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, - 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, - 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, - 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, - 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, - 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, - 1588, 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, - 1612, 1614, 1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, - 1636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, - 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, - 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, - 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, - 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, - 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, - 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, - 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, - 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, - 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, - 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, - 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, - 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, - 2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, - 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, - 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, - 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, - 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, - 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, - 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, - 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, - 2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, - 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, - 2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, - 2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, - 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, - 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, - 2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, - 2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, - 2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, - 2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, - 2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, - 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, - 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, - 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, - 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, - 2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, - 2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, - 2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, - 2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, - 2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, - 3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, - 3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, - 3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, - 3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, - 0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3129, 3131, 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, - 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165, 3167, - 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 3185, 0, 3187, 3189, - 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, - 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, - 3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, - 0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, - 3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, - 0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, - 3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, - 3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, - 3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, - 3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, - 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3532, 0, 3535, 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, - 0, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, - 3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, - 0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, - 3618, 3621, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3627, 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, - 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, - 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, - 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, - 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, - 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, - 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, - 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, - 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, - 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, - 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, - 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, - 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, - 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, - 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, - 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, - 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, - 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, - 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, - 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, - 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, - 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, - 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, - 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, - 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, - 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, - 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, - 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, - 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, - 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, - 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1439, 1441, 1443, 0, + 1445, 1447, 1449, 1451, 1453, 1455, 1457, 1459, 1461, 1463, 1465, 0, + 1467, 1469, 1471, 1473, 1475, 1477, 1479, 6, 1481, 1483, 1485, 1487, + 1489, 1491, 1493, 1495, 1497, 1499, 0, 1501, 1503, 1505, 25, 1507, 1509, + 1511, 1513, 1515, 1517, 1519, 1521, 1523, 1525, 1527, 1529, 1531, 1533, + 1535, 1537, 1539, 1541, 1543, 1545, 1547, 1549, 1551, 1553, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1557, + 1559, 1561, 1563, 1497, 1565, 1567, 1569, 1571, 1573, 1575, 1577, 1579, + 1581, 1583, 1585, 1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, + 1605, 1607, 1609, 1611, 1613, 1615, 1617, 1619, 1621, 1623, 1625, 1627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, - 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, - 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, - 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, - 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, - 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, - 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, - 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, - 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1629, 1632, 1635, 1638, + 1641, 1644, 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, + 1677, 1680, 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, + 1713, 1716, 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, + 1749, 1752, 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, + 1785, 1788, 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, + 1821, 1824, 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, + 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, + 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, + 1929, 1932, 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, + 1965, 1968, 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, + 2001, 2004, 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, + 2037, 2040, 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, + 2073, 2076, 2079, 2082, 2085, 2088, 2091, 2094, 0, 0, 0, 0, 2097, 2100, + 2103, 2106, 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, + 2139, 2142, 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, + 2175, 2178, 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, + 2211, 2214, 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, + 2247, 2250, 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, + 2283, 2286, 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, + 2319, 2322, 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, + 2355, 2358, 2361, 2364, 0, 0, 0, 0, 0, 0, 2367, 2370, 2373, 2376, 2379, + 2382, 2385, 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, + 2418, 2421, 2424, 2427, 2430, 0, 0, 2433, 2436, 2439, 2442, 2445, 2448, + 0, 0, 2451, 2454, 2457, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, + 2484, 2487, 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, + 2520, 2523, 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, + 2556, 2559, 2562, 0, 0, 2565, 2568, 2571, 2574, 2577, 2580, 0, 0, 2583, + 2586, 2589, 2592, 2595, 2598, 2601, 2604, 0, 2607, 0, 2610, 0, 2613, 0, + 2616, 2619, 2622, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, + 2652, 2655, 2658, 2661, 2664, 2667, 2670, 2672, 2675, 2677, 2680, 2682, + 2685, 2687, 2690, 2692, 2695, 2697, 2700, 0, 0, 2702, 2705, 2708, 2711, + 2714, 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, + 2750, 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, + 2786, 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, + 2822, 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, + 2858, 0, 2861, 2864, 2867, 2870, 2873, 2876, 2878, 2881, 2884, 2881, + 2886, 2889, 2892, 2895, 2898, 0, 2901, 2904, 2907, 2910, 2912, 2915, + 2917, 2920, 2923, 2926, 2929, 2932, 2935, 2938, 0, 0, 2940, 2943, 2946, + 2949, 2952, 2955, 0, 2957, 2960, 2963, 2966, 2969, 2972, 2975, 2977, + 2980, 2983, 2986, 2989, 2992, 2995, 2998, 3000, 3003, 3006, 3008, 0, 0, + 3010, 3013, 3016, 0, 3019, 3022, 3025, 3028, 3030, 3033, 3035, 3038, + 3040, 0, 3043, 3045, 3047, 3047, 3047, 3047, 3047, 1, 3047, 3047, 3047, + 0, 0, 0, 0, 0, 0, 3049, 0, 0, 0, 0, 0, 3051, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3054, 3056, 3059, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3063, + 3066, 0, 3070, 3073, 0, 0, 0, 0, 3077, 0, 3080, 0, 0, 0, 0, 0, 0, 0, 0, + 3083, 3086, 3089, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3092, 0, 0, 0, + 0, 0, 0, 0, 3047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3097, + 3099, 0, 0, 3101, 3103, 3105, 3107, 3109, 3111, 3113, 3115, 3117, 3119, + 3121, 3123, 3125, 3127, 3129, 3131, 3133, 3135, 3137, 3139, 3141, 3143, + 3145, 3147, 3149, 3151, 3153, 0, 3155, 3157, 3159, 3161, 3163, 3165, + 3167, 3169, 3171, 3173, 3175, 3177, 3179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3184, 3188, 3192, + 3194, 0, 3197, 3201, 3205, 0, 3207, 3210, 3212, 3212, 3212, 3214, 3216, + 3218, 3218, 3220, 3222, 0, 3224, 3226, 0, 0, 3229, 3231, 3233, 3233, + 3233, 0, 0, 3235, 3238, 3242, 0, 3245, 0, 3247, 0, 3245, 0, 3249, 3251, + 3253, 3192, 0, 3255, 3257, 3259, 0, 3261, 3263, 3265, 3267, 3269, 3271, + 3273, 0, 3275, 3279, 3281, 3283, 3285, 3287, 0, 0, 0, 0, 3289, 3291, + 3255, 3273, 3293, 0, 0, 0, 0, 0, 0, 3295, 3299, 3303, 3308, 3312, 3316, + 3320, 3324, 3328, 3332, 3336, 3340, 3344, 3348, 3352, 3356, 3359, 3361, + 3364, 3368, 3371, 3373, 3376, 3380, 3385, 3388, 3390, 3393, 3397, 3399, + 3401, 3403, 3405, 3407, 3410, 3414, 3417, 3419, 3422, 3426, 3431, 3434, + 3436, 3439, 3443, 3445, 3447, 3449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3451, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3455, 3458, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3464, + 3467, 3470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3473, 0, 0, 0, 0, 3476, 0, 0, 3479, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3482, 0, 3485, + 0, 0, 0, 0, 0, 3488, 3491, 0, 3495, 3498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3502, 0, 0, 3505, 0, 0, 3508, 0, 3511, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3514, 0, 3517, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3520, 3523, 3526, 3529, 3532, 0, 0, 3535, 3538, + 0, 0, 3541, 3544, 0, 0, 0, 0, 0, 0, 3547, 3550, 0, 0, 3553, 3556, 0, 0, + 3559, 3562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3565, 3568, 3571, 3574, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3577, + 3580, 3583, 3586, 0, 0, 0, 0, 0, 0, 3589, 3592, 3595, 3598, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3601, 3603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3605, 3607, 3609, 3611, 3613, 3615, 3617, 3619, 3621, 3623, 3626, 3629, + 3632, 3635, 3638, 3641, 3644, 3647, 3650, 3653, 3656, 3660, 3664, 3668, + 3672, 3676, 3680, 3684, 3688, 3692, 3697, 3702, 3707, 3712, 3717, 3722, + 3727, 3732, 3737, 3742, 3747, 3750, 3753, 3756, 3759, 3762, 3765, 3768, + 3771, 3774, 3778, 3782, 3786, 3790, 3794, 3798, 3802, 3806, 3810, 3814, + 3818, 3822, 3826, 3830, 3834, 3838, 3842, 3846, 3850, 3854, 3858, 3862, + 3866, 3870, 3874, 3878, 3882, 3886, 3890, 3894, 3898, 3902, 3906, 3910, + 3914, 3918, 3922, 3924, 3926, 3928, 3930, 3932, 3934, 3936, 3938, 3940, + 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956, 3958, 3960, 3962, 3964, + 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980, 3982, 3984, 3986, 3988, + 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, + 4014, 4016, 4018, 4020, 4022, 4024, 4026, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, - 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, - 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, - 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, - 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, - 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, - 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, - 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, - 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4033, 4037, 4040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, - 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, - 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, - 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, - 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, - 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, - 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, - 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, - 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, - 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, - 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, - 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, - 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, - 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, - 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, - 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, - 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, - 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, - 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, - 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, - 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, - 5664, 5666, 5668, 5671, 5676, 5681, 5686, 5690, 5695, 5699, 5703, 5709, - 5714, 5718, 5722, 5726, 5731, 5736, 5740, 5744, 5747, 5751, 5756, 5761, - 5764, 5770, 5777, 5783, 5787, 5793, 5799, 5804, 5808, 5812, 5816, 5821, - 5827, 5832, 5836, 5840, 5844, 5847, 5850, 5853, 5856, 5860, 5864, 5870, - 5874, 5879, 5885, 5889, 5892, 5895, 5901, 5906, 5912, 5916, 5922, 5925, - 5929, 5933, 5937, 5941, 5945, 5950, 5954, 5957, 5961, 5965, 5969, 5974, - 5978, 5982, 5986, 5992, 5997, 6000, 6006, 6009, 6014, 6019, 6023, 6027, - 6031, 6036, 6039, 6043, 6048, 6051, 6057, 6061, 6064, 6067, 6070, 6073, - 6076, 6079, 6082, 6085, 6088, 6091, 6095, 6099, 6103, 6107, 6111, 6115, - 6119, 6123, 6127, 6131, 6135, 6139, 6143, 6147, 6151, 6155, 6158, 6161, - 6165, 6168, 6171, 6174, 6178, 6182, 6185, 6188, 6191, 6194, 6197, 6202, - 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6226, 6230, 6235, 6238, 6241, - 6244, 6247, 6250, 6253, 6256, 6260, 6264, 6268, 6272, 6275, 6278, 6281, - 6284, 6287, 6290, 6293, 6296, 6299, 6302, 6306, 6310, 6313, 6317, 6321, - 6325, 6328, 6332, 6336, 6341, 6344, 6348, 6352, 6356, 6360, 6366, 6373, - 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, 6409, - 6412, 6415, 6418, 6421, 6424, 6427, 6432, 6435, 6438, 6441, 6446, 6450, - 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6480, 6484, 6487, - 6490, 6494, 6498, 6501, 6506, 6510, 6513, 6516, 6519, 6522, 6526, 6530, - 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6557, 6561, 6565, 6569, - 6573, 6577, 6581, 6585, 6589, 6593, 6597, 6601, 6605, 6609, 6613, 6617, - 6621, 6625, 6629, 6633, 6637, 6641, 6645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6649, 6651, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6653, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6655, 6657, 6659, 0, 0, 0, 6661, 6663, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6665, 6667, 6669, - 6671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6675, 6677, 6679, 6681, 6683, 6685, - 6687, 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, 6709, - 6711, 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, 6733, - 6735, 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, 6757, - 6759, 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, 6781, - 6783, 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, 6805, - 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, 6829, - 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, 6853, - 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, 6877, - 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, 6901, - 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, 6925, - 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6941, 6943, 6945, 6947, 6949, - 6951, 6953, 6955, 6957, 6959, 6961, 6963, 6965, 6967, 6969, 6971, 6973, - 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, 6995, 6997, - 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, 7017, 7019, 7021, - 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, 7041, 7043, 7045, - 7047, 7049, 7051, 7053, 7055, 7057, 7059, 7061, 7063, 7065, 7067, 7069, - 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, 7087, 7089, 7091, 7093, - 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, 7111, 7113, 7115, 7117, - 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, 7135, 7137, 7139, 7141, - 7143, 7145, 7147, 7149, 7151, 7153, 7155, 7157, 7159, 7161, 7163, 7165, - 7167, 7169, 7171, 7173, 7175, 7177, 7179, 7181, 7183, 7185, 7187, 7189, - 7191, 7193, 7195, 7197, 7199, 7201, 7203, 7205, 7207, 7209, 7211, 7213, - 0, 0, 7215, 0, 7217, 0, 0, 7219, 7221, 7223, 7225, 7227, 7229, 7231, - 7233, 7235, 7237, 0, 7239, 0, 7241, 0, 0, 7243, 7245, 0, 0, 0, 7247, - 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, 7267, 7269, 7271, - 7273, 7275, 7277, 7279, 7281, 7283, 7285, 7287, 7289, 7291, 7293, 7295, - 7297, 7299, 7301, 7303, 7305, 7307, 7309, 7311, 7313, 7315, 7317, 7319, - 7321, 7323, 7325, 7327, 7329, 7331, 7333, 7335, 7337, 7339, 7341, 7343, - 7345, 7347, 7349, 7351, 7353, 7355, 7357, 7359, 7361, 7363, 7365, 7367, - 7369, 7371, 7373, 7375, 7377, 7379, 7381, 0, 0, 7383, 7385, 7387, 7389, - 7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413, - 7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437, - 7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461, - 7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485, - 7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509, - 7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533, - 7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, 7557, - 7559, 7561, 7563, 7565, 7567, 7569, 7571, 7573, 7575, 7577, 7579, 7581, - 7583, 7585, 7587, 7589, 7591, 7593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7595, 7598, 7601, 7604, 7608, 7612, 7615, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7618, 7621, 7624, 7627, 7630, 0, 0, 0, 0, 0, 7633, 0, 7636, - 7639, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7655, 7657, 7659, 7662, - 7665, 7668, 7671, 7674, 7677, 7680, 7683, 7686, 7689, 7692, 7695, 0, - 7698, 7701, 7704, 7707, 7710, 0, 7713, 0, 7716, 7719, 0, 7722, 7725, 0, - 7728, 7731, 7734, 7737, 7740, 7743, 7746, 7749, 7752, 7755, 7758, 7760, - 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, - 7786, 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, - 7810, 7812, 7814, 7816, 7818, 7820, 7822, 7824, 7826, 7828, 7830, 7832, - 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, 7856, - 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, 7880, - 7882, 7884, 7886, 7888, 7890, 7892, 7894, 7896, 7898, 7900, 7902, 7904, - 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, 7928, - 7930, 7932, 7934, 7936, 7938, 7940, 7942, 7944, 7946, 7948, 7950, 7952, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7954, 7956, 7958, 7960, 7962, 7964, 7966, - 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, 7990, - 7992, 7994, 7996, 7998, 8000, 8003, 8006, 8009, 8012, 8015, 8018, 8021, - 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8051, 8054, 8056, - 8058, 8060, 8062, 8065, 8068, 8071, 8074, 8077, 8080, 8083, 8086, 8089, - 8092, 8095, 8098, 8101, 8104, 8107, 8110, 8113, 8116, 8119, 8122, 8125, - 8128, 8131, 8134, 8137, 8140, 8143, 8146, 8149, 8152, 8155, 8158, 8161, - 8164, 8167, 8170, 8173, 8176, 8179, 8182, 8185, 8188, 8191, 8194, 8197, - 8200, 8203, 8206, 8209, 8212, 8215, 8218, 8221, 8224, 8227, 8230, 8233, - 8236, 8239, 8242, 8245, 8248, 8251, 8254, 8257, 8260, 8263, 8266, 8269, - 8272, 8275, 8278, 8281, 8284, 8287, 8290, 8293, 8296, 8299, 8302, 8305, - 8308, 8311, 8314, 8317, 8320, 8323, 8326, 8329, 8332, 8335, 8338, 8341, - 8344, 8348, 8352, 8356, 8360, 8364, 8368, 8371, 8374, 8377, 8380, 8383, - 8386, 8389, 8392, 8395, 8398, 8401, 8404, 8407, 8410, 8413, 8416, 8419, - 8422, 8425, 8428, 8431, 8434, 8437, 8440, 8443, 8446, 8449, 8452, 8455, - 8458, 8461, 8464, 8467, 8470, 8473, 8476, 8479, 8482, 8485, 8488, 8491, - 8494, 8497, 8500, 8503, 8506, 8509, 8512, 8515, 8518, 8521, 8524, 8527, - 8530, 8533, 8536, 8539, 8542, 8545, 8548, 8551, 8554, 8557, 8560, 8563, - 8566, 8569, 8572, 8575, 8578, 8581, 8584, 8587, 8590, 8593, 8596, 8599, - 8602, 8605, 8608, 8611, 8614, 8617, 8620, 8623, 8626, 8629, 8632, 8635, - 8638, 8641, 8644, 8647, 8650, 8653, 8656, 8659, 8662, 8665, 8668, 8671, - 8674, 8677, 8680, 8683, 8686, 8689, 8692, 8695, 8698, 8701, 8704, 8707, - 8710, 8713, 8716, 8719, 8722, 8725, 8728, 8731, 8734, 8737, 8740, 8743, - 8746, 8749, 8752, 8755, 8758, 8761, 8764, 8767, 8770, 8773, 8776, 8779, - 8782, 8785, 8788, 8791, 8794, 8798, 8802, 8806, 8809, 8812, 8815, 8818, - 8821, 8824, 8827, 8830, 8833, 8836, 8839, 8842, 8845, 8848, 8851, 8854, - 8857, 8860, 8863, 8866, 8869, 8872, 8875, 8878, 8881, 8884, 8887, 8890, - 8893, 8896, 8899, 8902, 8905, 8908, 8911, 8914, 8917, 8920, 8923, 8926, - 8929, 8932, 8935, 8938, 8941, 8944, 8947, 8950, 8953, 8956, 8959, 8962, - 8965, 8968, 8971, 8974, 8977, 8980, 8983, 8986, 8989, 8992, 8995, 8998, - 9001, 9004, 9007, 9010, 9013, 9016, 9019, 9022, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9025, 9029, 9033, 9037, 9041, 9045, 9049, - 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, - 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, - 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, - 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, - 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, 9277, 0, 0, 9281, 9285, - 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, - 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, - 9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, - 9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, - 9481, 9485, 9489, 9493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9497, 9501, 9505, 9510, 9515, 9520, 9525, 9530, 9535, 9540, 9544, 9563, - 9572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9577, - 9579, 9581, 9583, 9585, 9587, 9589, 9591, 9593, 9595, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9597, 9599, 9601, 9603, - 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, 9621, 9623, 9625, 9627, - 9629, 9631, 9633, 9635, 9637, 0, 0, 9639, 9641, 9643, 9645, 9647, 9649, - 9651, 9653, 9655, 9657, 9659, 9661, 0, 9663, 9665, 9667, 9669, 9671, - 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, 9693, 9695, - 9697, 9699, 0, 9701, 9703, 9705, 9707, 0, 0, 0, 0, 9709, 9712, 9715, 0, - 9718, 0, 9721, 9724, 9727, 9730, 9733, 9736, 9739, 9742, 9745, 9748, - 9751, 9753, 9755, 9757, 9759, 9761, 9763, 9765, 9767, 9769, 9771, 9773, - 9775, 9777, 9779, 9781, 9783, 9785, 9787, 9789, 9791, 9793, 9795, 9797, - 9799, 9801, 9803, 9805, 9807, 9809, 9811, 9813, 9815, 9817, 9819, 9821, - 9823, 9825, 9827, 9829, 9831, 9833, 9835, 9837, 9839, 9841, 9843, 9845, - 9847, 9849, 9851, 9853, 9855, 9857, 9859, 9861, 9863, 9865, 9867, 9869, - 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, 9889, 9891, 9893, - 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, 9913, 9915, 9917, - 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, 9937, 9939, 9941, - 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, 9961, 9963, 9965, - 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9981, 9983, 9985, 9988, 9991, - 9994, 9997, 10000, 10003, 10006, 0, 0, 0, 0, 10009, 10011, 10013, 10015, - 10017, 10019, 10021, 10023, 10025, 10027, 10029, 10031, 10033, 10035, - 10037, 10039, 10041, 10043, 10045, 10047, 10049, 10051, 10053, 10055, - 10057, 10059, 10061, 10063, 10065, 10067, 10069, 10071, 10073, 10075, - 10077, 10079, 10081, 10083, 10085, 10087, 10089, 10091, 10093, 10095, - 10097, 10099, 10101, 10103, 10105, 10107, 10109, 10111, 10113, 10115, - 10117, 10119, 10121, 10123, 10125, 10127, 10129, 10131, 10133, 10135, - 10137, 10139, 10141, 10143, 10145, 10147, 10149, 10151, 10153, 10155, - 10157, 10159, 10161, 10163, 10165, 10167, 10169, 10171, 10173, 10175, - 10177, 10179, 10181, 10183, 10185, 10187, 10189, 10191, 10193, 10195, - 10197, 10199, 10201, 10203, 10205, 10207, 10209, 10211, 10213, 10215, - 10217, 10219, 10221, 10223, 10225, 10227, 10229, 10231, 10233, 10235, - 10237, 10239, 10241, 10243, 10245, 10247, 10249, 10251, 10253, 10255, - 10257, 10259, 10261, 10263, 10265, 10267, 10269, 10271, 10273, 10275, - 10277, 10279, 10281, 10283, 10285, 10287, 10289, 10291, 10293, 10295, - 10297, 10299, 10301, 10303, 10305, 10307, 10309, 10311, 10313, 10315, - 10317, 10319, 10321, 10323, 10325, 10327, 10329, 10331, 10333, 10335, - 10337, 10339, 10341, 10343, 10345, 10347, 10349, 10351, 10353, 10355, - 10357, 10359, 10361, 10363, 10365, 10367, 10369, 10371, 10373, 10375, - 10377, 10379, 10381, 10383, 10385, 10387, 0, 0, 0, 10389, 10391, 10393, - 10395, 10397, 10399, 0, 0, 10401, 10403, 10405, 10407, 10409, 10411, 0, - 0, 10413, 10415, 10417, 10419, 10421, 10423, 0, 0, 10425, 10427, 10429, - 0, 0, 0, 10431, 10433, 10435, 10437, 10439, 10441, 10443, 0, 10445, - 10447, 10449, 10451, 10453, 10455, 10457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10459, 10461, 10463, 10465, 10467, 0, 10469, - 10471, 10473, 10475, 10477, 10479, 10481, 10483, 10485, 10487, 10489, - 10491, 10493, 10495, 10497, 10499, 10501, 10503, 10505, 10507, 10509, - 10511, 10513, 10515, 10517, 10519, 10521, 10523, 10525, 10527, 10529, - 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, 10549, - 10551, 0, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10569, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4044, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4047, 4049, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10571, 0, 10574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10577, 0, 0, + 4055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4057, 4059, 4061, 4063, 4065, + 4067, 4069, 4071, 4073, 4075, 4077, 4079, 4081, 4083, 4085, 4087, 4089, + 4091, 4093, 4095, 4097, 4099, 4101, 4103, 4105, 4107, 4109, 4111, 4113, + 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, + 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, + 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, + 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, + 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, + 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, + 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, + 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, + 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, + 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, + 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, + 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, + 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, + 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, + 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, 4469, 4471, 4473, + 4475, 4477, 4479, 4481, 4483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4487, 0, 4103, 4489, 4491, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4493, 0, 4496, 0, 4499, 0, 4502, + 0, 4505, 0, 4508, 0, 4511, 0, 4514, 0, 4517, 0, 4520, 0, 4523, 0, 4526, + 0, 0, 4529, 0, 4532, 0, 4535, 0, 0, 0, 0, 0, 0, 4538, 4541, 0, 4544, + 4547, 0, 4550, 4553, 0, 4556, 4559, 0, 4562, 4565, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4568, 0, 0, 0, 0, 0, 0, + 4571, 4574, 0, 4577, 4580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4583, 0, + 4586, 0, 4589, 0, 4592, 0, 4595, 0, 4598, 0, 4601, 0, 4604, 0, 4607, 0, + 4610, 0, 4613, 0, 4616, 0, 0, 4619, 0, 4622, 0, 4625, 0, 0, 0, 0, 0, 0, + 4628, 4631, 0, 4634, 4637, 0, 4640, 4643, 0, 4646, 4649, 0, 4652, 4655, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4658, + 0, 0, 4661, 4664, 4667, 4670, 0, 0, 0, 4673, 4676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4679, 4681, 4683, + 4685, 4687, 4689, 4691, 4693, 4695, 4697, 4699, 4701, 4703, 4705, 4707, + 4709, 4711, 4713, 4715, 4717, 4719, 4721, 4723, 4725, 4727, 4729, 4731, + 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, 4753, 4755, + 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, 4777, 4779, + 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, + 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, 4825, 4827, + 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, 4849, 4851, + 4853, 4855, 4857, 4859, 4861, 4863, 4865, 0, 0, 0, 4867, 4869, 4871, + 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10580, 10583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4895, + 4899, 4903, 4907, 4911, 4915, 4919, 4923, 4927, 4931, 4935, 4939, 4943, + 4947, 4951, 4956, 4961, 4966, 4971, 4976, 4981, 4986, 4991, 4996, 5001, + 5006, 5011, 5016, 5021, 5026, 5034, 0, 5041, 5045, 5049, 5053, 5057, + 5061, 5065, 5069, 5073, 5077, 5081, 5085, 5089, 5093, 5097, 5101, 5105, + 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, 5145, 5149, 5153, + 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5187, 5189, 5191, 0, 0, + 0, 0, 0, 0, 0, 0, 5193, 5197, 5200, 5203, 5206, 5209, 5212, 5215, 5218, + 5221, 5224, 5227, 5230, 5233, 5236, 5239, 5242, 5244, 5246, 5248, 5250, + 5252, 5254, 5256, 5258, 5260, 5262, 5264, 5266, 5268, 5270, 5273, 5276, + 5279, 5282, 5285, 5288, 5291, 5294, 5297, 5300, 5303, 5306, 5309, 5312, + 5318, 5323, 0, 5326, 5328, 5330, 5332, 5334, 5336, 5338, 5340, 5342, + 5344, 5346, 5348, 5350, 5352, 5354, 5356, 5358, 5360, 5362, 5364, 5366, + 5368, 5370, 5372, 5374, 5376, 5378, 5380, 5382, 5384, 5386, 5388, 5390, + 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, 5412, 5414, + 5416, 5418, 5420, 5422, 5424, 5427, 5430, 5433, 5436, 5439, 5442, 5445, + 5448, 5451, 5454, 5457, 5460, 5463, 5466, 5469, 5472, 5475, 5478, 5481, + 5484, 5487, 5490, 5493, 5496, 5500, 5504, 5508, 5511, 5515, 5518, 5522, + 5524, 5526, 5528, 5530, 5532, 5534, 5536, 5538, 5540, 5542, 5544, 5546, + 5548, 5550, 5552, 5554, 5556, 5558, 5560, 5562, 5564, 5566, 5568, 5570, + 5572, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, 5592, 5594, + 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, 5616, 5619, + 5624, 5629, 5634, 5638, 5643, 5647, 5651, 5657, 5662, 5666, 5670, 5674, + 5679, 5684, 5688, 5692, 5695, 5699, 5704, 5709, 5712, 5718, 5725, 5731, + 5735, 5741, 5747, 5752, 5756, 5760, 5764, 5769, 5775, 5780, 5784, 5788, + 5792, 5795, 5798, 5801, 5804, 5808, 5812, 5818, 5822, 5827, 5833, 5837, + 5840, 5843, 5849, 5854, 5860, 5864, 5870, 5873, 5877, 5881, 5885, 5889, + 5893, 5898, 5902, 5905, 5909, 5913, 5917, 5922, 5926, 5930, 5934, 5940, + 5945, 5948, 5954, 5957, 5962, 5967, 5971, 5975, 5979, 5984, 5987, 5991, + 5996, 5999, 6005, 6009, 6012, 6015, 6018, 6021, 6024, 6027, 6030, 6033, + 6036, 6039, 6043, 6047, 6051, 6055, 6059, 6063, 6067, 6071, 6075, 6079, + 6083, 6087, 6091, 6095, 6099, 6103, 6106, 6109, 6113, 6116, 6119, 6122, + 6126, 6130, 6133, 6136, 6139, 6142, 6145, 6150, 6153, 6156, 6159, 6162, + 6165, 6168, 6171, 6174, 6178, 6183, 6186, 6189, 6192, 6195, 6198, 6201, + 6204, 6208, 6212, 6216, 6220, 6223, 6226, 6229, 6232, 6235, 6238, 6241, + 6244, 6247, 6250, 6254, 6258, 6261, 6265, 6269, 6273, 6276, 6280, 6284, + 6289, 6292, 6296, 6300, 6304, 6308, 6314, 6321, 6324, 6327, 6330, 6333, + 6336, 6339, 6342, 6345, 6348, 6351, 6354, 6357, 6360, 6363, 6366, 6369, + 6372, 6375, 6380, 6383, 6386, 6389, 6394, 6398, 6401, 6404, 6407, 6410, + 6413, 6416, 6419, 6422, 6425, 6428, 6432, 6435, 6438, 6442, 6446, 6449, + 6454, 6458, 6461, 6464, 6467, 6470, 6474, 6478, 6481, 6484, 6487, 6490, + 6493, 6496, 6499, 6502, 6505, 6509, 6513, 6517, 6521, 6525, 6529, 6533, + 6537, 6541, 6545, 6549, 6553, 6557, 6561, 6565, 6569, 6573, 6577, 6581, + 6585, 6589, 6593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6597, 6599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6603, 6605, + 6607, 0, 0, 0, 6609, 6611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6613, 6615, 6617, 6619, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6623, 6625, 6627, 6629, 6631, 6633, 6635, 6637, 6637, 6639, + 6641, 6643, 6645, 6647, 6649, 6651, 6653, 6655, 6657, 6659, 6661, 6663, + 6665, 6667, 6669, 6671, 6673, 6675, 6677, 6679, 6681, 6683, 6685, 6687, + 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, 6709, 6711, + 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, 6733, 6735, + 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, 6757, 6759, + 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, 6781, 6783, + 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, 6661, 6805, + 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, 6829, + 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, 6853, + 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, 6877, + 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, 6901, + 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, 6925, + 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6841, 6941, 6943, 6945, 6947, + 6949, 6951, 6953, 6955, 6809, 6957, 6959, 6961, 6963, 6965, 6967, 6969, + 6971, 6973, 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, + 6995, 6661, 6997, 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, + 7017, 7019, 7021, 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, + 7041, 7043, 7045, 7047, 7049, 6813, 7051, 7053, 7055, 7057, 7059, 7061, + 7063, 7065, 7067, 7069, 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, + 7087, 7089, 7091, 7093, 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, + 7111, 7113, 7115, 7117, 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, + 7135, 7137, 7139, 7141, 7143, 7145, 7147, 7149, 0, 0, 7151, 0, 7153, 0, + 0, 7155, 7157, 7159, 7161, 7163, 7165, 7167, 7169, 7171, 7173, 0, 7175, + 0, 7177, 0, 0, 7179, 7181, 0, 0, 0, 7183, 7185, 7187, 7189, 7191, 7193, + 7195, 7197, 7199, 7201, 7203, 7205, 7207, 7209, 7211, 7213, 7215, 7217, + 7219, 7221, 7223, 7225, 7227, 7229, 7231, 7233, 7235, 7237, 7239, 7241, + 7243, 7245, 7247, 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, + 7267, 7269, 7271, 6919, 7273, 7275, 7277, 7279, 7281, 7283, 7283, 7285, + 7287, 7289, 7291, 7293, 7295, 7297, 7299, 7179, 7301, 7303, 7305, 7307, + 7309, 7311, 0, 0, 7313, 7315, 7317, 7319, 7321, 7323, 7325, 7327, 7207, + 7329, 7331, 7333, 7151, 7335, 7337, 7339, 7341, 7343, 7345, 7347, 7349, + 7351, 7353, 7355, 7357, 7225, 7359, 7227, 7361, 7363, 7365, 7367, 7369, + 7153, 6703, 7371, 7373, 7375, 6843, 7017, 7377, 7379, 7241, 7381, 7243, + 7383, 7385, 7387, 7157, 7389, 7391, 7393, 7395, 7397, 7159, 7399, 7401, + 7403, 7405, 7407, 7409, 7271, 7411, 7413, 6919, 7415, 7279, 7417, 7419, + 7421, 7423, 7425, 7289, 7427, 7177, 7429, 7291, 6805, 7431, 7293, 7433, + 7297, 7435, 7437, 7439, 7441, 7443, 7301, 7169, 7445, 7303, 7447, 7305, + 7449, 6637, 7451, 7453, 7455, 7457, 7459, 7461, 7463, 7465, 7467, 7469, + 7471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7473, 7476, 7479, 7482, + 7486, 7490, 7493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7496, 7499, 7502, + 7505, 7508, 0, 0, 0, 0, 0, 7511, 0, 7514, 7517, 7519, 7521, 7523, 7525, + 7527, 7529, 7531, 7533, 7535, 7537, 7540, 7543, 7546, 7549, 7552, 7555, + 7558, 7561, 7564, 7567, 7570, 7573, 0, 7576, 7579, 7582, 7585, 7588, 0, + 7591, 0, 7594, 7597, 0, 7600, 7603, 0, 7606, 7609, 7612, 7615, 7618, + 7621, 7624, 7627, 7630, 7633, 7636, 7638, 7640, 7642, 7644, 7646, 7648, + 7650, 7652, 7654, 7656, 7658, 7660, 7662, 7664, 7666, 7668, 7670, 7672, + 7674, 7676, 7678, 7680, 7682, 7684, 7686, 7688, 7690, 7692, 7694, 7696, + 7698, 7700, 7702, 7704, 7706, 7708, 7710, 7712, 7714, 7716, 7718, 7720, + 7722, 7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, 7740, 7742, 7744, + 7746, 7748, 7750, 7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, + 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, + 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, + 7818, 7820, 7822, 7824, 7826, 7828, 7830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, + 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, + 7881, 7884, 7887, 7890, 7893, 7896, 7899, 7902, 7905, 7908, 7911, 7914, + 7917, 7920, 7923, 7926, 7929, 7932, 7934, 7936, 7938, 7940, 7943, 7946, + 7923, 7949, 7952, 7955, 7958, 7961, 7964, 7967, 7970, 7973, 7976, 7979, + 7982, 7985, 7988, 7991, 7994, 7997, 8000, 8003, 8006, 8009, 8012, 8015, + 8018, 8021, 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8051, + 8054, 8057, 8060, 8063, 8066, 8069, 8072, 8075, 8078, 8081, 8084, 8087, + 8090, 8093, 8096, 8099, 8102, 8105, 8108, 8111, 8114, 8117, 8120, 8123, + 8126, 8129, 8132, 8135, 8138, 8141, 8144, 8147, 8150, 8153, 8156, 8159, + 8162, 8165, 8168, 8171, 8174, 8177, 8180, 8183, 8186, 8189, 8192, 8195, + 8198, 8201, 8204, 8207, 8210, 8213, 8216, 8219, 8223, 8227, 8231, 8235, + 8239, 8243, 8246, 8249, 8252, 7926, 8255, 8258, 8261, 8264, 8267, 8270, + 8273, 8276, 8279, 8282, 8285, 8288, 8291, 8294, 8297, 8300, 8303, 8306, + 8309, 8312, 8315, 8318, 8321, 8324, 8327, 8330, 8333, 8336, 8339, 8342, + 8345, 8348, 8351, 8354, 8357, 8360, 8363, 8366, 8369, 8372, 8375, 8378, + 8381, 8384, 8387, 8390, 8393, 8396, 8399, 8402, 8405, 8408, 8411, 8414, + 8417, 8420, 8423, 8426, 8429, 8432, 8435, 8438, 8441, 8444, 8447, 8450, + 8453, 8456, 8459, 8462, 8465, 8468, 8471, 8474, 8477, 8480, 8483, 8486, + 8489, 8492, 8495, 8498, 8501, 8504, 8507, 8510, 8513, 8516, 8519, 8522, + 8525, 8528, 8531, 8534, 8537, 8540, 8543, 8546, 8549, 8552, 8555, 8558, + 8561, 8564, 8567, 8570, 8573, 8576, 8579, 8582, 8585, 8588, 8591, 8594, + 8597, 8600, 8603, 8606, 8609, 8612, 8615, 8618, 8621, 8624, 8627, 8630, + 8633, 8636, 8639, 8642, 8645, 8648, 8651, 8654, 8657, 8660, 8663, 8666, + 8670, 8674, 8678, 8681, 8684, 8687, 8690, 8693, 8696, 8699, 8702, 8705, + 8708, 8711, 8714, 8717, 8720, 8723, 8726, 8729, 8732, 8735, 8738, 8741, + 8744, 8747, 8750, 8753, 8756, 8759, 8762, 8765, 8768, 8771, 8774, 8777, + 8780, 8783, 8786, 8789, 8792, 8795, 8798, 8801, 8804, 8807, 8810, 8813, + 8816, 8819, 8822, 8825, 8828, 8831, 8834, 8837, 8840, 8843, 8846, 8849, + 8852, 8855, 8858, 8861, 8864, 8867, 8870, 8873, 8876, 8879, 8882, 8885, + 8888, 8891, 8894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8897, 8901, 8905, 8909, 8913, 8917, 8921, 8925, 8929, 8933, 8937, 8941, + 8945, 8949, 8953, 8957, 8961, 8965, 8969, 8973, 8977, 8981, 8985, 8989, + 8993, 8997, 9001, 9005, 9009, 9013, 9017, 9021, 9025, 9029, 9033, 9037, + 9041, 9045, 9049, 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, + 9089, 9093, 9097, 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, + 9137, 9141, 9145, 9149, 0, 0, 9153, 9157, 9161, 9165, 9169, 9173, 9177, + 9181, 9185, 9189, 9193, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, + 9229, 9233, 9237, 9241, 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, + 9277, 9281, 9285, 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, + 9325, 9329, 9333, 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9369, 9373, 9377, 9382, 9387, + 9392, 9397, 9402, 9407, 9412, 9416, 9435, 9444, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9449, 9451, 9453, 9455, 9457, 9459, + 9461, 9463, 9465, 9467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9469, 9471, 9473, 9475, 9475, 9477, 9479, 9481, 9483, + 9485, 9487, 9489, 9491, 9493, 9495, 9497, 9499, 9501, 9503, 9505, 9507, + 0, 0, 9509, 9511, 9513, 9513, 9513, 9513, 9515, 9515, 9515, 9517, 9519, + 9521, 0, 9523, 9525, 9527, 9529, 9531, 9533, 9535, 9537, 9539, 9541, + 9543, 9545, 9547, 9549, 9551, 9553, 9555, 9557, 9559, 0, 9561, 9563, + 9565, 9567, 0, 0, 0, 0, 9569, 9572, 9575, 0, 9578, 0, 9581, 9584, 9587, + 9590, 9593, 9596, 9599, 9602, 9605, 9608, 9611, 9613, 9615, 9617, 9619, + 9621, 9623, 9625, 9627, 9629, 9631, 9633, 9635, 9637, 9639, 9641, 9643, + 9645, 9647, 9649, 9651, 9653, 9655, 9657, 9659, 9661, 9663, 9665, 9667, + 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, + 9693, 9695, 9697, 9699, 9701, 9703, 9705, 9707, 9709, 9711, 9713, 9715, + 9717, 9719, 9721, 9723, 9725, 9727, 9729, 9731, 9733, 9735, 9737, 9739, + 9741, 9743, 9745, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, + 9765, 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, + 9789, 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, + 9813, 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, + 9837, 9839, 9841, 9843, 9845, 9848, 9851, 9854, 9857, 9860, 9863, 9866, + 0, 0, 0, 0, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, + 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, + 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, + 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, + 9961, 9963, 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9981, 9983, + 9985, 9987, 9989, 9991, 9993, 9995, 9997, 9999, 10001, 10003, 10005, + 10007, 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025, + 10027, 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045, + 10047, 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065, + 10067, 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085, + 10087, 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105, + 10107, 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125, + 10127, 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145, + 10147, 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165, + 10167, 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185, + 10187, 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205, + 10207, 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225, + 10227, 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245, + 10247, 0, 0, 0, 10249, 10251, 10253, 10255, 10257, 10259, 0, 0, 10261, + 10263, 10265, 10267, 10269, 10271, 0, 0, 10273, 10275, 10277, 10279, + 10281, 10283, 0, 0, 10285, 10287, 10289, 0, 0, 0, 10291, 10293, 10295, + 10297, 10299, 10301, 10303, 0, 10305, 10307, 10309, 10311, 10313, 10315, + 10317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10319, + 10321, 10323, 10325, 10327, 0, 10329, 10331, 10333, 10335, 10337, 10339, + 10341, 10343, 10345, 10347, 10349, 10351, 10353, 10355, 10357, 10359, + 10361, 10363, 10365, 10367, 10369, 10371, 10373, 10375, 10377, 10379, + 10381, 10383, 10385, 10387, 10389, 10391, 10393, 10395, 10397, 10399, + 10401, 10403, 10405, 10407, 10409, 10411, 0, 10413, 10415, 10417, 10419, + 10421, 10423, 10425, 10427, 10429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10431, 0, 10434, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10440, 10443, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10446, 10449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10452, 10455, 0, 10458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10461, 10464, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10467, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10470, 10473, + 10476, 10479, 10482, 10485, 10488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10491, 10494, 10497, 10500, 10503, 10506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, + 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, + 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, + 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, + 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, + 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, + 0, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, + 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, + 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, 3261, + 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, 10529, + 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, + 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, + 10557, 10559, 10561, 10563, 10565, 10567, 10509, 0, 3192, 3289, 0, 0, + 10511, 0, 0, 10513, 10515, 0, 0, 3224, 10517, 3229, 3231, 0, 10519, + 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, + 3291, 0, 10539, 0, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 0, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, + 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, + 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, + 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, + 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, 0, + 3289, 3257, 3259, 10511, 0, 0, 10513, 10515, 3220, 3261, 3224, 10517, + 3229, 3231, 0, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 0, 10533, + 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, + 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, + 10561, 10563, 10565, 10567, 10509, 3253, 0, 3289, 3257, 3259, 10511, 0, + 3218, 10513, 10515, 3220, 3261, 0, 10517, 0, 0, 0, 10519, 10521, 10523, + 10525, 10527, 10529, 10531, 0, 10533, 10535, 10537, 3291, 3255, 10539, + 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, + 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, + 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, + 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, + 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, + 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, + 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, + 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, + 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, + 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, + 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, + 10559, 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, + 10511, 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, + 3233, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, + 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, + 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, + 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, + 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, + 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, + 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, + 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, 10561, + 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, + 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, + 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, + 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, + 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, + 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, + 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, + 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, + 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10569, 10571, 0, 0, 10573, 10575, 3283, 10577, 10579, 10581, 10583, + 10585, 10587, 10589, 10591, 10593, 10595, 10597, 10599, 3285, 10601, + 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, 10619, 10621, + 10623, 3281, 10625, 10627, 10629, 10631, 10633, 10635, 10637, 10639, + 10641, 10643, 10645, 10647, 3279, 10649, 10651, 10653, 10655, 10657, + 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, + 10679, 10573, 10575, 3283, 10577, 10579, 10581, 10583, 10585, 10587, + 10589, 10591, 10593, 10595, 10597, 10599, 3285, 10601, 10603, 10605, + 10607, 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 3281, + 10625, 10627, 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, + 10645, 10647, 3279, 10649, 10651, 10653, 10655, 10657, 10659, 10661, + 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, 10679, 10573, + 10575, 3283, 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, + 10593, 10595, 10597, 10599, 3285, 10601, 10603, 10605, 10607, 10609, + 10611, 10613, 10615, 10617, 10619, 10621, 10623, 3281, 10625, 10627, + 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, + 3279, 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, + 10667, 10669, 10671, 10673, 10675, 10677, 10679, 10573, 10575, 3283, + 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, + 10597, 10599, 3285, 10601, 10603, 10605, 10607, 10609, 10611, 10613, + 10615, 10617, 10619, 10621, 10623, 3281, 10625, 10627, 10629, 10631, + 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, 3279, 10649, + 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, 10669, + 10671, 10673, 10675, 10677, 10679, 10573, 10575, 3283, 10577, 10579, + 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, 10597, 10599, + 3285, 10601, 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, + 10619, 10621, 10623, 3281, 10625, 10627, 10629, 10631, 10633, 10635, + 10637, 10639, 10641, 10643, 10645, 10647, 3279, 10649, 10651, 10653, + 10655, 10657, 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, + 10675, 10677, 10679, 10681, 10683, 0, 0, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10705, 10707, 10709, 10711, 0, + 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, 10729, 10731, + 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, 10749, 10751, + 10753, 10755, 10757, 10759, 10761, 10763, 10765, 0, 10707, 10709, 0, + 10767, 0, 0, 10717, 0, 10721, 10723, 10725, 10727, 10729, 10731, 10733, + 10735, 10737, 10739, 0, 10743, 10745, 10747, 10749, 0, 10753, 0, 10757, + 0, 0, 0, 0, 0, 0, 10709, 0, 0, 0, 0, 10717, 0, 10721, 0, 10725, 0, 10729, + 10731, 10733, 0, 10737, 10739, 0, 10743, 0, 0, 10749, 0, 10753, 0, 10757, + 0, 10761, 0, 10765, 0, 10707, 10709, 0, 10767, 0, 0, 10717, 10719, 10721, + 10723, 0, 10727, 10729, 10731, 10733, 10735, 10737, 10739, 0, 10743, + 10745, 10747, 10749, 0, 10753, 10755, 10757, 10759, 0, 10763, 0, 10705, + 10707, 10709, 10711, 10767, 10713, 10715, 10717, 10719, 10721, 0, 10725, + 10727, 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, + 10747, 10749, 10751, 10753, 10755, 10757, 0, 0, 0, 0, 0, 10707, 10709, + 10711, 0, 10713, 10715, 10717, 10719, 10721, 0, 10725, 10727, 10729, + 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, 10749, + 10751, 10753, 10755, 10757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10769, 10772, 10775, 10778, 10781, 10784, 10787, 10790, + 10793, 10796, 10799, 0, 0, 0, 0, 0, 10802, 10806, 10810, 10814, 10818, + 10822, 10826, 10830, 10834, 10838, 10842, 10846, 10850, 10854, 10858, + 10862, 10866, 10870, 10874, 10878, 10882, 10886, 10890, 10894, 10898, + 10902, 10906, 3926, 3956, 10910, 10913, 0, 10916, 10918, 10920, 10922, + 10924, 10926, 10928, 10930, 10932, 10934, 10936, 10938, 10940, 10942, + 10944, 10946, 10948, 10950, 10952, 10954, 10956, 10958, 10960, 10962, + 10964, 10966, 10968, 6348, 10971, 10974, 10977, 10981, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10984, 10987, + 10990, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10993, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10996, 10999, 11002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 11004, 11006, 11008, 11010, 11012, 11014, 11016, 11018, 11020, + 11022, 11024, 11026, 11028, 11030, 11032, 11034, 11036, 11038, 11040, + 11042, 11044, 11046, 11048, 11050, 11052, 11054, 11056, 11058, 11060, + 11062, 11064, 11066, 11068, 11070, 11072, 11074, 11076, 11078, 11080, + 11082, 11084, 11086, 11088, 11090, 0, 0, 0, 0, 11092, 11096, 11100, + 11104, 11108, 11112, 11116, 11120, 11124, 0, 0, 0, 0, 0, 0, 0, 11128, + 11130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10685, 10687, 10689, + 10691, 10693, 10695, 10697, 10699, 10701, 10703, 0, 0, 0, 0, 0, 0, 11132, + 11134, 11136, 11138, 11140, 7195, 11142, 11144, 11146, 11148, 7197, + 11150, 11152, 11154, 7199, 11156, 11158, 11160, 11162, 11164, 11166, + 11168, 11170, 11172, 11174, 11176, 11178, 7315, 11180, 11182, 11184, + 11186, 11188, 11190, 11192, 11194, 11196, 7325, 7201, 7203, 7327, 11198, + 11200, 6817, 11202, 7205, 11204, 11206, 11208, 11210, 11210, 11210, + 11212, 11214, 11216, 11218, 11220, 11222, 11224, 11226, 11228, 11230, + 11232, 11234, 11236, 11238, 11240, 11242, 11244, 11246, 11246, 7331, + 11248, 11250, 11252, 11254, 7209, 11256, 11258, 11260, 7123, 11262, + 11264, 11266, 11268, 11270, 11272, 11274, 11276, 11278, 11280, 11282, + 11284, 11286, 11288, 11290, 11292, 11294, 11296, 11298, 11300, 11302, + 11304, 11306, 11308, 11310, 11312, 11312, 11314, 11316, 11318, 6809, + 11320, 11322, 11324, 11326, 11328, 11330, 11332, 11334, 7219, 11336, + 11338, 11340, 11342, 11344, 11346, 11348, 11350, 11352, 11354, 11356, + 11358, 11360, 11362, 11364, 11366, 11368, 11370, 11372, 11374, 11376, + 6701, 11378, 11380, 11382, 11382, 11384, 11386, 11386, 11388, 11390, + 11392, 11394, 11396, 11398, 11400, 11402, 11404, 11406, 11408, 11410, + 11412, 7221, 11414, 11416, 11418, 11420, 7355, 11420, 11422, 7225, 11424, + 11426, 11428, 11430, 7227, 6647, 11432, 11434, 11436, 11438, 11440, + 11442, 11444, 11446, 11448, 11450, 11452, 11454, 11456, 11458, 11460, + 11462, 11464, 11466, 11468, 11470, 11472, 11474, 7229, 11476, 11478, + 11480, 11482, 11484, 11486, 7233, 11488, 11490, 11492, 11494, 11496, + 11498, 11500, 11502, 6703, 7371, 11504, 11506, 11508, 11510, 11512, + 11514, 11516, 11518, 7235, 11520, 11522, 11524, 11526, 7457, 11528, + 11530, 11532, 11534, 11536, 11538, 11540, 11542, 11544, 11546, 11548, + 11550, 11552, 6843, 11554, 11556, 11558, 11560, 11562, 11564, 11566, + 11568, 11570, 11572, 11574, 7237, 7017, 11576, 11578, 11580, 11582, + 11584, 11586, 11588, 11590, 7379, 11592, 11594, 11596, 11598, 11600, + 11602, 11604, 11606, 7381, 11608, 11610, 11612, 11614, 11616, 11618, + 11620, 11622, 11624, 11626, 11628, 11630, 7385, 11632, 11634, 11636, + 11638, 11640, 11642, 11644, 11646, 11648, 11650, 11652, 11652, 11654, + 11656, 7389, 11658, 11660, 11662, 11664, 11666, 11668, 11670, 6815, + 11672, 11674, 11676, 11678, 11680, 11682, 11684, 7401, 11686, 11688, + 11690, 11692, 11694, 11696, 11696, 7403, 7461, 11698, 11700, 11702, + 11704, 11706, 6739, 7407, 11708, 11710, 7259, 11712, 11714, 7167, 11716, + 11718, 7267, 11720, 11722, 11724, 11726, 11726, 11728, 11730, 11732, + 11734, 11736, 11738, 11740, 11742, 11744, 11746, 11748, 11750, 11752, + 11754, 11756, 11758, 11760, 11762, 11764, 11766, 11768, 11770, 11772, + 11774, 11776, 11778, 11780, 7279, 11782, 11784, 11786, 11788, 11790, + 11792, 11794, 11796, 11798, 11800, 11802, 11804, 11806, 11808, 11810, + 11812, 11384, 11814, 11816, 11818, 11820, 11822, 11824, 11826, 11828, + 11830, 11832, 11834, 11836, 6851, 11838, 11840, 11842, 11844, 11846, + 11848, 7285, 11850, 11852, 11854, 11856, 11858, 11860, 11862, 11864, + 11866, 11868, 11870, 11872, 11874, 11876, 11878, 11880, 11882, 11884, + 11886, 11888, 6729, 11890, 11892, 11894, 11896, 11898, 11900, 7421, + 11902, 11904, 11906, 11908, 11910, 11912, 11914, 11916, 11918, 11920, + 11922, 11924, 11926, 11928, 11930, 11932, 11934, 11936, 11938, 11940, + 7431, 7433, 11942, 11944, 11946, 11948, 11950, 11952, 11954, 11956, + 11958, 11960, 11962, 11964, 11966, 7435, 11968, 11970, 11972, 11974, + 11976, 11978, 11980, 11982, 11984, 11986, 11988, 11990, 11992, 11994, + 11996, 11998, 12000, 12002, 12004, 12006, 12008, 12010, 12012, 12014, + 12016, 12018, 12020, 12022, 12024, 12026, 7447, 7447, 12028, 12030, + 12032, 12034, 12036, 12038, 12040, 12042, 12044, 12046, 7449, 12048, + 12050, 12052, 12054, 12056, 12058, 12060, 12062, 12064, 12066, 12068, + 12070, 12072, 12074, 12076, 12078, 12080, 12082, 12084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10586, 10589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10592, 10595, 0, - 10598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10601, 10604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10607, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10610, 10613, 10616, 10619, 10622, - 10625, 10628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10631, 10634, - 10637, 10640, 10643, 10646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, - 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, - 10689, 10691, 10693, 10695, 10697, 10699, 10701, 10703, 10705, 10707, - 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, - 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, - 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, - 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, - 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, - 10809, 10811, 10813, 10815, 10817, 0, 10819, 10821, 10823, 10825, 10827, - 10829, 10831, 10833, 10835, 10837, 10839, 10841, 10843, 10845, 10847, - 10849, 10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, - 10869, 10871, 10873, 10875, 10877, 10879, 10881, 10883, 10885, 10887, - 10889, 10891, 10893, 10895, 10897, 10899, 10901, 10903, 10905, 10907, - 10909, 10911, 10913, 10915, 10917, 10919, 10921, 10923, 10925, 10927, - 10929, 10931, 10933, 10935, 10937, 10939, 10941, 10943, 10945, 10947, - 10949, 10951, 10953, 10955, 10957, 10959, 0, 10961, 10963, 0, 0, 10965, - 0, 0, 10967, 10969, 0, 0, 10971, 10973, 10975, 10977, 0, 10979, 10981, - 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, 11001, 0, - 11003, 0, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 0, 11019, - 11021, 11023, 11025, 11027, 11029, 11031, 11033, 11035, 11037, 11039, - 11041, 11043, 11045, 11047, 11049, 11051, 11053, 11055, 11057, 11059, - 11061, 11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, 11079, - 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, 11099, - 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, 11119, - 11121, 11123, 11125, 11127, 11129, 11131, 11133, 11135, 11137, 11139, - 11141, 11143, 11145, 11147, 0, 11149, 11151, 11153, 11155, 0, 0, 11157, - 11159, 11161, 11163, 11165, 11167, 11169, 11171, 0, 11173, 11175, 11177, - 11179, 11181, 11183, 11185, 0, 11187, 11189, 11191, 11193, 11195, 11197, - 11199, 11201, 11203, 11205, 11207, 11209, 11211, 11213, 11215, 11217, - 11219, 11221, 11223, 11225, 11227, 11229, 11231, 11233, 11235, 11237, - 11239, 11241, 0, 11243, 11245, 11247, 11249, 0, 11251, 11253, 11255, - 11257, 11259, 0, 11261, 0, 0, 0, 11263, 11265, 11267, 11269, 11271, - 11273, 11275, 0, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, - 11293, 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, - 11313, 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, - 11333, 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, - 11353, 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, - 11373, 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, - 11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, - 11413, 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, - 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, - 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, - 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, - 11493, 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, - 11513, 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, - 11533, 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, - 11553, 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, - 11573, 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, - 11593, 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, - 11613, 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, - 11633, 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, - 11653, 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, - 11673, 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, - 11693, 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, - 11713, 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, - 11733, 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, - 11753, 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, - 11773, 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, - 11793, 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, - 11813, 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 11831, - 11833, 11835, 11837, 11839, 11841, 11843, 11845, 11847, 11849, 11851, - 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, 11871, - 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, 11891, - 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, 11911, - 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, 11931, - 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, 11951, - 11953, 11955, 0, 0, 11957, 11959, 11961, 11963, 11965, 11967, 11969, - 11971, 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, - 11991, 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, - 12011, 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, - 12031, 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, - 12051, 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, - 12071, 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, - 12091, 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, - 12111, 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, - 12131, 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, - 12151, 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, - 12171, 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, - 12191, 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, - 12211, 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, - 12231, 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, - 12251, 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, - 12271, 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, - 12291, 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, - 12311, 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, - 12331, 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, - 12351, 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, - 12371, 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, - 12391, 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, - 12411, 12413, 12415, 12417, 12419, 12421, 12423, 12425, 12427, 12429, - 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, 12449, - 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, 12469, - 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, 12489, - 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, 12509, - 12511, 12513, 12515, 12517, 12519, 12521, 12523, 12525, 12527, 12529, - 12531, 12533, 12535, 12537, 12539, 0, 0, 12541, 12543, 12545, 12547, - 12549, 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, - 12569, 12571, 12573, 12575, 12577, 12579, 12581, 12583, 12585, 12587, - 12589, 12591, 12593, 12595, 12597, 12599, 12601, 12603, 12605, 12607, - 12609, 12611, 12613, 12615, 12617, 12619, 12621, 12623, 12625, 12627, - 12629, 12631, 12633, 12635, 12637, 12639, 12641, 12643, 12645, 12647, 0, - 12649, 12651, 12653, 12655, 12657, 12659, 12661, 12663, 12665, 12667, - 12669, 12671, 12673, 12675, 12677, 12679, 12681, 12683, 12685, 12687, - 12689, 12691, 12693, 12695, 12697, 12699, 12701, 0, 12703, 12705, 0, - 12707, 0, 0, 12709, 0, 12711, 12713, 12715, 12717, 12719, 12721, 12723, - 12725, 12727, 12729, 0, 12731, 12733, 12735, 12737, 0, 12739, 0, 12741, - 0, 0, 0, 0, 0, 0, 12743, 0, 0, 0, 0, 12745, 0, 12747, 0, 12749, 0, 12751, - 12753, 12755, 0, 12757, 12759, 0, 12761, 0, 0, 12763, 0, 12765, 0, 12767, - 0, 12769, 0, 12771, 0, 12773, 12775, 0, 12777, 0, 0, 12779, 12781, 12783, - 12785, 0, 12787, 12789, 12791, 12793, 12795, 12797, 12799, 0, 12801, - 12803, 12805, 12807, 0, 12809, 12811, 12813, 12815, 0, 12817, 0, 12819, - 12821, 12823, 12825, 12827, 12829, 12831, 12833, 12835, 12837, 0, 12839, - 12841, 12843, 12845, 12847, 12849, 12851, 12853, 12855, 12857, 12859, - 12861, 12863, 12865, 12867, 12869, 12871, 0, 0, 0, 0, 0, 12873, 12875, - 12877, 0, 12879, 12881, 12883, 12885, 12887, 0, 12889, 12891, 12893, - 12895, 12897, 12899, 12901, 12903, 12905, 12907, 12909, 12911, 12913, - 12915, 12917, 12919, 12921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12923, 12926, 12929, 12932, 12935, 12938, 12941, 12944, - 12947, 12950, 12953, 0, 0, 0, 0, 0, 12956, 12960, 12964, 12968, 12972, - 12976, 12980, 12984, 12988, 12992, 12996, 13000, 13004, 13008, 13012, - 13016, 13020, 13024, 13028, 13032, 13036, 13040, 13044, 13048, 13052, - 13056, 13060, 13064, 13066, 13068, 13071, 0, 13074, 13076, 13078, 13080, - 13082, 13084, 13086, 13088, 13090, 13092, 13094, 13096, 13098, 13100, - 13102, 13104, 13106, 13108, 13110, 13112, 13114, 13116, 13118, 13120, - 13122, 13124, 13126, 13129, 13132, 13135, 13138, 13142, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13145, 13148, - 13151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13154, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 13157, 13160, 13163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 13165, 13167, 13169, 13171, 13173, 13175, 13177, 13179, 13181, - 13183, 13185, 13187, 13189, 13191, 13193, 13195, 13197, 13199, 13201, - 13203, 13205, 13207, 13209, 13211, 13213, 13215, 13217, 13219, 13221, - 13223, 13225, 13227, 13229, 13231, 13233, 13235, 13237, 13239, 13241, - 13243, 13245, 13247, 13249, 13251, 0, 0, 0, 0, 13253, 13257, 13261, - 13265, 13269, 13273, 13277, 13281, 13285, 0, 0, 0, 0, 0, 0, 0, 13289, - 13291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13293, 13295, 13297, - 13299, 13301, 13303, 13305, 13307, 13309, 13311, 0, 0, 0, 0, 0, 0, 13313, - 13315, 13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, - 13335, 13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, - 13355, 13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, - 13375, 13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, - 13395, 13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, - 13415, 13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, - 13435, 13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 13453, - 13455, 13457, 13459, 13461, 13463, 13465, 13467, 13469, 13471, 13473, - 13475, 13477, 13479, 13481, 13483, 13485, 13487, 13489, 13491, 13493, - 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13509, 13511, 13513, - 13515, 13517, 13519, 13521, 13523, 13525, 13527, 13529, 13531, 13533, - 13535, 13537, 13539, 13541, 13543, 13545, 13547, 13549, 13551, 13553, - 13555, 13557, 13559, 13561, 13563, 13565, 13567, 13569, 13571, 13573, - 13575, 13577, 13579, 13581, 13583, 13585, 13587, 13589, 13591, 13593, - 13595, 13597, 13599, 13601, 13603, 13605, 13607, 13609, 13611, 13613, - 13615, 13617, 13619, 13621, 13623, 13625, 13627, 13629, 13631, 13633, - 13635, 13637, 13639, 13641, 13643, 13645, 13647, 13649, 13651, 13653, - 13655, 13657, 13659, 13661, 13663, 13665, 13667, 13669, 13671, 13673, - 13675, 13677, 13679, 13681, 13683, 13685, 13687, 13689, 13691, 13693, - 13695, 13697, 13699, 13701, 13703, 13705, 13707, 13709, 13711, 13713, - 13715, 13717, 13719, 13721, 13723, 13725, 13727, 13729, 13731, 13733, - 13735, 13737, 13739, 13741, 13743, 13745, 13747, 13749, 13751, 13753, - 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769, 13771, 13773, - 13775, 13777, 13779, 13781, 13783, 13785, 13787, 13789, 13791, 13793, - 13795, 13797, 13799, 13801, 13803, 13805, 13807, 13809, 13811, 13813, - 13815, 13817, 13819, 13821, 13823, 13825, 13827, 13829, 13831, 13833, - 13835, 13837, 13839, 13841, 13843, 13845, 13847, 13849, 13851, 13853, - 13855, 13857, 13859, 13861, 13863, 13865, 13867, 13869, 13871, 13873, - 13875, 13877, 13879, 13881, 13883, 13885, 13887, 13889, 13891, 13893, - 13895, 13897, 13899, 13901, 13903, 13905, 13907, 13909, 13911, 13913, - 13915, 13917, 13919, 13921, 13923, 13925, 13927, 13929, 13931, 13933, - 13935, 13937, 13939, 13941, 13943, 13945, 13947, 13949, 13951, 13953, - 13955, 13957, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13973, - 13975, 13977, 13979, 13981, 13983, 13985, 13987, 13989, 13991, 13993, - 13995, 13997, 13999, 14001, 14003, 14005, 14007, 14009, 14011, 14013, - 14015, 14017, 14019, 14021, 14023, 14025, 14027, 14029, 14031, 14033, - 14035, 14037, 14039, 14041, 14043, 14045, 14047, 14049, 14051, 14053, - 14055, 14057, 14059, 14061, 14063, 14065, 14067, 14069, 14071, 14073, - 14075, 14077, 14079, 14081, 14083, 14085, 14087, 14089, 14091, 14093, - 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14109, 14111, 14113, - 14115, 14117, 14119, 14121, 14123, 14125, 14127, 14129, 14131, 14133, - 14135, 14137, 14139, 14141, 14143, 14145, 14147, 14149, 14151, 14153, - 14155, 14157, 14159, 14161, 14163, 14165, 14167, 14169, 14171, 14173, - 14175, 14177, 14179, 14181, 14183, 14185, 14187, 14189, 14191, 14193, - 14195, 14197, 14199, 14201, 14203, 14205, 14207, 14209, 14211, 14213, - 14215, 14217, 14219, 14221, 14223, 14225, 14227, 14229, 14231, 14233, - 14235, 14237, 14239, 14241, 14243, 14245, 14247, 14249, 14251, 14253, - 14255, 14257, 14259, 14261, 14263, 14265, 14267, 14269, 14271, 14273, - 14275, 14277, 14279, 14281, 14283, 14285, 14287, 14289, 14291, 14293, - 14295, 14297, 14299, 14301, 14303, 14305, 14307, 14309, 14311, 14313, - 14315, 14317, 14319, 14321, 14323, 14325, 14327, 14329, 14331, 14333, - 14335, 14337, 14339, 14341, 14343, 14345, 14347, 14349, 14351, 14353, - 14355, 14357, 14359, 14361, 14363, 14365, 14367, 14369, 14371, 14373, - 14375, 14377, 14379, 14381, 14383, 14385, 14387, 14389, 14391, 14393, - 14395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* NFC pairs */ diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 489484443aab..f28266f390c1 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -169,6 +169,7 @@ def makeunicodedata(unicode, trace): # 2) decomposition data + decomp_data_cache = {} decomp_data = [0] decomp_prefix = [""] decomp_index = [0] * len(unicode.chars) @@ -207,12 +208,15 @@ def makeunicodedata(unicode, trace): comp_first[l] = 1 comp_last[r] = 1 comp_pairs.append((l,r,char)) - try: - i = decomp_data.index(decomp) - except ValueError: + key = tuple(decomp) + i = decomp_data_cache.get(key, -1) + if i == -1: i = len(decomp_data) decomp_data.extend(decomp) decomp_size = decomp_size + len(decomp) * 2 + decomp_data_cache[key] = i + else: + assert decomp_data[i:i+len(decomp)] == decomp else: i = 0 decomp_index[char] = i From webhook-mailer at python.org Fri Aug 19 15:33:55 2022 From: webhook-mailer at python.org (brandtbucher) Date: Fri, 19 Aug 2022 19:33:55 -0000 Subject: [Python-checkins] GH-90997: Wrap yield from/await in a virtual try/except StopIteration (GH-96010) Message-ID: <mailman.747.1660937635.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5bfb3c372bda1113aea1385d4793f073a1d37155 commit: 5bfb3c372bda1113aea1385d4793f073a1d37155 branch: main author: Brandt Bucher <brandtbucher at microsoft.com> committer: brandtbucher <brandtbucher at gmail.com> date: 2022-08-19T12:33:44-07:00 summary: GH-90997: Wrap yield from/await in a virtual try/except StopIteration (GH-96010) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-15-11-58-05.gh-issue-90997.bWwV8Q.rst M Doc/library/dis.rst M Include/internal/pycore_opcode.h M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_dis.py M Objects/genobject.c M Python/ceval.c M Python/compile.c M Python/opcode_targets.h diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 63b064e7b444..691819fbca03 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -567,6 +567,17 @@ the original TOS1. .. versionchanged:: 3.11 Exception representation on the stack now consist of one, not three, items. + +.. opcode:: CLEANUP_THROW + + Handles an exception raised during a :meth:`~generator.throw` or + :meth:`~generator.close` call through the current frame. If TOS is an + instance of :exc:`StopIteration`, pop three values from the stack and push + its ``value`` member. Otherwise, re-raise TOS. + + .. versionadded:: 3.12 + + .. opcode:: BEFORE_ASYNC_WITH Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the @@ -1344,10 +1355,14 @@ iterations of the loop. .. versionadded:: 3.11 -.. opcode:: SEND +.. opcode:: SEND (delta) + + Equivalent to ``TOS = TOS1.send(TOS)``. Used in ``yield from`` and ``await`` + statements. - Sends ``None`` to the sub-generator of this generator. - Used in ``yield from`` and ``await`` statements. + If the call raises :exc:`StopIteration`, pop both items, push the + exception's ``value`` attribute, and increment the bytecode counter by + *delta*. .. versionadded:: 3.11 diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index 6906cd5c7881..587590172b56 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -104,6 +104,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [CALL_PY_WITH_DEFAULTS] = CALL, [CHECK_EG_MATCH] = CHECK_EG_MATCH, [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, + [CLEANUP_THROW] = CLEANUP_THROW, [COMPARE_OP] = COMPARE_OP, [COMPARE_OP_ADAPTIVE] = COMPARE_OP, [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP, @@ -298,38 +299,38 @@ static const char *const _PyOpcode_OpName[267] = { [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", [BEFORE_WITH] = "BEFORE_WITH", [END_ASYNC_FOR] = "END_ASYNC_FOR", + [CLEANUP_THROW] = "CLEANUP_THROW", [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1", [COMPARE_OP_ADAPTIVE] = "COMPARE_OP_ADAPTIVE", [COMPARE_OP_FLOAT_JUMP] = "COMPARE_OP_FLOAT_JUMP", [COMPARE_OP_INT_JUMP] = "COMPARE_OP_INT_JUMP", - [COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP", [STORE_SUBSCR] = "STORE_SUBSCR", [DELETE_SUBSCR] = "DELETE_SUBSCR", + [COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP", [EXTENDED_ARG_QUICK] = "EXTENDED_ARG_QUICK", [FOR_ITER_ADAPTIVE] = "FOR_ITER_ADAPTIVE", [FOR_ITER_LIST] = "FOR_ITER_LIST", [FOR_ITER_RANGE] = "FOR_ITER_RANGE", [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", - [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", [GET_ITER] = "GET_ITER", [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", [PRINT_EXPR] = "PRINT_EXPR", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", + [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", - [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", - [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", [LIST_TO_TUPLE] = "LIST_TO_TUPLE", [RETURN_VALUE] = "RETURN_VALUE", [IMPORT_STAR] = "IMPORT_STAR", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [POP_EXCEPT] = "POP_EXCEPT", @@ -356,7 +357,7 @@ static const char *const _PyOpcode_OpName[267] = { [JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -364,7 +365,7 @@ static const char *const _PyOpcode_OpName[267] = { [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", + [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", @@ -384,9 +385,9 @@ static const char *const _PyOpcode_OpName[267] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", - [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", @@ -396,30 +397,31 @@ static const char *const _PyOpcode_OpName[267] = { [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", - [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", + [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [RESUME_QUICK] = "RESUME_QUICK", - [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", + [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", - [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", [CALL] = "CALL", [KW_NAMES] = "KW_NAMES", [POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE", [POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE", [POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", + [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", @@ -427,7 +429,6 @@ static const char *const _PyOpcode_OpName[267] = { [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", - [184] = "<184>", [185] = "<185>", [186] = "<186>", [187] = "<187>", @@ -514,7 +515,6 @@ static const char *const _PyOpcode_OpName[267] = { #endif #define EXTRA_CASES \ - case 184: \ case 185: \ case 186: \ case 187: \ diff --git a/Include/opcode.h b/Include/opcode.h index 210e3fe002ca..cf11e5560674 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -32,6 +32,7 @@ extern "C" { #define BEFORE_ASYNC_WITH 52 #define BEFORE_WITH 53 #define END_ASYNC_FOR 54 +#define CLEANUP_THROW 55 #define STORE_SUBSCR 60 #define DELETE_SUBSCR 61 #define GET_ITER 68 @@ -164,48 +165,48 @@ extern "C" { #define CALL_NO_KW_METHOD_DESCRIPTOR_O 46 #define CALL_NO_KW_STR_1 47 #define CALL_NO_KW_TUPLE_1 48 -#define CALL_NO_KW_TYPE_1 55 -#define COMPARE_OP_ADAPTIVE 56 -#define COMPARE_OP_FLOAT_JUMP 57 -#define COMPARE_OP_INT_JUMP 58 -#define COMPARE_OP_STR_JUMP 59 -#define EXTENDED_ARG_QUICK 62 -#define FOR_ITER_ADAPTIVE 63 -#define FOR_ITER_LIST 64 -#define FOR_ITER_RANGE 65 -#define JUMP_BACKWARD_QUICK 66 -#define LOAD_ATTR_ADAPTIVE 67 -#define LOAD_ATTR_CLASS 72 -#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 73 -#define LOAD_ATTR_INSTANCE_VALUE 76 -#define LOAD_ATTR_MODULE 77 -#define LOAD_ATTR_PROPERTY 78 -#define LOAD_ATTR_SLOT 79 -#define LOAD_ATTR_WITH_HINT 80 -#define LOAD_ATTR_METHOD_LAZY_DICT 81 -#define LOAD_ATTR_METHOD_NO_DICT 86 -#define LOAD_ATTR_METHOD_WITH_DICT 113 -#define LOAD_ATTR_METHOD_WITH_VALUES 121 -#define LOAD_CONST__LOAD_FAST 141 -#define LOAD_FAST__LOAD_CONST 143 -#define LOAD_FAST__LOAD_FAST 153 -#define LOAD_GLOBAL_ADAPTIVE 154 -#define LOAD_GLOBAL_BUILTIN 158 -#define LOAD_GLOBAL_MODULE 159 -#define RESUME_QUICK 160 -#define STORE_ATTR_ADAPTIVE 161 -#define STORE_ATTR_INSTANCE_VALUE 166 -#define STORE_ATTR_SLOT 167 -#define STORE_ATTR_WITH_HINT 168 -#define STORE_FAST__LOAD_FAST 169 -#define STORE_FAST__STORE_FAST 170 -#define STORE_SUBSCR_ADAPTIVE 177 -#define STORE_SUBSCR_DICT 178 -#define STORE_SUBSCR_LIST_INT 179 -#define UNPACK_SEQUENCE_ADAPTIVE 180 -#define UNPACK_SEQUENCE_LIST 181 -#define UNPACK_SEQUENCE_TUPLE 182 -#define UNPACK_SEQUENCE_TWO_TUPLE 183 +#define CALL_NO_KW_TYPE_1 56 +#define COMPARE_OP_ADAPTIVE 57 +#define COMPARE_OP_FLOAT_JUMP 58 +#define COMPARE_OP_INT_JUMP 59 +#define COMPARE_OP_STR_JUMP 62 +#define EXTENDED_ARG_QUICK 63 +#define FOR_ITER_ADAPTIVE 64 +#define FOR_ITER_LIST 65 +#define FOR_ITER_RANGE 66 +#define JUMP_BACKWARD_QUICK 67 +#define LOAD_ATTR_ADAPTIVE 72 +#define LOAD_ATTR_CLASS 73 +#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 76 +#define LOAD_ATTR_INSTANCE_VALUE 77 +#define LOAD_ATTR_MODULE 78 +#define LOAD_ATTR_PROPERTY 79 +#define LOAD_ATTR_SLOT 80 +#define LOAD_ATTR_WITH_HINT 81 +#define LOAD_ATTR_METHOD_LAZY_DICT 86 +#define LOAD_ATTR_METHOD_NO_DICT 113 +#define LOAD_ATTR_METHOD_WITH_DICT 121 +#define LOAD_ATTR_METHOD_WITH_VALUES 141 +#define LOAD_CONST__LOAD_FAST 143 +#define LOAD_FAST__LOAD_CONST 153 +#define LOAD_FAST__LOAD_FAST 154 +#define LOAD_GLOBAL_ADAPTIVE 158 +#define LOAD_GLOBAL_BUILTIN 159 +#define LOAD_GLOBAL_MODULE 160 +#define RESUME_QUICK 161 +#define STORE_ATTR_ADAPTIVE 166 +#define STORE_ATTR_INSTANCE_VALUE 167 +#define STORE_ATTR_SLOT 168 +#define STORE_ATTR_WITH_HINT 169 +#define STORE_FAST__LOAD_FAST 170 +#define STORE_FAST__STORE_FAST 177 +#define STORE_SUBSCR_ADAPTIVE 178 +#define STORE_SUBSCR_DICT 179 +#define STORE_SUBSCR_LIST_INT 180 +#define UNPACK_SEQUENCE_ADAPTIVE 181 +#define UNPACK_SEQUENCE_LIST 182 +#define UNPACK_SEQUENCE_TUPLE 183 +#define UNPACK_SEQUENCE_TWO_TUPLE 184 #define DO_TRACING 255 #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\ diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 82d204257ed7..b30d0896c849 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -411,10 +411,10 @@ def _write_atomic(path, data, mode=0o666): # Python 3.12a1 3505 (Specialization/Cache for FOR_ITER) # Python 3.12a1 3506 (Add BINARY_SLICE and STORE_SLICE instructions) # Python 3.12a1 3507 (Set lineno of module's RESUME to 0) +# Python 3.12a1 3508 (Add CLEANUP_THROW) # Python 3.13 will start with 3550 -# # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually # due to the addition of new opcodes). @@ -424,7 +424,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 = (3507).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3508).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c diff --git a/Lib/opcode.py b/Lib/opcode.py index 665852291a69..52c1271868e3 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -104,6 +104,7 @@ def pseudo_op(name, op, real_ops): def_op('BEFORE_ASYNC_WITH', 52) def_op('BEFORE_WITH', 53) def_op('END_ASYNC_FOR', 54) +def_op('CLEANUP_THROW', 55) def_op('STORE_SUBSCR', 60) def_op('DELETE_SUBSCR', 61) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index f07e7c860547..67cb1502add9 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -507,26 +507,31 @@ async def _asyncwith(c): LOAD_CONST 0 (None) RETURN_VALUE -%3d >> PUSH_EXC_INFO +%3d >> CLEANUP_THROW + JUMP_BACKWARD 24 (to 22) + >> CLEANUP_THROW + JUMP_BACKWARD 9 (to 56) + >> PUSH_EXC_INFO WITH_EXCEPT_START GET_AWAITABLE 2 LOAD_CONST 0 (None) - >> SEND 3 (to 82) + >> SEND 4 (to 92) YIELD_VALUE 6 RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 4 (to 74) - >> POP_JUMP_FORWARD_IF_TRUE 1 (to 86) + JUMP_BACKWARD_NO_INTERRUPT 4 (to 82) + >> CLEANUP_THROW + >> POP_JUMP_FORWARD_IF_TRUE 1 (to 96) RERAISE 2 >> POP_TOP POP_EXCEPT POP_TOP POP_TOP - JUMP_BACKWARD 19 (to 58) + JUMP_BACKWARD 24 (to 58) >> COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: -2 rows +6 rows """ % (_asyncwith.__code__.co_firstlineno, _asyncwith.__code__.co_firstlineno + 1, _asyncwith.__code__.co_firstlineno + 2, diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-15-11-58-05.gh-issue-90997.bWwV8Q.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-11-58-05.gh-issue-90997.bWwV8Q.rst new file mode 100644 index 000000000000..8db714e59e15 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-11-58-05.gh-issue-90997.bWwV8Q.rst @@ -0,0 +1,3 @@ +Compile virtual :keyword:`try`/:keyword:`except` blocks to handle exceptions +raised during :meth:`~generator.close` or :meth:`~generator.throw` calls +through a suspended frame. diff --git a/Objects/genobject.c b/Objects/genobject.c index 2b45e28cbf16..da4afecc69c8 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -485,26 +485,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } Py_DECREF(yf); if (!ret) { - PyObject *val; - /* Pop subiterator from stack */ - assert(gen->gi_frame_state < FRAME_CLEARED); - ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe); - assert(ret == yf); - Py_DECREF(ret); - // XXX: Performing this jump ourselves is awkward and problematic. - // See https://github.com/python/cpython/pull/31968. - /* Termination repetition of SEND loop */ - assert(_PyInterpreterFrame_LASTI(frame) >= 0); - /* Backup to SEND */ - assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND); - int jump = _Py_OPARG(frame->prev_instr[-1]); - frame->prev_instr += jump - 1; - if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send(gen, val); - Py_DECREF(val); - } else { - ret = gen_send_ex(gen, Py_None, 1, 0); - } + ret = gen_send_ex(gen, Py_None, 1, 0); } return ret; } diff --git a/Python/ceval.c b/Python/ceval.c index 8c17e51e8085..7024addfe626 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2668,6 +2668,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(YIELD_VALUE) { + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. assert(oparg == STACK_LEVEL()); assert(frame->is_entry); PyObject *retval = POP(); @@ -2746,6 +2749,26 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } } + TARGET(CLEANUP_THROW) { + assert(throwflag); + PyObject *exc_value = TOP(); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + PyObject *value = ((PyStopIterationObject *)exc_value)->value; + Py_INCREF(value); + Py_DECREF(POP()); // The StopIteration. + Py_DECREF(POP()); // The last sent value. + Py_DECREF(POP()); // The delegated sub-iterator. + PUSH(value); + DISPATCH(); + } + Py_INCREF(exc_value); + PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value)); + PyObject *exc_traceback = PyException_GetTraceback(exc_value); + _PyErr_Restore(tstate, exc_type, exc_value, exc_traceback); + goto exception_unwind; + } + TARGET(LOAD_ASSERTION_ERROR) { PyObject *value = PyExc_AssertionError; Py_INCREF(value); diff --git a/Python/compile.c b/Python/compile.c index 3dec7b5edfb5..339e0e792be4 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1234,6 +1234,8 @@ stack_effect(int opcode, int oparg, int jump) return 0; case END_ASYNC_FOR: return -2; + case CLEANUP_THROW: + return -2; case FORMAT_VALUE: /* If there's a fmt_spec on the stack, we go from 2->1, else 1->1. */ @@ -1946,17 +1948,22 @@ compiler_call_exit_with_nones(struct compiler *c) { static int compiler_add_yield_from(struct compiler *c, int await) { - NEW_JUMP_TARGET_LABEL(c, start); - NEW_JUMP_TARGET_LABEL(c, resume); + NEW_JUMP_TARGET_LABEL(c, send); + NEW_JUMP_TARGET_LABEL(c, fail); NEW_JUMP_TARGET_LABEL(c, exit); - USE_LABEL(c, start); + USE_LABEL(c, send); ADDOP_JUMP(c, SEND, exit); - - USE_LABEL(c, resume); + // Set up a virtual try/except to handle when StopIteration is raised during + // a close or throw call. The only way YIELD_VALUE raises if they do! + ADDOP_JUMP(c, SETUP_FINALLY, fail); ADDOP_I(c, YIELD_VALUE, 0); + ADDOP_NOLINE(c, POP_BLOCK); ADDOP_I(c, RESUME, await ? 3 : 2); - ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start); + ADDOP_JUMP(c, JUMP_NO_INTERRUPT, send); + + USE_LABEL(c, fail); + ADDOP(c, CLEANUP_THROW); USE_LABEL(c, exit); return 1; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index db4bbc466a94..7c782d101c1b 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -54,38 +54,38 @@ static void *opcode_targets[256] = { &&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_WITH, &&TARGET_END_ASYNC_FOR, + &&TARGET_CLEANUP_THROW, &&TARGET_CALL_NO_KW_TYPE_1, &&TARGET_COMPARE_OP_ADAPTIVE, &&TARGET_COMPARE_OP_FLOAT_JUMP, &&TARGET_COMPARE_OP_INT_JUMP, - &&TARGET_COMPARE_OP_STR_JUMP, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, + &&TARGET_COMPARE_OP_STR_JUMP, &&TARGET_EXTENDED_ARG_QUICK, &&TARGET_FOR_ITER_ADAPTIVE, &&TARGET_FOR_ITER_LIST, &&TARGET_FOR_ITER_RANGE, &&TARGET_JUMP_BACKWARD_QUICK, - &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, + &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_CLASS, - &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, + &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_LOAD_ATTR_METHOD_NO_DICT, + &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, &&TARGET_ASYNC_GEN_WRAP, &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_POP_JUMP_FORWARD_IF_FALSE, &&TARGET_POP_JUMP_FORWARD_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,7 +120,7 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, + &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, @@ -140,9 +140,9 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, @@ -152,30 +152,31 @@ static void *opcode_targets[256] = { &&TARGET_YIELD_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_FAST__LOAD_FAST, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, + &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_RESUME_QUICK, - &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, + &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_CALL, &&TARGET_KW_NAMES, &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, + &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, @@ -253,6 +254,5 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_DO_TRACING }; From webhook-mailer at python.org Fri Aug 19 15:41:35 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 19:41:35 -0000 Subject: [Python-checkins] gh-96125: Fix sys.thread_info.name on pthread platforms (GH-96126) Message-ID: <mailman.748.1660938096.3313.python-checkins@python.org> https://github.com/python/cpython/commit/822955c16654c22c10a993f5a94bbb68b857a150 commit: 822955c16654c22c10a993f5a94bbb68b857a150 branch: main author: Christian Heimes <christian at python.org> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T12:41:25-07:00 summary: gh-96125: Fix sys.thread_info.name on pthread platforms (GH-96126) Automerge-Triggered-By: GH:tiran files: A Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst M Lib/test/test_sys.py M Python/thread.c diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 78da09d6abc..202fb30a8a7 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -628,6 +628,14 @@ def test_thread_info(self): self.assertEqual(len(info), 3) self.assertIn(info.name, ('nt', 'pthread', 'pthread-stubs', 'solaris', None)) self.assertIn(info.lock, ('semaphore', 'mutex+cond', None)) + if sys.platform.startswith(("linux", "freebsd")): + self.assertEqual(info.name, "pthread") + elif sys.platform == "win32": + self.assertEqual(info.name, "nt") + elif sys.platform == "emscripten": + self.assertIn(info.name, {"pthread", "pthread-stubs"}) + elif sys.platform == "wasi": + self.assertEqual(info.name, "pthread-stubs") @unittest.skipUnless(support.is_emscripten, "only available on Emscripten") def test_emscripten_info(self): diff --git a/Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst b/Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst new file mode 100644 index 00000000000..ba7d26a9658 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst @@ -0,0 +1,2 @@ +Fix incorrect condition that causes ``sys.thread_info.name`` to be wrong on +pthread platforms. diff --git a/Python/thread.c b/Python/thread.c index e206a69c050..8c8a4e81895 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -59,7 +59,7 @@ PyThread_init_thread(void) # define PYTHREAD_NAME "pthread-stubs" # include "thread_pthread_stubs.h" #elif defined(_POSIX_THREADS) -# if defined(__EMSCRIPTEN__) || !defined(__EMSCRIPTEN_PTHREADS__) +# if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) # define PYTHREAD_NAME "pthread-stubs" # else # define PYTHREAD_NAME "pthread" From webhook-mailer at python.org Fri Aug 19 15:43:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 19 Aug 2022 19:43:08 -0000 Subject: [Python-checkins] GH-96071: fix deadlock in PyGILState_Ensure (GH-96124) Message-ID: <mailman.749.1660938189.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e0d54a4a799dae4ebdd72a16bcf287ed62ae2972 commit: e0d54a4a799dae4ebdd72a16bcf287ed62ae2972 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-19T12:43:00-07:00 summary: GH-96071: fix deadlock in PyGILState_Ensure (GH-96124) Alternative of #96107 files: A Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst M Python/pystate.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst new file mode 100644 index 000000000000..37653ffac124 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst @@ -0,0 +1 @@ +Fix a deadlock in :c:func:`PyGILState_Ensure` when allocating new thread state. Patch by Kumar Aditya. diff --git a/Python/pystate.c b/Python/pystate.c index 642d680ba20b..a11f1622ecd4 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -810,7 +810,15 @@ new_threadstate(PyInterpreterState *interp) { PyThreadState *tstate; _PyRuntimeState *runtime = interp->runtime; - + // We don't need to allocate a thread state for the main interpreter + // (the common case), but doing it later for the other case revealed a + // reentrancy problem (deadlock). So for now we always allocate before + // taking the interpreters lock. See GH-96071. + PyThreadState *new_tstate = alloc_threadstate(); + int used_newtstate; + if (new_tstate == NULL) { + return NULL; + } /* We serialize concurrent creation to protect global state. */ HEAD_LOCK(runtime); @@ -822,18 +830,15 @@ new_threadstate(PyInterpreterState *interp) if (old_head == NULL) { // It's the interpreter's initial thread state. assert(id == 1); - + used_newtstate = 0; tstate = &interp->_initial_thread; } else { // Every valid interpreter must have at least one thread. assert(id > 1); assert(old_head->prev == NULL); - - tstate = alloc_threadstate(); - if (tstate == NULL) { - goto error; - } + used_newtstate = 1; + tstate = new_tstate; // Set to _PyThreadState_INIT. memcpy(tstate, &initial._main_interpreter._initial_thread, @@ -844,11 +849,11 @@ new_threadstate(PyInterpreterState *interp) init_threadstate(tstate, interp, id, old_head); HEAD_UNLOCK(runtime); + if (!used_newtstate) { + // Must be called with lock unlocked to avoid re-entrancy deadlock. + PyMem_RawFree(new_tstate); + } return tstate; - -error: - HEAD_UNLOCK(runtime); - return NULL; } PyThreadState * From webhook-mailer at python.org Fri Aug 19 17:11:40 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 19 Aug 2022 21:11:40 -0000 Subject: [Python-checkins] GH-96071: fix deadlock in PyGILState_Ensure (GH-96124) (#96129) Message-ID: <mailman.750.1660943501.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1fa9644c23632f8ffc3f59e7f574b92185c371e4 commit: 1fa9644c23632f8ffc3f59e7f574b92185c371e4 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-19T22:11:31+01:00 summary: GH-96071: fix deadlock in PyGILState_Ensure (GH-96124) (#96129) Alternative of GH-96107 (cherry picked from commit e0d54a4a799dae4ebdd72a16bcf287ed62ae2972) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst M Python/pystate.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst new file mode 100644 index 000000000000..37653ffac124 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-19-06-51-17.gh-issue-96071.mVgPAo.rst @@ -0,0 +1 @@ +Fix a deadlock in :c:func:`PyGILState_Ensure` when allocating new thread state. Patch by Kumar Aditya. diff --git a/Python/pystate.c b/Python/pystate.c index 2e4585688ea8..a0c12bac9d14 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -795,7 +795,15 @@ new_threadstate(PyInterpreterState *interp) { PyThreadState *tstate; _PyRuntimeState *runtime = interp->runtime; - + // We don't need to allocate a thread state for the main interpreter + // (the common case), but doing it later for the other case revealed a + // reentrancy problem (deadlock). So for now we always allocate before + // taking the interpreters lock. See GH-96071. + PyThreadState *new_tstate = alloc_threadstate(); + int used_newtstate; + if (new_tstate == NULL) { + return NULL; + } /* We serialize concurrent creation to protect global state. */ HEAD_LOCK(runtime); @@ -807,18 +815,15 @@ new_threadstate(PyInterpreterState *interp) if (old_head == NULL) { // It's the interpreter's initial thread state. assert(id == 1); - + used_newtstate = 0; tstate = &interp->_initial_thread; } else { // Every valid interpreter must have at least one thread. assert(id > 1); assert(old_head->prev == NULL); - - tstate = alloc_threadstate(); - if (tstate == NULL) { - goto error; - } + used_newtstate = 1; + tstate = new_tstate; // Set to _PyThreadState_INIT. memcpy(tstate, &initial._main_interpreter._initial_thread, @@ -829,11 +834,11 @@ new_threadstate(PyInterpreterState *interp) init_threadstate(tstate, interp, id, old_head); HEAD_UNLOCK(runtime); + if (!used_newtstate) { + // Must be called with lock unlocked to avoid re-entrancy deadlock. + PyMem_RawFree(new_tstate); + } return tstate; - -error: - HEAD_UNLOCK(runtime); - return NULL; } PyThreadState * From webhook-mailer at python.org Sat Aug 20 11:11:43 2022 From: webhook-mailer at python.org (corona10) Date: Sat, 20 Aug 2022 15:11:43 -0000 Subject: [Python-checkins] gh-90536: Fix link syntax to LLVM-BOLT repository (gh-96141) Message-ID: <mailman.751.1661008304.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6ec57e7c5af6816178d34233a4da12eb0c21c9d9 commit: 6ec57e7c5af6816178d34233a4da12eb0c21c9d9 branch: main author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-21T00:11:35+09:00 summary: gh-90536: Fix link syntax to LLVM-BOLT repository (gh-96141) files: M Doc/using/configure.rst diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index ef770d7747c3..cd5540320c4f 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -235,7 +235,7 @@ also be used to improve performance. .. cmdoption:: --enable-bolt Enable usage of the `BOLT post-link binary optimizer - <https://github.com/llvm/llvm-project/tree/main/bolt>` (disabled by + <https://github.com/llvm/llvm-project/tree/main/bolt>`_ (disabled by default). BOLT is part of the LLVM project but is not always included in their binary From webhook-mailer at python.org Sat Aug 20 22:09:17 2022 From: webhook-mailer at python.org (ncoghlan) Date: Sun, 21 Aug 2022 02:09:17 -0000 Subject: [Python-checkins] gh-96098: Clearly link concurrent.futures from threading & multiprocessing docs (GH-96112) Message-ID: <mailman.752.1661047758.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bcc4cb0c7d5e0590928e74cae86b0a7938c0f74b commit: bcc4cb0c7d5e0590928e74cae86b0a7938c0f74b branch: main author: Nick Coghlan <ncoghlan at gmail.com> committer: ncoghlan <ncoghlan at gmail.com> date: 2022-08-21T14:09:05+12:00 summary: gh-96098: Clearly link concurrent.futures from threading & multiprocessing docs (GH-96112) Clearly link concurrent.futures from threading & multiprocessing docs Also link directly to asyncio from the beginning of the threading docs. files: A Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst M Doc/library/multiprocessing.rst M Doc/library/threading.rst diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index eaa946462a11..caf24a35fdfc 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -45,6 +45,16 @@ will print to standard output :: [1, 4, 9] +.. seealso:: + + :class:`concurrent.futures.ProcessPoolExecutor` offers a higher level interface + to push tasks to a background process without blocking execution of the + calling process. Compared to using the :class:`~multiprocessing.pool.Pool` + interface directly, the :mod:`concurrent.futures` API more readily allows + the submission of work to the underlying process pool to be separated from + waiting for the results. + + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index a8851dd15052..b22d48766224 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -9,11 +9,23 @@ -------------- This module constructs higher-level threading interfaces on top of the lower -level :mod:`_thread` module. See also the :mod:`queue` module. +level :mod:`_thread` module. .. versionchanged:: 3.7 This module used to be optional, it is now always available. +.. seealso:: + + :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface + to push tasks to a background thread without blocking execution of the + calling thread, while still being able to retrieve their results when needed. + + :mod:`queue` provides a thread-safe interface for exchanging data between + running threads. + + :mod:`asyncio` offers an alternative approach to achieving task level + concurrency without requiring the use of multiple operating system threads. + .. note:: In the Python 2.x series, this module contained ``camelCase`` names diff --git a/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst b/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst new file mode 100644 index 000000000000..5ead20bbb535 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst @@ -0,0 +1,3 @@ +Improve discoverability of the higher level concurrent.futures module by +providing clearer links from the lower level threading and multiprocessing +modules. From webhook-mailer at python.org Sun Aug 21 00:27:41 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 21 Aug 2022 04:27:41 -0000 Subject: [Python-checkins] gh-96098: Clearly link concurrent.futures from threading & multiprocessing docs (GH-96112) Message-ID: <mailman.753.1661056061.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5a094f0255eea1db58fb2cf14c200971e64ec36e commit: 5a094f0255eea1db58fb2cf14c200971e64ec36e branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-20T21:27:22-07:00 summary: gh-96098: Clearly link concurrent.futures from threading & multiprocessing docs (GH-96112) Clearly link concurrent.futures from threading & multiprocessing docs Also link directly to asyncio from the beginning of the threading docs. (cherry picked from commit bcc4cb0c7d5e0590928e74cae86b0a7938c0f74b) Co-authored-by: Nick Coghlan <ncoghlan at gmail.com> files: A Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst M Doc/library/multiprocessing.rst M Doc/library/threading.rst diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 0de44855a50c..18e9b1ee8cb3 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -43,6 +43,16 @@ will print to standard output :: [1, 4, 9] +.. seealso:: + + :class:`concurrent.futures.ProcessPoolExecutor` offers a higher level interface + to push tasks to a background process without blocking execution of the + calling process. Compared to using the :class:`~multiprocessing.pool.Pool` + interface directly, the :mod:`concurrent.futures` API more readily allows + the submission of work to the underlying process pool to be separated from + waiting for the results. + + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 14434fbd52d0..47ff74dfc67f 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -9,11 +9,23 @@ -------------- This module constructs higher-level threading interfaces on top of the lower -level :mod:`_thread` module. See also the :mod:`queue` module. +level :mod:`_thread` module. .. versionchanged:: 3.7 This module used to be optional, it is now always available. +.. seealso:: + + :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface + to push tasks to a background thread without blocking execution of the + calling thread, while still being able to retrieve their results when needed. + + :mod:`queue` provides a thread-safe interface for exchanging data between + running threads. + + :mod:`asyncio` offers an alternative approach to achieving task level + concurrency without requiring the use of multiple operating system threads. + .. note:: In the Python 2.x series, this module contained ``camelCase`` names diff --git a/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst b/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst new file mode 100644 index 000000000000..5ead20bbb535 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst @@ -0,0 +1,3 @@ +Improve discoverability of the higher level concurrent.futures module by +providing clearer links from the lower level threading and multiprocessing +modules. From webhook-mailer at python.org Sun Aug 21 00:28:14 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 21 Aug 2022 04:28:14 -0000 Subject: [Python-checkins] gh-96098: Clearly link concurrent.futures from threading & multiprocessing docs (GH-96112) Message-ID: <mailman.754.1661056095.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b21ff7433e74307ff584222695c817e8b200d23b commit: b21ff7433e74307ff584222695c817e8b200d23b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-20T21:28:10-07:00 summary: gh-96098: Clearly link concurrent.futures from threading & multiprocessing docs (GH-96112) Clearly link concurrent.futures from threading & multiprocessing docs Also link directly to asyncio from the beginning of the threading docs. (cherry picked from commit bcc4cb0c7d5e0590928e74cae86b0a7938c0f74b) Co-authored-by: Nick Coghlan <ncoghlan at gmail.com> files: A Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst M Doc/library/multiprocessing.rst M Doc/library/threading.rst diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index eaa946462a11..caf24a35fdfc 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -45,6 +45,16 @@ will print to standard output :: [1, 4, 9] +.. seealso:: + + :class:`concurrent.futures.ProcessPoolExecutor` offers a higher level interface + to push tasks to a background process without blocking execution of the + calling process. Compared to using the :class:`~multiprocessing.pool.Pool` + interface directly, the :mod:`concurrent.futures` API more readily allows + the submission of work to the underlying process pool to be separated from + waiting for the results. + + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 9511eaebf158..ef140d75c431 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -9,11 +9,23 @@ -------------- This module constructs higher-level threading interfaces on top of the lower -level :mod:`_thread` module. See also the :mod:`queue` module. +level :mod:`_thread` module. .. versionchanged:: 3.7 This module used to be optional, it is now always available. +.. seealso:: + + :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface + to push tasks to a background thread without blocking execution of the + calling thread, while still being able to retrieve their results when needed. + + :mod:`queue` provides a thread-safe interface for exchanging data between + running threads. + + :mod:`asyncio` offers an alternative approach to achieving task level + concurrency without requiring the use of multiple operating system threads. + .. note:: In the Python 2.x series, this module contained ``camelCase`` names diff --git a/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst b/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst new file mode 100644 index 000000000000..5ead20bbb535 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst @@ -0,0 +1,3 @@ +Improve discoverability of the higher level concurrent.futures module by +providing clearer links from the lower level threading and multiprocessing +modules. From webhook-mailer at python.org Sun Aug 21 10:40:35 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 14:40:35 -0000 Subject: [Python-checkins] GH-93179: Document the thread safety of functools.lru_cache (GH-96101) Message-ID: <mailman.755.1661092837.3313.python-checkins@python.org> https://github.com/python/cpython/commit/eea8f42deddb3b6fec80984e7557b1f0c4578b62 commit: eea8f42deddb3b6fec80984e7557b1f0c4578b62 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T09:40:13-05:00 summary: GH-93179: Document the thread safety of functools.lru_cache (GH-96101) files: From webhook-mailer at python.org Sun Aug 21 10:41:37 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 14:41:37 -0000 Subject: [Python-checkins] Add polynomial_from_roots() to the itertools recipes (#96102) Message-ID: <mailman.756.1661092898.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0e28a3a50ff9c612a2a745907ebcb30911fd51e8 commit: 0e28a3a50ff9c612a2a745907ebcb30911fd51e8 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T09:41:29-05:00 summary: Add polynomial_from_roots() to the itertools recipes (#96102) files: M Doc/library/itertools.rst diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 55a4c90137f..c35ff8c4343 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -800,6 +800,18 @@ which incur interpreter overhead. window.append(x) yield sum(map(operator.mul, kernel, window)) + def polynomial_from_roots(roots): + """Compute a polynomial's coefficients from its roots. + + (x - 5) (x + 4) (x - 3) expands to: x? -4x? -17x + 60 + """ + # polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60] + roots = list(map(operator.neg, roots)) + return [ + sum(map(math.prod, combinations(roots, k))) + for k in range(len(roots) + 1) + ] + def flatten(list_of_lists): "Flatten one level of nesting" return chain.from_iterable(list_of_lists) @@ -1137,6 +1149,13 @@ which incur interpreter overhead. >>> list(convolve(data, [1, -2, 1])) [20, 0, -36, 24, -20, 20, -20, -4, 16] + >>> polynomial_from_roots([5, -4, 3]) + [1, -4, -17, 60] + >>> factored = lambda x: (x - 5) * (x + 4) * (x - 3) + >>> expanded = lambda x: x**3 -4*x**2 -17*x + 60 + >>> all(factored(x) == expanded(x) for x in range(-10, 11)) + True + >>> list(flatten([('a', 'b'), (), ('c', 'd', 'e'), ('f',), ('g', 'h', 'i')])) ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] From webhook-mailer at python.org Sun Aug 21 10:42:23 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 14:42:23 -0000 Subject: [Python-checkins] GH-95880: Clarify StringIO append/overwrite behavior. (GH-96104) Message-ID: <mailman.757.1661092943.3313.python-checkins@python.org> https://github.com/python/cpython/commit/511dea0a3ea9beb2fd72c7c689e2b1cb1636a6fa commit: 511dea0a3ea9beb2fd72c7c689e2b1cb1636a6fa branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T09:42:15-05:00 summary: GH-95880: Clarify StringIO append/overwrite behavior. (GH-96104) files: M Doc/library/io.rst diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 753e6c1e3b9..97a70646a93 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -1052,8 +1052,12 @@ Text I/O The initial value of the buffer can be set by providing *initial_value*. If newline translation is enabled, newlines will be encoded as if by - :meth:`~TextIOBase.write`. The stream is positioned at the start of - the buffer. + :meth:`~TextIOBase.write`. The stream is positioned at the start of the + buffer which emulates opening an existing file in a `w+` mode, making it + ready for an immediate write from the beginning or for a write that + would overwrite the initial value. To emulate opening a file in an `a+` + mode ready for appending, use `f.seek(0, io.SEEK_END)` to reposition the + stream at the end of the buffer. The *newline* argument works like that of :class:`TextIOWrapper`, except that when writing output to the stream, if *newline* is ``None``, From webhook-mailer at python.org Sun Aug 21 10:47:54 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 14:47:54 -0000 Subject: [Python-checkins] Add polynomial_from_roots() to the itertools recipes (GH-96102) (#96155) Message-ID: <mailman.758.1661093275.3313.python-checkins@python.org> https://github.com/python/cpython/commit/21c46f359b8c0ef3c63b01afb81053c591434b60 commit: 21c46f359b8c0ef3c63b01afb81053c591434b60 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T09:47:45-05:00 summary: Add polynomial_from_roots() to the itertools recipes (GH-96102) (#96155) files: M Doc/library/itertools.rst diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 416c4eca5eb..da550e6fa25 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -800,6 +800,18 @@ which incur interpreter overhead. window.append(x) yield sum(map(operator.mul, kernel, window)) + def polynomial_from_roots(roots): + """Compute a polynomial's coefficients from its roots. + + (x - 5) (x + 4) (x - 3) expands to: x? -4x? -17x + 60 + """ + # polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60] + roots = list(map(operator.neg, roots)) + return [ + sum(map(math.prod, combinations(roots, k))) + for k in range(len(roots) + 1) + ] + def flatten(list_of_lists): "Flatten one level of nesting" return chain.from_iterable(list_of_lists) @@ -1137,6 +1149,13 @@ which incur interpreter overhead. >>> list(convolve(data, [1, -2, 1])) [20, 0, -36, 24, -20, 20, -20, -4, 16] + >>> polynomial_from_roots([5, -4, 3]) + [1, -4, -17, 60] + >>> factored = lambda x: (x - 5) * (x + 4) * (x - 3) + >>> expanded = lambda x: x**3 -4*x**2 -17*x + 60 + >>> all(factored(x) == expanded(x) for x in range(-10, 11)) + True + >>> list(flatten([('a', 'b'), (), ('c', 'd', 'e'), ('f',), ('g', 'h', 'i')])) ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] From webhook-mailer at python.org Sun Aug 21 10:55:55 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 14:55:55 -0000 Subject: [Python-checkins] GH-95880: Clarify StringIO append/overwrite behavior. (GH-96104) (GH-96156) Message-ID: <mailman.759.1661093755.3313.python-checkins@python.org> https://github.com/python/cpython/commit/58e1fe24c71a865a60bc9975c664dabba77f8588 commit: 58e1fe24c71a865a60bc9975c664dabba77f8588 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T09:55:50-05:00 summary: GH-95880: Clarify StringIO append/overwrite behavior. (GH-96104) (GH-96156) files: M Doc/library/io.rst diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 753e6c1e3b9..97a70646a93 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -1052,8 +1052,12 @@ Text I/O The initial value of the buffer can be set by providing *initial_value*. If newline translation is enabled, newlines will be encoded as if by - :meth:`~TextIOBase.write`. The stream is positioned at the start of - the buffer. + :meth:`~TextIOBase.write`. The stream is positioned at the start of the + buffer which emulates opening an existing file in a `w+` mode, making it + ready for an immediate write from the beginning or for a write that + would overwrite the initial value. To emulate opening a file in an `a+` + mode ready for appending, use `f.seek(0, io.SEEK_END)` to reposition the + stream at the end of the buffer. The *newline* argument works like that of :class:`TextIOWrapper`, except that when writing output to the stream, if *newline* is ``None``, From webhook-mailer at python.org Sun Aug 21 10:57:00 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 14:57:00 -0000 Subject: [Python-checkins] small grammatical change (GH-96138) Message-ID: <mailman.760.1661093821.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d8c7a1174cc182668085b10aab4049f6a2794c2f commit: d8c7a1174cc182668085b10aab4049f6a2794c2f branch: main author: sand8089 <89005131+sand8089 at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T09:56:52-05:00 summary: small grammatical change (GH-96138) changed a to an under An example that uses most of the list methods files: M Doc/tutorial/datastructures.rst diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index f5986fe292fb..12b00be3793e 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -106,7 +106,7 @@ An example that uses most of the list methods:: 0 >>> fruits.index('banana') 3 - >>> fruits.index('banana', 4) # Find next banana starting a position 4 + >>> fruits.index('banana', 4) # Find next banana starting at position 4 6 >>> fruits.reverse() >>> fruits From webhook-mailer at python.org Sun Aug 21 12:37:20 2022 From: webhook-mailer at python.org (pablogsal) Date: Sun, 21 Aug 2022 16:37:20 -0000 Subject: [Python-checkins] gh-96125: Fix sys.thread_info.name on pthread platforms (GH-96126) (#96128) Message-ID: <mailman.761.1661099841.3313.python-checkins@python.org> https://github.com/python/cpython/commit/27f390bc308870732785905b15d72d4811233110 commit: 27f390bc308870732785905b15d72d4811233110 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-21T17:37:15+01:00 summary: gh-96125: Fix sys.thread_info.name on pthread platforms (GH-96126) (#96128) Automerge-Triggered-By: GH:tiran (cherry picked from commit 822955c16654c22c10a993f5a94bbb68b857a150) Co-authored-by: Christian Heimes <christian at python.org> Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst M Lib/test/test_sys.py M Python/thread.c diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index c513cf08a116..f87fcaa8f9e2 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -628,6 +628,14 @@ def test_thread_info(self): self.assertEqual(len(info), 3) self.assertIn(info.name, ('nt', 'pthread', 'pthread-stubs', 'solaris', None)) self.assertIn(info.lock, ('semaphore', 'mutex+cond', None)) + if sys.platform.startswith(("linux", "freebsd")): + self.assertEqual(info.name, "pthread") + elif sys.platform == "win32": + self.assertEqual(info.name, "nt") + elif sys.platform == "emscripten": + self.assertIn(info.name, {"pthread", "pthread-stubs"}) + elif sys.platform == "wasi": + self.assertEqual(info.name, "pthread-stubs") @unittest.skipUnless(support.is_emscripten, "only available on Emscripten") def test_emscripten_info(self): diff --git a/Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst b/Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst new file mode 100644 index 000000000000..ba7d26a96582 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-19-18-21-01.gh-issue-96125.ODcF1Y.rst @@ -0,0 +1,2 @@ +Fix incorrect condition that causes ``sys.thread_info.name`` to be wrong on +pthread platforms. diff --git a/Python/thread.c b/Python/thread.c index 08bcdda0483d..940d8b8093ab 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -97,7 +97,7 @@ _PyThread_debug_deprecation(void) # define PYTHREAD_NAME "pthread-stubs" # include "thread_pthread_stubs.h" #elif defined(_POSIX_THREADS) -# if defined(__EMSCRIPTEN__) || !defined(__EMSCRIPTEN_PTHREADS__) +# if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) # define PYTHREAD_NAME "pthread-stubs" # else # define PYTHREAD_NAME "pthread" From webhook-mailer at python.org Sun Aug 21 16:55:05 2022 From: webhook-mailer at python.org (rhettinger) Date: Sun, 21 Aug 2022 20:55:05 -0000 Subject: [Python-checkins] small grammatical change (GH-96138) (GH-96157) Message-ID: <mailman.762.1661115306.3313.python-checkins@python.org> https://github.com/python/cpython/commit/fedd25eb645d1371a5f8e28e4574c4aa0d0193e7 commit: fedd25eb645d1371a5f8e28e4574c4aa0d0193e7 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-21T15:55:00-05:00 summary: small grammatical change (GH-96138) (GH-96157) files: M Doc/tutorial/datastructures.rst diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index f5986fe292fb..12b00be3793e 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -106,7 +106,7 @@ An example that uses most of the list methods:: 0 >>> fruits.index('banana') 3 - >>> fruits.index('banana', 4) # Find next banana starting a position 4 + >>> fruits.index('banana', 4) # Find next banana starting at position 4 6 >>> fruits.reverse() >>> fruits From webhook-mailer at python.org Mon Aug 22 01:24:27 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 05:24:27 -0000 Subject: [Python-checkins] gh-96046: Initialize ht_cached_keys in PyType_Ready() (GH-96047) Message-ID: <mailman.763.1661145868.3313.python-checkins@python.org> https://github.com/python/cpython/commit/53e6a9a7254bdcd0538580ba7d799cd453e2dca5 commit: 53e6a9a7254bdcd0538580ba7d799cd453e2dca5 branch: main author: Christian Heimes <christian at python.org> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-21T22:24:03-07:00 summary: gh-96046: Initialize ht_cached_keys in PyType_Ready() (GH-96047) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst M Objects/typeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst new file mode 100644 index 00000000000..b8cb52d4b4e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst @@ -0,0 +1,4 @@ +:c:func:`PyType_Ready` now initializes ``ht_cached_keys`` and performs +additional checks to ensure that type objects are properly configured. This +avoids crashes in 3rd party packages that don't use regular API to create +new types. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e61acd295ac..40d42947dbc 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3287,11 +3287,6 @@ type_new_impl(type_new_ctx *ctx) // Put the proper slots in place fixup_slot_dispatchers(type); - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyHeapTypeObject *et = (PyHeapTypeObject*)type; - et->ht_cached_keys = _PyDict_NewKeysForClass(); - } - if (type_new_set_names(type) < 0) { goto error; } @@ -3836,10 +3831,6 @@ PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, goto finally; } - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - res->ht_cached_keys = _PyDict_NewKeysForClass(); - } - if (type->tp_doc) { PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); if (!__doc__) { @@ -6774,6 +6765,29 @@ type_ready_set_new(PyTypeObject *type) return 0; } +static int +type_ready_managed_dict(PyTypeObject *type) +{ + if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + return 0; + } + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but not Py_TPFLAGS_HEAPTYPE flag", + type->tp_name); + return -1; + } + PyHeapTypeObject* et = (PyHeapTypeObject*)type; + if (et->ht_cached_keys == NULL) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + if (et->ht_cached_keys == NULL) { + PyErr_NoMemory(); + return -1; + } + } + return 0; +} static int type_ready_post_checks(PyTypeObject *type) @@ -6852,6 +6866,9 @@ type_ready(PyTypeObject *type) if (type_ready_add_subclasses(type) < 0) { return -1; } + if (type_ready_managed_dict(type) < 0) { + return -1; + } if (type_ready_post_checks(type) < 0) { return -1; } From webhook-mailer at python.org Mon Aug 22 04:03:46 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 22 Aug 2022 08:03:46 -0000 Subject: [Python-checkins] gh-96121: Merge sqlite3.Row examples into sqlite3.Row class doc (#96122) Message-ID: <mailman.764.1661155428.3313.python-checkins@python.org> https://github.com/python/cpython/commit/18b1782192f85bd26db89f5bc850f8bee4247c1a commit: 18b1782192f85bd26db89f5bc850f8bee4247c1a branch: main author: Erlend E. Aasland <erlend.aasland at innova.no> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-22T10:03:24+02:00 summary: gh-96121: Merge sqlite3.Row examples into sqlite3.Row class doc (#96122) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: D Doc/includes/sqlite3/rowclass.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py deleted file mode 100644 index fc60287069a8..000000000000 --- a/Doc/includes/sqlite3/rowclass.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.row_factory = sqlite3.Row - -cur = con.cursor() -cur.execute("select 'John' as name, 42 as age") -for row in cur: - assert row[0] == row["name"] - assert row["name"] == row["nAmE"] - assert row[1] == row["age"] - assert row[1] == row["AgE"] - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 6413d8859180..0d1185dd4658 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -207,7 +207,6 @@ inserted data and retrieved values from it in multiple ways. * :ref:`sqlite3-placeholders` * :ref:`sqlite3-adapters` * :ref:`sqlite3-converters` - * :ref:`sqlite3-columns-by-name` * :ref:`sqlite3-connection-context-manager` * :ref:`sqlite3-explanation` for in-depth background on transaction control. @@ -1255,6 +1254,11 @@ Cursor objects >>> cur.connection == con True +.. The sqlite3.Row example used to be a how-to. It has now been incorporated + into the Row reference. We keep the anchor here in order not to break + existing links. + +.. _sqlite3-columns-by-name: .. _sqlite3-row-objects: Row objects @@ -1262,10 +1266,9 @@ Row objects .. class:: Row - A :class:`Row` instance serves as a highly optimized + A :class:`!Row` instance serves as a highly optimized :attr:`~Connection.row_factory` for :class:`Connection` objects. - It tries to mimic a :class:`tuple` in most of its features, - and supports iteration, :func:`repr`, equality testing, :func:`len`, + It supports iteration, equality testing, :func:`len`, and :term:`mapping` access by column name and index. Two row objects compare equal if have equal columns and equal members. @@ -1279,45 +1282,18 @@ Row objects .. versionchanged:: 3.5 Added support of slicing. -Let's assume we initialize a table as in the example given above:: + Example:: - con = sqlite3.connect(":memory:") - cur = con.cursor() - cur.execute('''create table stocks - (date text, trans text, symbol text, - qty real, price real)''') - cur.execute("""insert into stocks - values ('2006-01-05','BUY','RHAT',100,35.14)""") - con.commit() - cur.close() - -Now we plug :class:`Row` in:: - - >>> con.row_factory = sqlite3.Row - >>> cur = con.cursor() - >>> cur.execute('select * from stocks') - <sqlite3.Cursor object at 0x7f4e7dd8fa80> - >>> r = cur.fetchone() - >>> type(r) - <class 'sqlite3.Row'> - >>> tuple(r) - ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14) - >>> len(r) - 5 - >>> r[2] - 'RHAT' - >>> r.keys() - ['date', 'trans', 'symbol', 'qty', 'price'] - >>> r['qty'] - 100.0 - >>> for member in r: - ... print(member) - ... - 2006-01-05 - BUY - RHAT - 100.0 - 35.14 + >>> con = sqlite3.connect(":memory:") + >>> con.row_factory = sqlite3.Row + >>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius") + >>> row = res.fetchone() + >>> row.keys() + ['name', 'radius'] + >>> row[0], row["name"] # Access by index and name. + ('Earth', 'Earth') + >>> row["RADIUS"] # Column names are case-insensitive. + 6378 .. _sqlite3-blob-objects: @@ -1766,20 +1742,6 @@ directly using only a single call on the :class:`Connection` object. .. literalinclude:: ../includes/sqlite3/shortcut_methods.py -.. _sqlite3-columns-by-name: - -Accessing columns by name instead of by index -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -One useful feature of the :mod:`!sqlite3` module is the built-in -:class:`sqlite3.Row` class designed to be used as a row factory. - -Rows wrapped with this class can be accessed both by index (like tuples) and -case-insensitively by name: - -.. literalinclude:: ../includes/sqlite3/rowclass.py - - .. _sqlite3-connection-context-manager: Using the connection as a context manager From webhook-mailer at python.org Mon Aug 22 04:11:06 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 08:11:06 -0000 Subject: [Python-checkins] gh-96121: Merge sqlite3.Row examples into sqlite3.Row class doc (GH-96122) Message-ID: <mailman.765.1661155868.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a836204777dad55c983efba58e654a62a7bfdf61 commit: a836204777dad55c983efba58e654a62a7bfdf61 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T01:10:53-07:00 summary: gh-96121: Merge sqlite3.Row examples into sqlite3.Row class doc (GH-96122) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> (cherry picked from commit 18b1782192f85bd26db89f5bc850f8bee4247c1a) Co-authored-by: Erlend E. Aasland <erlend.aasland at innova.no> files: D Doc/includes/sqlite3/rowclass.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py deleted file mode 100644 index fc60287069a8..000000000000 --- a/Doc/includes/sqlite3/rowclass.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.row_factory = sqlite3.Row - -cur = con.cursor() -cur.execute("select 'John' as name, 42 as age") -for row in cur: - assert row[0] == row["name"] - assert row["name"] == row["nAmE"] - assert row[1] == row["age"] - assert row[1] == row["AgE"] - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index d01c7b554e9c..1f7ebbe109ff 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -207,7 +207,6 @@ inserted data and retrieved values from it in multiple ways. * :ref:`sqlite3-placeholders` * :ref:`sqlite3-adapters` * :ref:`sqlite3-converters` - * :ref:`sqlite3-columns-by-name` * :ref:`sqlite3-connection-context-manager` * :ref:`sqlite3-explanation` for in-depth background on transaction control. @@ -1017,6 +1016,11 @@ Cursor objects >>> cur.connection == con True +.. The sqlite3.Row example used to be a how-to. It has now been incorporated + into the Row reference. We keep the anchor here in order not to break + existing links. + +.. _sqlite3-columns-by-name: .. _sqlite3-row-objects: Row objects @@ -1024,10 +1028,9 @@ Row objects .. class:: Row - A :class:`Row` instance serves as a highly optimized + A :class:`!Row` instance serves as a highly optimized :attr:`~Connection.row_factory` for :class:`Connection` objects. - It tries to mimic a :class:`tuple` in most of its features, - and supports iteration, :func:`repr`, equality testing, :func:`len`, + It supports iteration, equality testing, :func:`len`, and :term:`mapping` access by column name and index. Two row objects compare equal if have equal columns and equal members. @@ -1041,45 +1044,18 @@ Row objects .. versionchanged:: 3.5 Added support of slicing. -Let's assume we initialize a table as in the example given above:: + Example:: - con = sqlite3.connect(":memory:") - cur = con.cursor() - cur.execute('''create table stocks - (date text, trans text, symbol text, - qty real, price real)''') - cur.execute("""insert into stocks - values ('2006-01-05','BUY','RHAT',100,35.14)""") - con.commit() - cur.close() - -Now we plug :class:`Row` in:: - - >>> con.row_factory = sqlite3.Row - >>> cur = con.cursor() - >>> cur.execute('select * from stocks') - <sqlite3.Cursor object at 0x7f4e7dd8fa80> - >>> r = cur.fetchone() - >>> type(r) - <class 'sqlite3.Row'> - >>> tuple(r) - ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14) - >>> len(r) - 5 - >>> r[2] - 'RHAT' - >>> r.keys() - ['date', 'trans', 'symbol', 'qty', 'price'] - >>> r['qty'] - 100.0 - >>> for member in r: - ... print(member) - ... - 2006-01-05 - BUY - RHAT - 100.0 - 35.14 + >>> con = sqlite3.connect(":memory:") + >>> con.row_factory = sqlite3.Row + >>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius") + >>> row = res.fetchone() + >>> row.keys() + ['name', 'radius'] + >>> row[0], row["name"] # Access by index and name. + ('Earth', 'Earth') + >>> row["RADIUS"] # Column names are case-insensitive. + 6378 PrepareProtocol objects @@ -1429,20 +1405,6 @@ directly using only a single call on the :class:`Connection` object. .. literalinclude:: ../includes/sqlite3/shortcut_methods.py -.. _sqlite3-columns-by-name: - -Accessing columns by name instead of by index -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -One useful feature of the :mod:`!sqlite3` module is the built-in -:class:`sqlite3.Row` class designed to be used as a row factory. - -Rows wrapped with this class can be accessed both by index (like tuples) and -case-insensitively by name: - -.. literalinclude:: ../includes/sqlite3/rowclass.py - - .. _sqlite3-connection-context-manager: Using the connection as a context manager From webhook-mailer at python.org Mon Aug 22 04:12:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 08:12:08 -0000 Subject: [Python-checkins] gh-96121: Merge sqlite3.Row examples into sqlite3.Row class doc (GH-96122) Message-ID: <mailman.766.1661155928.3313.python-checkins@python.org> https://github.com/python/cpython/commit/98622fa00e0f9d6c20ddb1ff62534e5aa2f16e25 commit: 98622fa00e0f9d6c20ddb1ff62534e5aa2f16e25 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T01:12:02-07:00 summary: gh-96121: Merge sqlite3.Row examples into sqlite3.Row class doc (GH-96122) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> (cherry picked from commit 18b1782192f85bd26db89f5bc850f8bee4247c1a) Co-authored-by: Erlend E. Aasland <erlend.aasland at innova.no> files: D Doc/includes/sqlite3/rowclass.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py deleted file mode 100644 index fc60287069a8..000000000000 --- a/Doc/includes/sqlite3/rowclass.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.row_factory = sqlite3.Row - -cur = con.cursor() -cur.execute("select 'John' as name, 42 as age") -for row in cur: - assert row[0] == row["name"] - assert row["name"] == row["nAmE"] - assert row[1] == row["age"] - assert row[1] == row["AgE"] - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 20ad760ac4b4..9805a42d2f59 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -207,7 +207,6 @@ inserted data and retrieved values from it in multiple ways. * :ref:`sqlite3-placeholders` * :ref:`sqlite3-adapters` * :ref:`sqlite3-converters` - * :ref:`sqlite3-columns-by-name` * :ref:`sqlite3-connection-context-manager` * :ref:`sqlite3-explanation` for in-depth background on transaction control. @@ -1242,6 +1241,11 @@ Cursor objects >>> cur.connection == con True +.. The sqlite3.Row example used to be a how-to. It has now been incorporated + into the Row reference. We keep the anchor here in order not to break + existing links. + +.. _sqlite3-columns-by-name: .. _sqlite3-row-objects: Row objects @@ -1249,10 +1253,9 @@ Row objects .. class:: Row - A :class:`Row` instance serves as a highly optimized + A :class:`!Row` instance serves as a highly optimized :attr:`~Connection.row_factory` for :class:`Connection` objects. - It tries to mimic a :class:`tuple` in most of its features, - and supports iteration, :func:`repr`, equality testing, :func:`len`, + It supports iteration, equality testing, :func:`len`, and :term:`mapping` access by column name and index. Two row objects compare equal if have equal columns and equal members. @@ -1266,45 +1269,18 @@ Row objects .. versionchanged:: 3.5 Added support of slicing. -Let's assume we initialize a table as in the example given above:: + Example:: - con = sqlite3.connect(":memory:") - cur = con.cursor() - cur.execute('''create table stocks - (date text, trans text, symbol text, - qty real, price real)''') - cur.execute("""insert into stocks - values ('2006-01-05','BUY','RHAT',100,35.14)""") - con.commit() - cur.close() - -Now we plug :class:`Row` in:: - - >>> con.row_factory = sqlite3.Row - >>> cur = con.cursor() - >>> cur.execute('select * from stocks') - <sqlite3.Cursor object at 0x7f4e7dd8fa80> - >>> r = cur.fetchone() - >>> type(r) - <class 'sqlite3.Row'> - >>> tuple(r) - ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14) - >>> len(r) - 5 - >>> r[2] - 'RHAT' - >>> r.keys() - ['date', 'trans', 'symbol', 'qty', 'price'] - >>> r['qty'] - 100.0 - >>> for member in r: - ... print(member) - ... - 2006-01-05 - BUY - RHAT - 100.0 - 35.14 + >>> con = sqlite3.connect(":memory:") + >>> con.row_factory = sqlite3.Row + >>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius") + >>> row = res.fetchone() + >>> row.keys() + ['name', 'radius'] + >>> row[0], row["name"] # Access by index and name. + ('Earth', 'Earth') + >>> row["RADIUS"] # Column names are case-insensitive. + 6378 .. _sqlite3-blob-objects: @@ -1726,20 +1702,6 @@ directly using only a single call on the :class:`Connection` object. .. literalinclude:: ../includes/sqlite3/shortcut_methods.py -.. _sqlite3-columns-by-name: - -Accessing columns by name instead of by index -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -One useful feature of the :mod:`!sqlite3` module is the built-in -:class:`sqlite3.Row` class designed to be used as a row factory. - -Rows wrapped with this class can be accessed both by index (like tuples) and -case-insensitively by name: - -.. literalinclude:: ../includes/sqlite3/rowclass.py - - .. _sqlite3-connection-context-manager: Using the connection as a context manager From webhook-mailer at python.org Mon Aug 22 05:13:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 09:13:21 -0000 Subject: [Python-checkins] gh-96046: Initialize ht_cached_keys in PyType_Ready() (GH-96047) Message-ID: <mailman.767.1661159601.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3ea0beb3599f734bb9387a526dccd5768ad6b1a9 commit: 3ea0beb3599f734bb9387a526dccd5768ad6b1a9 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T02:12:42-07:00 summary: gh-96046: Initialize ht_cached_keys in PyType_Ready() (GH-96047) (cherry picked from commit 53e6a9a7254bdcd0538580ba7d799cd453e2dca5) Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst M Objects/typeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst new file mode 100644 index 000000000000..b8cb52d4b4ec --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst @@ -0,0 +1,4 @@ +:c:func:`PyType_Ready` now initializes ``ht_cached_keys`` and performs +additional checks to ensure that type objects are properly configured. This +avoids crashes in 3rd party packages that don't use regular API to create +new types. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 03cc72e742b2..9ee57105204e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3202,11 +3202,6 @@ type_new_impl(type_new_ctx *ctx) // Put the proper slots in place fixup_slot_dispatchers(type); - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyHeapTypeObject *et = (PyHeapTypeObject*)type; - et->ht_cached_keys = _PyDict_NewKeysForClass(); - } - if (type_new_set_names(type) < 0) { goto error; } @@ -3588,10 +3583,6 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) if (PyType_Ready(type) < 0) goto fail; - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - res->ht_cached_keys = _PyDict_NewKeysForClass(); - } - if (type->tp_doc) { PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); if (!__doc__) @@ -6409,6 +6400,29 @@ type_ready_set_new(PyTypeObject *type) return 0; } +static int +type_ready_managed_dict(PyTypeObject *type) +{ + if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + return 0; + } + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but not Py_TPFLAGS_HEAPTYPE flag", + type->tp_name); + return -1; + } + PyHeapTypeObject* et = (PyHeapTypeObject*)type; + if (et->ht_cached_keys == NULL) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + if (et->ht_cached_keys == NULL) { + PyErr_NoMemory(); + return -1; + } + } + return 0; +} static int type_ready_post_checks(PyTypeObject *type) @@ -6469,6 +6483,9 @@ type_ready(PyTypeObject *type) if (type_ready_add_subclasses(type) < 0) { return -1; } + if (type_ready_managed_dict(type) < 0) { + return -1; + } if (type_ready_post_checks(type) < 0) { return -1; } From webhook-mailer at python.org Mon Aug 22 12:23:43 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 22 Aug 2022 16:23:43 -0000 Subject: [Python-checkins] gh-96076: Change test_launcher to use non-admin location for py.ini (GH-96091) Message-ID: <mailman.768.1661185424.3313.python-checkins@python.org> https://github.com/python/cpython/commit/216ccacda193733ef92146c8ac1eb81893b4478d commit: 216ccacda193733ef92146c8ac1eb81893b4478d branch: main author: Terry Jan Reedy <tjreedy at udel.edu> committer: zooba <steve.dower at microsoft.com> date: 2022-08-22T17:23:27+01:00 summary: gh-96076: Change test_launcher to use non-admin location for py.ini (GH-96091) Patch authored by Eryksun. files: M Lib/test/test_launcher.py diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index 835a51e3b6e..9e265901b18 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -238,9 +238,11 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non return data def py_ini(self, content): - if not self.py_exe: - self.py_exe = self.find_py() - return PreservePyIni(self.py_exe.with_name("py.ini"), content) + local_appdata = os.environ.get("LOCALAPPDATA") + if not local_appdata: + raise unittest.SkipTest("LOCALAPPDATA environment variable is " + "missing or empty") + return PreservePyIni(Path(local_appdata) / "py.ini", content) @contextlib.contextmanager def script(self, content, encoding="utf-8"): From webhook-mailer at python.org Mon Aug 22 12:49:39 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 16:49:39 -0000 Subject: [Python-checkins] gh-96076: Change test_launcher to use non-admin location for py.ini (GH-96091) Message-ID: <mailman.769.1661186979.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4f7f83b5bdd61f01a5ad49fb4df61cab3607ab99 commit: 4f7f83b5bdd61f01a5ad49fb4df61cab3607ab99 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T09:49:34-07:00 summary: gh-96076: Change test_launcher to use non-admin location for py.ini (GH-96091) Patch authored by Eryksun. (cherry picked from commit 216ccacda193733ef92146c8ac1eb81893b4478d) Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu> files: M Lib/test/test_launcher.py diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index 4ff84773727..8ef1f5df8b4 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -239,9 +239,11 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non return data def py_ini(self, content): - if not self.py_exe: - self.py_exe = self.find_py() - return PreservePyIni(self.py_exe.with_name("py.ini"), content) + local_appdata = os.environ.get("LOCALAPPDATA") + if not local_appdata: + raise unittest.SkipTest("LOCALAPPDATA environment variable is " + "missing or empty") + return PreservePyIni(Path(local_appdata) / "py.ini", content) @contextlib.contextmanager def script(self, content, encoding="utf-8"): From webhook-mailer at python.org Mon Aug 22 14:40:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 18:40:38 -0000 Subject: [Python-checkins] GH-96071: add regression test for #96071 (GH-96137) Message-ID: <mailman.770.1661193638.3313.python-checkins@python.org> https://github.com/python/cpython/commit/079baee1962ff7c1f4b60f4dd4c803535ecbd18e commit: 079baee1962ff7c1f4b60f4dd4c803535ecbd18e branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T11:40:23-07:00 summary: GH-96071: add regression test for #96071 (GH-96137) Automerge-Triggered-By: GH:ericsnowcurrently files: M Lib/test/test_capi.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index b698e34dec4..d0c4811cad1 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -1053,6 +1053,21 @@ def callback(): t.start() t.join() + @threading_helper.reap_threads + @threading_helper.requires_working_threading() + def test_gilstate_ensure_no_deadlock(self): + # See https://github.com/python/cpython/issues/96071 + code = textwrap.dedent(f""" + import _testcapi + + def callback(): + print('callback called') + + _testcapi._test_thread_state(callback) + """) + ret = assert_python_ok('-X', 'tracemalloc', '-c', code) + self.assertIn(b'callback called', ret.out) + class Test_testcapi(unittest.TestCase): locals().update((name, getattr(_testcapi, name)) From webhook-mailer at python.org Mon Aug 22 15:05:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 22 Aug 2022 19:05:34 -0000 Subject: [Python-checkins] GH-96075: move interned dict under runtime state (GH-96077) Message-ID: <mailman.771.1661195136.3313.python-checkins@python.org> https://github.com/python/cpython/commit/129998bd7b133defa37c7529bfad9052c0022b5c commit: 129998bd7b133defa37c7529bfad9052c0022b5c branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T12:05:21-07:00 summary: GH-96075: move interned dict under runtime state (GH-96077) files: M Include/internal/pycore_global_objects.h M Objects/unicodeobject.c diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h index 98673d4efce..82e89db7b1b 100644 --- a/Include/internal/pycore_global_objects.h +++ b/Include/internal/pycore_global_objects.h @@ -45,6 +45,8 @@ struct _Py_global_objects { _PyGC_Head_UNUSED _tuple_empty_gc_not_used; PyTupleObject tuple_empty; } singletons; + + PyObject *interned; }; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index b1d14a32f70..13f2c5b49bd 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -191,16 +191,6 @@ extern "C" { # define OVERALLOCATE_FACTOR 4 #endif -/* This dictionary holds all interned unicode strings. Note that references - to strings in this dictionary are *not* counted in the string's ob_refcnt. - When the interned string reaches a refcnt of 0 the string deallocation - function will delete the reference from this dictionary. - - Another way to look at this is that to say that the actual reference - count of a string is: s->ob_refcnt + (s->state ? 2 : 0) -*/ -static PyObject *interned = NULL; - /* Forward declaration */ static inline int _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); @@ -235,6 +225,23 @@ static inline PyObject* unicode_new_empty(void) return empty; } +/* This dictionary holds all interned unicode strings. Note that references + to strings in this dictionary are *not* counted in the string's ob_refcnt. + When the interned string reaches a refcnt of 0 the string deallocation + function will delete the reference from this dictionary. + Another way to look at this is that to say that the actual reference + count of a string is: s->ob_refcnt + (s->state ? 2 : 0) +*/ +static inline PyObject *get_interned_dict(void) +{ + return _PyRuntime.global_objects.interned; +} + +static inline void set_interned_dict(PyObject *dict) +{ + _PyRuntime.global_objects.interned = dict; +} + #define _Py_RETURN_UNICODE_EMPTY() \ do { \ return unicode_new_empty(); \ @@ -1523,7 +1530,7 @@ unicode_dealloc(PyObject *unicode) _Py_FatalRefcountError("deallocating an Unicode singleton"); } #endif - + PyObject *interned = get_interned_dict(); if (PyUnicode_CHECK_INTERNED(unicode)) { /* Revive the dead object temporarily. PyDict_DelItem() removes two references (key and value) which were ignored by @@ -14657,12 +14664,14 @@ PyUnicode_InternInPlace(PyObject **p) return; } + PyObject *interned = get_interned_dict(); if (interned == NULL) { interned = PyDict_New(); if (interned == NULL) { PyErr_Clear(); /* Don't leave an exception */ return; } + set_interned_dict(interned); } PyObject *t = PyDict_SetDefault(interned, s, s); @@ -14713,6 +14722,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) return; } + PyObject *interned = get_interned_dict(); if (interned == NULL) { return; } @@ -14748,7 +14758,8 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) #endif PyDict_Clear(interned); - Py_CLEAR(interned); + Py_DECREF(interned); + set_interned_dict(NULL); } @@ -15155,7 +15166,7 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void) static inline int unicode_is_finalizing(void) { - return (interned == NULL); + return (get_interned_dict() == NULL); } #endif @@ -15197,7 +15208,7 @@ _PyUnicode_Fini(PyInterpreterState *interp) if (_Py_IsMainInterpreter(interp)) { // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() - assert(interned == NULL); + assert(get_interned_dict() == NULL); // bpo-47182: force a unicodedata CAPI capsule re-import on // subsequent initialization of main interpreter. ucnhash_capi = NULL; From webhook-mailer at python.org Tue Aug 23 02:29:04 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 23 Aug 2022 06:29:04 -0000 Subject: [Python-checkins] =?utf-8?q?gh-96159=3A_Fix_significant_performa?= =?utf-8?q?nce_degradation_in_logging=2ETimedRotat=E2=80=A6_=28GH-96182=29?= Message-ID: <mailman.772.1661236145.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1499d73b3e02878850c007fa7298bb62f6c5a9a1 commit: 1499d73b3e02878850c007fa7298bb62f6c5a9a1 branch: main author: Duncan Grisby <duncan-github at grisby.org> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-23T07:28:43+01:00 summary: gh-96159: Fix significant performance degradation in logging.TimedRotat? (GH-96182) files: A Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst M Lib/logging/handlers.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 1c8226c18163..3f97862cc37a 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -348,11 +348,15 @@ def shouldRollover(self, record): record is not used, as we are just comparing times, but it is needed so the method signatures are the same """ - # See bpo-45401: Never rollover anything other than regular files - if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): - return False t = int(time.time()) if t >= self.rolloverAt: + # See #89564: Never rollover anything other than regular files + if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): + # The file is not a regular file, so do not rollover, but do + # set the next rollover time to avoid repeated checks. + self.rolloverAt = self.computeRollover(t) + return False + return True return False diff --git a/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst b/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst new file mode 100644 index 000000000000..f64469e563f3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst @@ -0,0 +1 @@ +Fix a performance regression in logging TimedRotatingFileHandler. Only check for special files when the rollover time has passed. From webhook-mailer at python.org Tue Aug 23 02:48:26 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 23 Aug 2022 06:48:26 -0000 Subject: [Python-checkins] gh-95432: Add doctest for sqlite3 tutorial (#96193) Message-ID: <mailman.773.1661237307.3313.python-checkins@python.org> https://github.com/python/cpython/commit/04c73e5efbfea8ae9da5bd518cee96086017ef4f commit: 04c73e5efbfea8ae9da5bd518cee96086017ef4f branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-23T08:48:13+02:00 summary: gh-95432: Add doctest for sqlite3 tutorial (#96193) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 0d1185dd4658..de769f35dd3f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -8,6 +8,15 @@ **Source code:** :source:`Lib/sqlite3/` +.. Make sure we always doctest the tutorial with an empty database. + +.. testsetup:: + + import sqlite3 + src = sqlite3.connect(":memory:", isolation_level=None) + dst = sqlite3.connect("tutorial.db", isolation_level=None) + src.backup(dst) + del src, dst .. _sqlite3-intro: @@ -65,7 +74,9 @@ First, we need to create a new database and open a database connection to allow :mod:`!sqlite3` to work with it. Call :func:`sqlite3.connect` to to create a connection to the database :file:`tutorial.db` in the current working directory, -implicitly creating it if it does not exist:: +implicitly creating it if it does not exist: + +.. testcode:: import sqlite3 con = sqlite3.connect("tutorial.db") @@ -75,7 +86,9 @@ represents the connection to the on-disk database. In order to execute SQL statements and fetch results from SQL queries, we will need to use a database cursor. -Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:: +Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`: + +.. testcode:: cur = con.cursor() @@ -86,7 +99,9 @@ For simplicity, we can just use column names in the table declaration -- thanks to the `flexible typing`_ feature of SQLite, specifying the data types is optional. Execute the ``CREATE TABLE`` statement -by calling :meth:`cur.execute(...) <Cursor.execute>`:: +by calling :meth:`cur.execute(...) <Cursor.execute>`: + +.. testcode:: cur.execute("CREATE TABLE movie(title, year, score)") @@ -99,7 +114,9 @@ which should now contain an entry for the ``movie`` table definition (see `The Schema Table`_ for details). Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`, assign the result to ``res``, -and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: +and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row: + +.. doctest:: >>> res = cur.execute("SELECT name FROM sqlite_master") >>> res.fetchone() @@ -108,7 +125,9 @@ and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: We can see that the table has been created, as the query returns a :class:`tuple` containing the table's name. If we query ``sqlite_master`` for a non-existent table ``spam``, -:meth:`!res.fetchone()` will return ``None``:: +:meth:`!res.fetchone()` will return ``None``: + +.. doctest:: >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") >>> res.fetchone() is None @@ -116,7 +135,9 @@ If we query ``sqlite_master`` for a non-existent table ``spam``, Now, add two rows of data supplied as SQL literals by executing an ``INSERT`` statement, -once again by calling :meth:`cur.execute(...) <Cursor.execute>`:: +once again by calling :meth:`cur.execute(...) <Cursor.execute>`: + +.. testcode:: cur.execute(""" INSERT INTO movie VALUES @@ -128,7 +149,9 @@ The ``INSERT`` statement implicitly opens a transaction, which needs to be committed before changes are saved in the database (see :ref:`sqlite3-controlling-transactions` for details). Call :meth:`con.commit() <Connection.commit>` on the connection object -to commit the transaction:: +to commit the transaction: + +.. testcode:: con.commit() @@ -136,7 +159,9 @@ We can verify that the data was inserted correctly by executing a ``SELECT`` query. Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to assign the result to ``res``, -and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:: +and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows: + +.. doctest:: >>> res = cur.execute("SELECT score FROM movie") >>> res.fetchall() @@ -146,7 +171,9 @@ The result is a :class:`list` of two :class:`!tuple`\s, one per row, each containing that row's ``score`` value. Now, insert three more rows by calling -:meth:`cur.executemany(...) <Cursor.executemany>`:: +:meth:`cur.executemany(...) <Cursor.executemany>`: + +.. testcode:: data = [ ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), @@ -164,14 +191,16 @@ to avoid `SQL injection attacks`_ We can verify that the new rows were inserted by executing a ``SELECT`` query, -this time iterating over the results of the query:: +this time iterating over the results of the query: + +.. doctest:: >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): ... print(row) - (1971, "And Now for Something Completely Different") - (1975, "Monty Python and the Holy Grail") + (1971, 'And Now for Something Completely Different') + (1975, 'Monty Python and the Holy Grail') (1979, "Monty Python's Life of Brian") - (1982, "Monty Python Live at the Hollywood Bowl") + (1982, 'Monty Python Live at the Hollywood Bowl') (1983, "Monty Python's The Meaning of Life") Each row is a two-item :class:`tuple` of ``(year, title)``, @@ -180,15 +209,17 @@ matching the columns selected in the query. Finally, verify that the database has been written to disk by calling :meth:`con.close() <Connection.close>` to close the existing connection, opening a new one, -creating a new cursor, then querying the database:: +creating a new cursor, then querying the database: + +.. doctest:: >>> con.close() >>> new_con = sqlite3.connect("tutorial.db") >>> new_cur = new_con.cursor() - >>> res = new_cur.execute("SELECT year, title FROM movie ORDER BY score DESC"): + >>> res = new_cur.execute("SELECT title, year FROM movie ORDER BY score DESC") >>> title, year = res.fetchone() >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') - 'The highest scoring Monty Python movie is "Monty Python and the Holy Grail", released in 1975' + The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975 You've now created an SQLite database using the :mod:`!sqlite3` module, inserted data and retrieved values from it in multiple ways. From webhook-mailer at python.org Tue Aug 23 02:51:29 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 23 Aug 2022 06:51:29 -0000 Subject: [Python-checkins] gh-96096: Add undocumented SQLITE_OK/DENY/IGNORE sqlite3 constants (#96134) Message-ID: <mailman.774.1661237490.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d6259c58cbb48b8f3fbd70047f004ea19fe91e86 commit: d6259c58cbb48b8f3fbd70047f004ea19fe91e86 branch: main author: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-23T08:51:20+02:00 summary: gh-96096: Add undocumented SQLITE_OK/DENY/IGNORE sqlite3 constants (#96134) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index de769f35dd3..798c2d795b1 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -447,6 +447,17 @@ Module constants This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` (bitwise or) operator. +.. data:: SQLITE_OK + SQLITE_DENY + SQLITE_IGNORE + + Flags that should be returned by the *authorizer_callback* callable + passed to :meth:`Connection.set_authorizer`, to indicate whether: + + * Access is allowed (:const:`!SQLITE_OK`), + * The SQL statement should be aborted with an error (:const:`!SQLITE_DENY`) + * The column should be treated as a ``NULL`` value (:const:`!SQLITE_IGNORE`) + .. data:: apilevel String constant stating the supported DB-API level. Required by the DB-API. @@ -822,10 +833,9 @@ Connection objects Register callable *authorizer_callback* to be invoked for each attempt to access a column of a table in the database. The callback should return - :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL - statement should be aborted with an error and :const:`SQLITE_IGNORE` if the - column should be treated as a NULL value. These constants are available in the - :mod:`!sqlite3` module. + one of :const:`SQLITE_OK`, :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE` + to signal how access to the column should be handled + by the underlying SQLite library. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or ``None`` From webhook-mailer at python.org Tue Aug 23 02:55:44 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 06:55:44 -0000 Subject: [Python-checkins] gh-95432: Add doctest for sqlite3 tutorial (GH-96193) Message-ID: <mailman.775.1661237746.3313.python-checkins@python.org> https://github.com/python/cpython/commit/88a559ffea69b971dd09ac84e0849693dae08183 commit: 88a559ffea69b971dd09ac84e0849693dae08183 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T23:55:35-07:00 summary: gh-95432: Add doctest for sqlite3 tutorial (GH-96193) (cherry picked from commit 04c73e5efbfea8ae9da5bd518cee96086017ef4f) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 9805a42d2f59..013f417c2b3c 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -8,6 +8,15 @@ **Source code:** :source:`Lib/sqlite3/` +.. Make sure we always doctest the tutorial with an empty database. + +.. testsetup:: + + import sqlite3 + src = sqlite3.connect(":memory:", isolation_level=None) + dst = sqlite3.connect("tutorial.db", isolation_level=None) + src.backup(dst) + del src, dst .. _sqlite3-intro: @@ -65,7 +74,9 @@ First, we need to create a new database and open a database connection to allow :mod:`!sqlite3` to work with it. Call :func:`sqlite3.connect` to to create a connection to the database :file:`tutorial.db` in the current working directory, -implicitly creating it if it does not exist:: +implicitly creating it if it does not exist: + +.. testcode:: import sqlite3 con = sqlite3.connect("tutorial.db") @@ -75,7 +86,9 @@ represents the connection to the on-disk database. In order to execute SQL statements and fetch results from SQL queries, we will need to use a database cursor. -Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:: +Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`: + +.. testcode:: cur = con.cursor() @@ -86,7 +99,9 @@ For simplicity, we can just use column names in the table declaration -- thanks to the `flexible typing`_ feature of SQLite, specifying the data types is optional. Execute the ``CREATE TABLE`` statement -by calling :meth:`cur.execute(...) <Cursor.execute>`:: +by calling :meth:`cur.execute(...) <Cursor.execute>`: + +.. testcode:: cur.execute("CREATE TABLE movie(title, year, score)") @@ -99,7 +114,9 @@ which should now contain an entry for the ``movie`` table definition (see `The Schema Table`_ for details). Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`, assign the result to ``res``, -and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: +and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row: + +.. doctest:: >>> res = cur.execute("SELECT name FROM sqlite_master") >>> res.fetchone() @@ -108,7 +125,9 @@ and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: We can see that the table has been created, as the query returns a :class:`tuple` containing the table's name. If we query ``sqlite_master`` for a non-existent table ``spam``, -:meth:`!res.fetchone()` will return ``None``:: +:meth:`!res.fetchone()` will return ``None``: + +.. doctest:: >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") >>> res.fetchone() is None @@ -116,7 +135,9 @@ If we query ``sqlite_master`` for a non-existent table ``spam``, Now, add two rows of data supplied as SQL literals by executing an ``INSERT`` statement, -once again by calling :meth:`cur.execute(...) <Cursor.execute>`:: +once again by calling :meth:`cur.execute(...) <Cursor.execute>`: + +.. testcode:: cur.execute(""" INSERT INTO movie VALUES @@ -128,7 +149,9 @@ The ``INSERT`` statement implicitly opens a transaction, which needs to be committed before changes are saved in the database (see :ref:`sqlite3-controlling-transactions` for details). Call :meth:`con.commit() <Connection.commit>` on the connection object -to commit the transaction:: +to commit the transaction: + +.. testcode:: con.commit() @@ -136,7 +159,9 @@ We can verify that the data was inserted correctly by executing a ``SELECT`` query. Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to assign the result to ``res``, -and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:: +and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows: + +.. doctest:: >>> res = cur.execute("SELECT score FROM movie") >>> res.fetchall() @@ -146,7 +171,9 @@ The result is a :class:`list` of two :class:`!tuple`\s, one per row, each containing that row's ``score`` value. Now, insert three more rows by calling -:meth:`cur.executemany(...) <Cursor.executemany>`:: +:meth:`cur.executemany(...) <Cursor.executemany>`: + +.. testcode:: data = [ ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), @@ -164,14 +191,16 @@ to avoid `SQL injection attacks`_ We can verify that the new rows were inserted by executing a ``SELECT`` query, -this time iterating over the results of the query:: +this time iterating over the results of the query: + +.. doctest:: >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): ... print(row) - (1971, "And Now for Something Completely Different") - (1975, "Monty Python and the Holy Grail") + (1971, 'And Now for Something Completely Different') + (1975, 'Monty Python and the Holy Grail') (1979, "Monty Python's Life of Brian") - (1982, "Monty Python Live at the Hollywood Bowl") + (1982, 'Monty Python Live at the Hollywood Bowl') (1983, "Monty Python's The Meaning of Life") Each row is a two-item :class:`tuple` of ``(year, title)``, @@ -180,15 +209,17 @@ matching the columns selected in the query. Finally, verify that the database has been written to disk by calling :meth:`con.close() <Connection.close>` to close the existing connection, opening a new one, -creating a new cursor, then querying the database:: +creating a new cursor, then querying the database: + +.. doctest:: >>> con.close() >>> new_con = sqlite3.connect("tutorial.db") >>> new_cur = new_con.cursor() - >>> res = new_cur.execute("SELECT year, title FROM movie ORDER BY score DESC"): + >>> res = new_cur.execute("SELECT title, year FROM movie ORDER BY score DESC") >>> title, year = res.fetchone() >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') - 'The highest scoring Monty Python movie is "Monty Python and the Holy Grail", released in 1975' + The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975 You've now created an SQLite database using the :mod:`!sqlite3` module, inserted data and retrieved values from it in multiple ways. From webhook-mailer at python.org Tue Aug 23 02:56:44 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 06:56:44 -0000 Subject: [Python-checkins] gh-95432: Add doctest for sqlite3 tutorial (GH-96193) Message-ID: <mailman.776.1661237805.3313.python-checkins@python.org> https://github.com/python/cpython/commit/145d8f0e57c8e1c819e76f2e6644013e3305e030 commit: 145d8f0e57c8e1c819e76f2e6644013e3305e030 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T23:56:39-07:00 summary: gh-95432: Add doctest for sqlite3 tutorial (GH-96193) (cherry picked from commit 04c73e5efbfea8ae9da5bd518cee96086017ef4f) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 1f7ebbe109ff..ce009bef2397 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -8,6 +8,15 @@ **Source code:** :source:`Lib/sqlite3/` +.. Make sure we always doctest the tutorial with an empty database. + +.. testsetup:: + + import sqlite3 + src = sqlite3.connect(":memory:", isolation_level=None) + dst = sqlite3.connect("tutorial.db", isolation_level=None) + src.backup(dst) + del src, dst .. _sqlite3-intro: @@ -65,7 +74,9 @@ First, we need to create a new database and open a database connection to allow :mod:`!sqlite3` to work with it. Call :func:`sqlite3.connect` to to create a connection to the database :file:`tutorial.db` in the current working directory, -implicitly creating it if it does not exist:: +implicitly creating it if it does not exist: + +.. testcode:: import sqlite3 con = sqlite3.connect("tutorial.db") @@ -75,7 +86,9 @@ represents the connection to the on-disk database. In order to execute SQL statements and fetch results from SQL queries, we will need to use a database cursor. -Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`:: +Call :meth:`con.cursor() <Connection.cursor>` to create the :class:`Cursor`: + +.. testcode:: cur = con.cursor() @@ -86,7 +99,9 @@ For simplicity, we can just use column names in the table declaration -- thanks to the `flexible typing`_ feature of SQLite, specifying the data types is optional. Execute the ``CREATE TABLE`` statement -by calling :meth:`cur.execute(...) <Cursor.execute>`:: +by calling :meth:`cur.execute(...) <Cursor.execute>`: + +.. testcode:: cur.execute("CREATE TABLE movie(title, year, score)") @@ -99,7 +114,9 @@ which should now contain an entry for the ``movie`` table definition (see `The Schema Table`_ for details). Execute that query by calling :meth:`cur.execute(...) <Cursor.execute>`, assign the result to ``res``, -and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: +and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row: + +.. doctest:: >>> res = cur.execute("SELECT name FROM sqlite_master") >>> res.fetchone() @@ -108,7 +125,9 @@ and call :meth:`res.fetchone() <Cursor.fetchone>` to fetch the resulting row:: We can see that the table has been created, as the query returns a :class:`tuple` containing the table's name. If we query ``sqlite_master`` for a non-existent table ``spam``, -:meth:`!res.fetchone()` will return ``None``:: +:meth:`!res.fetchone()` will return ``None``: + +.. doctest:: >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") >>> res.fetchone() is None @@ -116,7 +135,9 @@ If we query ``sqlite_master`` for a non-existent table ``spam``, Now, add two rows of data supplied as SQL literals by executing an ``INSERT`` statement, -once again by calling :meth:`cur.execute(...) <Cursor.execute>`:: +once again by calling :meth:`cur.execute(...) <Cursor.execute>`: + +.. testcode:: cur.execute(""" INSERT INTO movie VALUES @@ -128,7 +149,9 @@ The ``INSERT`` statement implicitly opens a transaction, which needs to be committed before changes are saved in the database (see :ref:`sqlite3-controlling-transactions` for details). Call :meth:`con.commit() <Connection.commit>` on the connection object -to commit the transaction:: +to commit the transaction: + +.. testcode:: con.commit() @@ -136,7 +159,9 @@ We can verify that the data was inserted correctly by executing a ``SELECT`` query. Use the now-familiar :meth:`cur.execute(...) <Cursor.execute>` to assign the result to ``res``, -and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows:: +and call :meth:`res.fetchall() <Cursor.fetchall>` to return all resulting rows: + +.. doctest:: >>> res = cur.execute("SELECT score FROM movie") >>> res.fetchall() @@ -146,7 +171,9 @@ The result is a :class:`list` of two :class:`!tuple`\s, one per row, each containing that row's ``score`` value. Now, insert three more rows by calling -:meth:`cur.executemany(...) <Cursor.executemany>`:: +:meth:`cur.executemany(...) <Cursor.executemany>`: + +.. testcode:: data = [ ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), @@ -164,14 +191,16 @@ to avoid `SQL injection attacks`_ We can verify that the new rows were inserted by executing a ``SELECT`` query, -this time iterating over the results of the query:: +this time iterating over the results of the query: + +.. doctest:: >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): ... print(row) - (1971, "And Now for Something Completely Different") - (1975, "Monty Python and the Holy Grail") + (1971, 'And Now for Something Completely Different') + (1975, 'Monty Python and the Holy Grail') (1979, "Monty Python's Life of Brian") - (1982, "Monty Python Live at the Hollywood Bowl") + (1982, 'Monty Python Live at the Hollywood Bowl') (1983, "Monty Python's The Meaning of Life") Each row is a two-item :class:`tuple` of ``(year, title)``, @@ -180,15 +209,17 @@ matching the columns selected in the query. Finally, verify that the database has been written to disk by calling :meth:`con.close() <Connection.close>` to close the existing connection, opening a new one, -creating a new cursor, then querying the database:: +creating a new cursor, then querying the database: + +.. doctest:: >>> con.close() >>> new_con = sqlite3.connect("tutorial.db") >>> new_cur = new_con.cursor() - >>> res = new_cur.execute("SELECT year, title FROM movie ORDER BY score DESC"): + >>> res = new_cur.execute("SELECT title, year FROM movie ORDER BY score DESC") >>> title, year = res.fetchone() >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') - 'The highest scoring Monty Python movie is "Monty Python and the Holy Grail", released in 1975' + The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975 You've now created an SQLite database using the :mod:`!sqlite3` module, inserted data and retrieved values from it in multiple ways. From webhook-mailer at python.org Tue Aug 23 02:58:22 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 06:58:22 -0000 Subject: [Python-checkins] gh-96096: Add undocumented SQLITE_OK/DENY/IGNORE sqlite3 constants (GH-96134) Message-ID: <mailman.777.1661237903.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e9ede9d2a0376961933c03245199a8f348a9880c commit: e9ede9d2a0376961933c03245199a8f348a9880c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T23:58:17-07:00 summary: gh-96096: Add undocumented SQLITE_OK/DENY/IGNORE sqlite3 constants (GH-96134) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit d6259c58cbb48b8f3fbd70047f004ea19fe91e86) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index ce009bef239..be9a22efad1 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -426,6 +426,17 @@ Module constants This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` (bitwise or) operator. +.. data:: SQLITE_OK + SQLITE_DENY + SQLITE_IGNORE + + Flags that should be returned by the *authorizer_callback* callable + passed to :meth:`Connection.set_authorizer`, to indicate whether: + + * Access is allowed (:const:`!SQLITE_OK`), + * The SQL statement should be aborted with an error (:const:`!SQLITE_DENY`) + * The column should be treated as a ``NULL`` value (:const:`!SQLITE_IGNORE`) + .. data:: apilevel String constant stating the supported DB-API level. Required by the DB-API. @@ -695,10 +706,9 @@ Connection objects Register callable *authorizer_callback* to be invoked for each attempt to access a column of a table in the database. The callback should return - :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL - statement should be aborted with an error and :const:`SQLITE_IGNORE` if the - column should be treated as a NULL value. These constants are available in the - :mod:`!sqlite3` module. + one of :const:`SQLITE_OK`, :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE` + to signal how access to the column should be handled + by the underlying SQLite library. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or ``None`` From webhook-mailer at python.org Tue Aug 23 02:58:40 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 06:58:40 -0000 Subject: [Python-checkins] gh-96096: Add undocumented SQLITE_OK/DENY/IGNORE sqlite3 constants (GH-96134) Message-ID: <mailman.778.1661237922.3313.python-checkins@python.org> https://github.com/python/cpython/commit/dc6391705ed4934626f4119837190b994d90a7e1 commit: dc6391705ed4934626f4119837190b994d90a7e1 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-22T23:58:35-07:00 summary: gh-96096: Add undocumented SQLITE_OK/DENY/IGNORE sqlite3 constants (GH-96134) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> (cherry picked from commit d6259c58cbb48b8f3fbd70047f004ea19fe91e86) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 013f417c2b3..cf496b7f6a6 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -444,6 +444,17 @@ Module constants This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` (bitwise or) operator. +.. data:: SQLITE_OK + SQLITE_DENY + SQLITE_IGNORE + + Flags that should be returned by the *authorizer_callback* callable + passed to :meth:`Connection.set_authorizer`, to indicate whether: + + * Access is allowed (:const:`!SQLITE_OK`), + * The SQL statement should be aborted with an error (:const:`!SQLITE_DENY`) + * The column should be treated as a ``NULL`` value (:const:`!SQLITE_IGNORE`) + .. data:: apilevel String constant stating the supported DB-API level. Required by the DB-API. @@ -809,10 +820,9 @@ Connection objects Register callable *authorizer_callback* to be invoked for each attempt to access a column of a table in the database. The callback should return - :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL - statement should be aborted with an error and :const:`SQLITE_IGNORE` if the - column should be treated as a NULL value. These constants are available in the - :mod:`!sqlite3` module. + one of :const:`SQLITE_OK`, :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE` + to signal how access to the column should be handled + by the underlying SQLite library. The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or ``None`` From webhook-mailer at python.org Tue Aug 23 03:00:50 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 23 Aug 2022 07:00:50 -0000 Subject: [Python-checkins] =?utf-8?q?=5B3=2E10=5D_gh-96159=3A_Fix_signifi?= =?utf-8?q?cant_performance_degradation_in_logging=2ETimedRotat=E2=80=A6_?= =?utf-8?b?KEdILTk2MTgyKSAoR0gtOTYxOTUp?= Message-ID: <mailman.779.1661238050.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9c34d644edec7e5d4da78317ad2bbceb246aa039 commit: 9c34d644edec7e5d4da78317ad2bbceb246aa039 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-23T08:00:40+01:00 summary: [3.10] gh-96159: Fix significant performance degradation in logging.TimedRotat? (GH-96182) (GH-96195) Co-authored-by: Duncan Grisby <duncan-github at grisby.org> files: A Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst M Lib/logging/handlers.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index b2d1f279225d..32c04202c5aa 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -348,11 +348,15 @@ def shouldRollover(self, record): record is not used, as we are just comparing times, but it is needed so the method signatures are the same """ - # See bpo-45401: Never rollover anything other than regular files - if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): - return False t = int(time.time()) if t >= self.rolloverAt: + # See #89564: Never rollover anything other than regular files + if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): + # The file is not a regular file, so do not rollover, but do + # set the next rollover time to avoid repeated checks. + self.rolloverAt = self.computeRollover(t) + return False + return True return False diff --git a/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst b/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst new file mode 100644 index 000000000000..f64469e563f3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst @@ -0,0 +1 @@ +Fix a performance regression in logging TimedRotatingFileHandler. Only check for special files when the rollover time has passed. From webhook-mailer at python.org Tue Aug 23 03:01:15 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 23 Aug 2022 07:01:15 -0000 Subject: [Python-checkins] =?utf-8?q?=5B3=2E11=5D_gh-96159=3A_Fix_signifi?= =?utf-8?q?cant_performance_degradation_in_logging=2ETimedRotat=E2=80=A6_?= =?utf-8?b?KEdILTk2MTgyKSAoR0gtOTYxOTYp?= Message-ID: <mailman.780.1661238076.3313.python-checkins@python.org> https://github.com/python/cpython/commit/04e37850981bceaa31759c2673a945d3713ae7ae commit: 04e37850981bceaa31759c2673a945d3713ae7ae branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-23T08:01:10+01:00 summary: [3.11] gh-96159: Fix significant performance degradation in logging.TimedRotat? (GH-96182) (GH-96196) Co-authored-by: Duncan Grisby <duncan-github at grisby.org> files: A Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst M Lib/logging/handlers.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 78b756019dc8..2bcab657ba4e 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -348,11 +348,15 @@ def shouldRollover(self, record): record is not used, as we are just comparing times, but it is needed so the method signatures are the same """ - # See bpo-45401: Never rollover anything other than regular files - if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): - return False t = int(time.time()) if t >= self.rolloverAt: + # See #89564: Never rollover anything other than regular files + if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): + # The file is not a regular file, so do not rollover, but do + # set the next rollover time to avoid repeated checks. + self.rolloverAt = self.computeRollover(t) + return False + return True return False diff --git a/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst b/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst new file mode 100644 index 000000000000..f64469e563f3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst @@ -0,0 +1 @@ +Fix a performance regression in logging TimedRotatingFileHandler. Only check for special files when the rollover time has passed. From webhook-mailer at python.org Tue Aug 23 04:59:20 2022 From: webhook-mailer at python.org (corona10) Date: Tue, 23 Aug 2022 08:59:20 -0000 Subject: [Python-checkins] gh-96197: Add `del sys.breakpointhook` behavior test (gh-96198) Message-ID: <mailman.781.1661245160.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ba7d4b9dc18777e1d3ad2bfc9d935e45e47ebe00 commit: ba7d4b9dc18777e1d3ad2bfc9d935e45e47ebe00 branch: main author: Jeong YunWon <69878+youknowone at users.noreply.github.com> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-23T17:58:38+09:00 summary: gh-96197: Add `del sys.breakpointhook` behavior test (gh-96198) files: M Lib/test/test_builtin.py diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 6fa5ea67c8b3..8c9c1e506752 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2072,6 +2072,11 @@ def test_envar_ignored_when_hook_is_set(self): breakpoint() mock.assert_not_called() + def test_runtime_error_when_hook_is_lost(self): + del sys.breakpointhook + with self.assertRaises(RuntimeError): + breakpoint() + @unittest.skipUnless(pty, "the pty and signal modules must be available") class PtyTests(unittest.TestCase): From webhook-mailer at python.org Tue Aug 23 06:14:02 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 23 Aug 2022 10:14:02 -0000 Subject: [Python-checkins] GH-96187: Prevent _PyCode_GetExtra to return garbage for negative indexes (GH-96188) Message-ID: <mailman.782.1661249643.3313.python-checkins@python.org> https://github.com/python/cpython/commit/16ebae4cd4029205d932751f26c719c6cb8a6e92 commit: 16ebae4cd4029205d932751f26c719c6cb8a6e92 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: markshannon <mark at hotpy.org> date: 2022-08-23T11:13:53+01:00 summary: GH-96187: Prevent _PyCode_GetExtra to return garbage for negative indexes (GH-96188) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst M Objects/codeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst new file mode 100644 index 000000000000..fd194faa6854 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst @@ -0,0 +1,2 @@ +Fixed a bug that caused ``_PyCode_GetExtra`` to return garbage for negative +indexes. Patch by Pablo Galindo diff --git a/Objects/codeobject.c b/Objects/codeobject.c index aeb6a8c0804e..72712f40e42c 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1339,7 +1339,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) PyCodeObject *o = (PyCodeObject*) code; _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra; - if (co_extra == NULL || co_extra->ce_size <= index) { + if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) { *extra = NULL; return 0; } From webhook-mailer at python.org Tue Aug 23 07:02:52 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 11:02:52 -0000 Subject: [Python-checkins] GH-96187: Prevent _PyCode_GetExtra to return garbage for negative indexes (GH-96188) Message-ID: <mailman.783.1661252574.3313.python-checkins@python.org> https://github.com/python/cpython/commit/27950d8f761b5c9b80d8ee53d2e6e619bab90180 commit: 27950d8f761b5c9b80d8ee53d2e6e619bab90180 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-23T04:02:19-07:00 summary: GH-96187: Prevent _PyCode_GetExtra to return garbage for negative indexes (GH-96188) (cherry picked from commit 16ebae4cd4029205d932751f26c719c6cb8a6e92) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst M Objects/codeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst new file mode 100644 index 000000000000..fd194faa6854 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst @@ -0,0 +1,2 @@ +Fixed a bug that caused ``_PyCode_GetExtra`` to return garbage for negative +indexes. Patch by Pablo Galindo diff --git a/Objects/codeobject.c b/Objects/codeobject.c index c0151434489a..d7434ddefbc0 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1337,7 +1337,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) PyCodeObject *o = (PyCodeObject*) code; _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra; - if (co_extra == NULL || co_extra->ce_size <= index) { + if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) { *extra = NULL; return 0; } From webhook-mailer at python.org Tue Aug 23 07:23:46 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 23 Aug 2022 11:23:46 -0000 Subject: [Python-checkins] [3.10] GH--93592: Fix frame chain when throwing exceptions into coroutines (GH-95207) Message-ID: <mailman.784.1661253828.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d23ab79952836e67216113d9195c9c0e879b3e83 commit: d23ab79952836e67216113d9195c9c0e879b3e83 branch: 3.10 author: Kristj?n Valur J?nsson <sweskman at gmail.com> committer: markshannon <mark at hotpy.org> date: 2022-08-23T12:23:39+01:00 summary: [3.10] GH--93592: Fix frame chain when throwing exceptions into coroutines (GH-95207) files: A Misc/NEWS.d/next/Core and Builtins/2022-07-24-19-23-23.gh-issue-93592.zdgp6o.rst M Lib/test/test_coroutines.py M Objects/genobject.c diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index a6a199e323c5..a414a6f505c9 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -4,6 +4,7 @@ import pickle import sys import types +import traceback import unittest import warnings from test import support @@ -2119,6 +2120,29 @@ async def run_gen(): return 'end' self.assertEqual(run_async(run_gen()), ([], 'end')) + def test_stack_in_coroutine_throw(self): + # Regression test for https://github.com/python/cpython/issues/93592 + async def a(): + return await b() + + async def b(): + return await c() + + @types.coroutine + def c(): + try: + # traceback.print_stack() + yield len(traceback.extract_stack()) + except ZeroDivisionError: + # traceback.print_stack() + yield len(traceback.extract_stack()) + + coro = a() + len_send = coro.send(None) + len_throw = coro.throw(ZeroDivisionError) + # before fixing, visible stack from throw would be shorter than from send. + self.assertEqual(len_send, len_throw) + class CoroAsyncIOCompatTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-24-19-23-23.gh-issue-93592.zdgp6o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-24-19-23-23.gh-issue-93592.zdgp6o.rst new file mode 100644 index 000000000000..89267ed37da3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-24-19-23-23.gh-issue-93592.zdgp6o.rst @@ -0,0 +1,2 @@ +``coroutine.throw()`` now properly initializes the ``frame.f_back`` when resuming a stack of coroutines. +This allows e.g. ``traceback.print_stack()`` to work correctly when an exception (such as ``CancelledError``) is thrown into a coroutine. diff --git a/Objects/genobject.c b/Objects/genobject.c index 123c17aae7e7..4f6fefdd8bfd 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -439,20 +439,25 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, /* `yf` is a generator or a coroutine. */ PyThreadState *tstate = _PyThreadState_GET(); PyFrameObject *f = tstate->frame; + PyFrameObject *gf = gen->gi_frame; /* Since we are fast-tracking things by skipping the eval loop, we need to update the current frame so the stack trace will be reported correctly to the user. */ /* XXX We should probably be updating the current frame somewhere in ceval.c. */ - tstate->frame = gen->gi_frame; + assert(gf->f_back == NULL); + Py_XINCREF(f); + gf->f_back = f; + tstate->frame = gf; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ - PyFrameState state = gen->gi_frame->f_state; - gen->gi_frame->f_state = FRAME_EXECUTING; + PyFrameState state = gf->f_state; + gf->f_state = FRAME_EXECUTING; ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); - gen->gi_frame->f_state = state; + gf->f_state = state; + Py_CLEAR(gf->f_back); tstate->frame = f; } else { /* `yf` is an iterator or a coroutine-like object. */ From webhook-mailer at python.org Tue Aug 23 08:55:52 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 23 Aug 2022 12:55:52 -0000 Subject: [Python-checkins] GH-96068: Document object layout (GH-96069) Message-ID: <mailman.785.1661259353.3313.python-checkins@python.org> https://github.com/python/cpython/commit/575f8880bf8498ee05a8e197fc2ed85db6880361 commit: 575f8880bf8498ee05a8e197fc2ed85db6880361 branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-23T13:55:43+01:00 summary: GH-96068: Document object layout (GH-96069) files: A Objects/object_layout.md A Objects/object_layout_312.gv A Objects/object_layout_312.png A Objects/object_layout_full_312.gv A Objects/object_layout_full_312.png diff --git a/Objects/object_layout.md b/Objects/object_layout.md new file mode 100644 index 00000000000..9380b57938c --- /dev/null +++ b/Objects/object_layout.md @@ -0,0 +1,82 @@ +# Object layout + +## Common header + +Each Python object starts with two fields: + +* ob_refcnt +* ob_type + +which the form the header common to all Python objects, for all versions, +and hold the reference count and class of the object, respectively. + +## Pre-header + +Since the introduction of the cycle GC, there has also been a pre-header. +Before 3.11, this pre-header was two words in size. +It should be considered opaque to all code except the cycle GC. + +## 3.11 pre-header + +In 3.11 the pre-header was extended to include pointers to the VM managed ``__dict__``. +The reason for moving the ``__dict__`` to the pre-header is that it allows +faster access, as it is at a fixed offset, and it also allows object's +dictionaries to be lazily created when the ``__dict__`` attribute is +specifically asked for. + +In the 3.11 the non-GC part of the pre-header consists of two pointers: + +* dict +* values + +The values pointer refers to the ``PyDictValues`` array which holds the +values of the objects's attributes. +Should the dictionary be needed, then ``values`` is set to ``NULL`` +and the ``dict`` field points to the dictionary. + +## 3.12 pre-header + +In 3.12 the the pointer to the list of weak references is added to the +pre-header. In order to make space for it, the ``dict`` and ``values`` +pointers are combined into a single tagged pointer: + +* weakreflist +* dict_or_values + +If the object has no physical dictionary, then the ``dict_or_values`` +has its low bit set to one, and points to the values array. +If the object has a physical dictioanry, then the ``dict_or_values`` +has its low bit set to zero, and points to the dictionary. + +The untagged form is chosen for the dictionary pointer, rather than +the values pointer, to enable the (legacy) C-API function +`_PyObject_GetDictPtr(PyObject *obj)` to work. + + +## Layout of a "normal" Python object in 3.12: + +* weakreflist +* dict_or_values +* GC 1 +* GC 2 +* ob_refcnt +* ob_type + +For a "normal" Python object, that is one that doesn't inherit from a builtin +class or have slots, the header and pre-header form the entire object. + +![Layout of "normal" object in 3.12](./object_layout_312.png) + +There are several advantages to this layout: + +* It allows lazy `__dict__`s, as described above. +* The regular layout allows us to create tailored traversal and deallocation + functions based on layout, rather than inheritance. +* Multiple inheritance works properly, + as the weakrefs and dict are always at the same offset. + +The full layout object, with an opaque part defined by a C extension, +and `__slots__` looks like this: + +![Layout of "full" object in 3.12](./object_layout_full_312.png) + diff --git a/Objects/object_layout_312.gv b/Objects/object_layout_312.gv new file mode 100644 index 00000000000..c0068d78568 --- /dev/null +++ b/Objects/object_layout_312.gv @@ -0,0 +1,50 @@ +digraph ideal { + + rankdir = "LR" + + + object [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>object</b></td></tr> + <tr><td port="w" border="1">weakrefs</td></tr> + <tr><td port="dv" border="1">dict or values</td></tr> + <tr><td border="1" >GC info 0</td></tr> + <tr><td border="1" >GC info 1</td></tr> + <tr><td port="r" border="1" >refcount</td></tr> + <tr><td port="h" border="1" >__class__</td></tr> + </table>> + ] + + values [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>values</b></td></tr> + <tr><td port="0" border="1">values[0]</td></tr> + <tr><td border="1">values[1]</td></tr> + <tr><td border="1">...</td></tr> + </table>> + + ] + + class [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>class</b></td></tr> + <tr><td port="head" bgcolor="lightgreen" border="1">...</td></tr> + <tr><td border="1" bgcolor="lightgreen">dict_offset</td></tr> + <tr><td border="1" bgcolor="lightgreen">...</td></tr> + <tr><td port="k" border="1" bgcolor="lightgreen">cached_keys</td></tr> + </table>> + ] + + keys [label = "dictionary keys"; fillcolor="lightgreen"; style="filled"] + NULL [ label = " NULL"; shape="plain"] + object:w -> NULL + object:h -> class:head + object:dv -> values:0 + class:k -> keys + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_312.png b/Objects/object_layout_312.png new file mode 100644 index 00000000000..396dab183b3 Binary files /dev/null and b/Objects/object_layout_312.png differ diff --git a/Objects/object_layout_full_312.gv b/Objects/object_layout_full_312.gv new file mode 100644 index 00000000000..522fa32b066 --- /dev/null +++ b/Objects/object_layout_full_312.gv @@ -0,0 +1,25 @@ +digraph ideal { + + rankdir = "LR" + + + object [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>object</b></td></tr> + <tr><td port="w" border="1">weakrefs</td></tr> + <tr><td port="dv" border="1">dict or values</td></tr> + <tr><td border="1" >GC info 0</td></tr> + <tr><td border="1" >GC info 1</td></tr> + <tr><td port="r" border="1" >refcount</td></tr> + <tr><td port="h" border="1" >__class__</td></tr> + <tr><td border="1">opaque (extension) data </td></tr> + <tr><td border="1">...</td></tr> + <tr><td border="1">__slot__ 0</td></tr> + <tr><td border="1">...</td></tr> + </table>> + ] + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_full_312.png b/Objects/object_layout_full_312.png new file mode 100644 index 00000000000..4f46ca86091 Binary files /dev/null and b/Objects/object_layout_full_312.png differ From webhook-mailer at python.org Tue Aug 23 10:58:34 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 23 Aug 2022 14:58:34 -0000 Subject: [Python-checkins] [3.10] GH-96187: Prevent _PyCode_GetExtra to return garbage for negative indexes (GH-96188). (#96210) Message-ID: <mailman.786.1661266715.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a6c3f6d34792c5f9dc296ce8329938b7b2b02ea9 commit: a6c3f6d34792c5f9dc296ce8329938b7b2b02ea9 branch: 3.10 author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-23T15:58:25+01:00 summary: [3.10] GH-96187: Prevent _PyCode_GetExtra to return garbage for negative indexes (GH-96188). (#96210) (cherry picked from commit 16ebae4cd4029205d932751f26c719c6cb8a6e92) Co-authored-by: Pablo Galindo Salgado <Pablogsal at gmail.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst M Objects/codeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst new file mode 100644 index 000000000000..fd194faa6854 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst @@ -0,0 +1,2 @@ +Fixed a bug that caused ``_PyCode_GetExtra`` to return garbage for negative +indexes. Patch by Pablo Galindo diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 976cec584e9f..390b76cafd51 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1304,7 +1304,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) PyCodeObject *o = (PyCodeObject*) code; _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra; - if (co_extra == NULL || co_extra->ce_size <= index) { + if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) { *extra = NULL; return 0; } From webhook-mailer at python.org Tue Aug 23 11:37:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 15:37:36 -0000 Subject: [Python-checkins] GH-96071: add regression test for GH-96071 (GH-96137) Message-ID: <mailman.787.1661269057.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0aed1e71f3bd6cf298b08cf82078b013a32362c2 commit: 0aed1e71f3bd6cf298b08cf82078b013a32362c2 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-23T08:37:19-07:00 summary: GH-96071: add regression test for GH-96071 (GH-96137) Automerge-Triggered-By: GH:ericsnowcurrently (cherry picked from commit 079baee1962ff7c1f4b60f4dd4c803535ecbd18e) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: M Lib/test/test_capi.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 40750cc49324..e157d9fdc850 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -915,6 +915,21 @@ def callback(): t.start() t.join() + @threading_helper.reap_threads + @threading_helper.requires_working_threading() + def test_gilstate_ensure_no_deadlock(self): + # See https://github.com/python/cpython/issues/96071 + code = textwrap.dedent(f""" + import _testcapi + + def callback(): + print('callback called') + + _testcapi._test_thread_state(callback) + """) + ret = assert_python_ok('-X', 'tracemalloc', '-c', code) + self.assertIn(b'callback called', ret.out) + class Test_testcapi(unittest.TestCase): locals().update((name, getattr(_testcapi, name)) From webhook-mailer at python.org Tue Aug 23 12:16:15 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 23 Aug 2022 16:16:15 -0000 Subject: [Python-checkins] gh-96175: add missing self._localName assignment in `xml.dom.minidom.Attr` (#96176) Message-ID: <mailman.788.1661271376.3313.python-checkins@python.org> https://github.com/python/cpython/commit/58f6953d6d3fe20d972bfa2f6e982206adcf1353 commit: 58f6953d6d3fe20d972bfa2f6e982206adcf1353 branch: main author: Kevin Kirsche <Kev.Kirsche+GitHub at gmail.com> committer: JelleZijlstra <jelle.zijlstra at gmail.com> date: 2022-08-23T09:16:02-07:00 summary: gh-96175: add missing self._localName assignment in `xml.dom.minidom.Attr` (#96176) X-Ref: https://github.com/python/typeshed/pull/8590#discussion_r951473977 Co-authored-by: Jelle Zijlstra <jelle.zijlstra at gmail.com> files: A Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst M Lib/test/test_minidom.py M Lib/xml/dom/minidom.py diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 97620258d82f..ef38c362103f 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -9,7 +9,7 @@ import pyexpat import xml.dom.minidom -from xml.dom.minidom import parse, Node, Document, parseString +from xml.dom.minidom import parse, Attr, Node, Document, parseString from xml.dom.minidom import getDOMImplementation from xml.parsers.expat import ExpatError @@ -77,6 +77,20 @@ def testParseFromTextFile(self): dom.unlink() self.confirm(isinstance(dom, Document)) + def testAttrModeSetsParamsAsAttrs(self): + attr = Attr("qName", "namespaceURI", "localName", "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, "localName") + + def testAttrModeSetsNonOptionalAttrs(self): + attr = Attr("qName", "namespaceURI", None, "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, attr.name) + def testGetElementsByTagName(self): dom = parse(tstfile) self.confirm(dom.getElementsByTagName("LI") == \ diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index d09ef5e7d037..ef8a159833bb 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -358,6 +358,8 @@ def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None, self._name = qName self.namespaceURI = namespaceURI self._prefix = prefix + if localName is not None: + self._localName = localName self.childNodes = NodeList() # Add the single child node that represents the value of the attr diff --git a/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst b/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst new file mode 100644 index 000000000000..c34eff22b3d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst @@ -0,0 +1 @@ +Fix unused ``localName`` parameter in the ``Attr`` class in :mod:`xml.dom.minidom`. From webhook-mailer at python.org Tue Aug 23 12:42:42 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 16:42:42 -0000 Subject: [Python-checkins] gh-96175: add missing self._localName assignment in `xml.dom.minidom.Attr` (GH-96176) Message-ID: <mailman.789.1661272963.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e783a23702f181cdd5b371f180bedbe87a95920b commit: e783a23702f181cdd5b371f180bedbe87a95920b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-23T09:42:10-07:00 summary: gh-96175: add missing self._localName assignment in `xml.dom.minidom.Attr` (GH-96176) X-Ref: https://github.com/python/typeshed/pull/8590GH-discussion_r951473977 Co-authored-by: Jelle Zijlstra <jelle.zijlstra at gmail.com> (cherry picked from commit 58f6953d6d3fe20d972bfa2f6e982206adcf1353) Co-authored-by: Kevin Kirsche <Kev.Kirsche+GitHub at gmail.com> files: A Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst M Lib/test/test_minidom.py M Lib/xml/dom/minidom.py diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 97620258d82f..ef38c362103f 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -9,7 +9,7 @@ import pyexpat import xml.dom.minidom -from xml.dom.minidom import parse, Node, Document, parseString +from xml.dom.minidom import parse, Attr, Node, Document, parseString from xml.dom.minidom import getDOMImplementation from xml.parsers.expat import ExpatError @@ -77,6 +77,20 @@ def testParseFromTextFile(self): dom.unlink() self.confirm(isinstance(dom, Document)) + def testAttrModeSetsParamsAsAttrs(self): + attr = Attr("qName", "namespaceURI", "localName", "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, "localName") + + def testAttrModeSetsNonOptionalAttrs(self): + attr = Attr("qName", "namespaceURI", None, "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, attr.name) + def testGetElementsByTagName(self): dom = parse(tstfile) self.confirm(dom.getElementsByTagName("LI") == \ diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index d09ef5e7d037..ef8a159833bb 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -358,6 +358,8 @@ def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None, self._name = qName self.namespaceURI = namespaceURI self._prefix = prefix + if localName is not None: + self._localName = localName self.childNodes = NodeList() # Add the single child node that represents the value of the attr diff --git a/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst b/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst new file mode 100644 index 000000000000..c34eff22b3d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst @@ -0,0 +1 @@ +Fix unused ``localName`` parameter in the ``Attr`` class in :mod:`xml.dom.minidom`. From webhook-mailer at python.org Tue Aug 23 13:18:35 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 17:18:35 -0000 Subject: [Python-checkins] gh-96175: add missing self._localName assignment in `xml.dom.minidom.Attr` (GH-96176) Message-ID: <mailman.790.1661275116.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d7eea0f1ca29b143f070b36d8df8e278dc302a90 commit: d7eea0f1ca29b143f070b36d8df8e278dc302a90 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-23T10:18:19-07:00 summary: gh-96175: add missing self._localName assignment in `xml.dom.minidom.Attr` (GH-96176) X-Ref: https://github.com/python/typeshed/pull/8590GH-discussion_r951473977 Co-authored-by: Jelle Zijlstra <jelle.zijlstra at gmail.com> (cherry picked from commit 58f6953d6d3fe20d972bfa2f6e982206adcf1353) Co-authored-by: Kevin Kirsche <Kev.Kirsche+GitHub at gmail.com> files: A Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst M Lib/test/test_minidom.py M Lib/xml/dom/minidom.py diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 97620258d82f..ef38c362103f 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -9,7 +9,7 @@ import pyexpat import xml.dom.minidom -from xml.dom.minidom import parse, Node, Document, parseString +from xml.dom.minidom import parse, Attr, Node, Document, parseString from xml.dom.minidom import getDOMImplementation from xml.parsers.expat import ExpatError @@ -77,6 +77,20 @@ def testParseFromTextFile(self): dom.unlink() self.confirm(isinstance(dom, Document)) + def testAttrModeSetsParamsAsAttrs(self): + attr = Attr("qName", "namespaceURI", "localName", "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, "localName") + + def testAttrModeSetsNonOptionalAttrs(self): + attr = Attr("qName", "namespaceURI", None, "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, attr.name) + def testGetElementsByTagName(self): dom = parse(tstfile) self.confirm(dom.getElementsByTagName("LI") == \ diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index d09ef5e7d037..ef8a159833bb 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -358,6 +358,8 @@ def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None, self._name = qName self.namespaceURI = namespaceURI self._prefix = prefix + if localName is not None: + self._localName = localName self.childNodes = NodeList() # Add the single child node that represents the value of the attr diff --git a/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst b/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst new file mode 100644 index 000000000000..c34eff22b3d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst @@ -0,0 +1 @@ +Fix unused ``localName`` parameter in the ``Attr`` class in :mod:`xml.dom.minidom`. From webhook-mailer at python.org Tue Aug 23 15:21:29 2022 From: webhook-mailer at python.org (1st1) Date: Tue, 23 Aug 2022 19:21:29 -0000 Subject: [Python-checkins] Drop myself from owners of genobject (#96216) Message-ID: <mailman.791.1661282491.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e046cf872e33cc79891d829235633077c33c9315 commit: e046cf872e33cc79891d829235633077c33c9315 branch: main author: Yury Selivanov <yury at edgedb.com> committer: 1st1 <yury at edgedb.com> date: 2022-08-23T12:21:10-07:00 summary: Drop myself from owners of genobject (#96216) files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cacd925cf4e3..0e38536ba994 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,7 +9,7 @@ # Core **/*context* @1st1 -**/*genobject* @1st1 @markshannon +**/*genobject* @markshannon **/*hamt* @1st1 Objects/set* @rhettinger Objects/dict* @methane @markshannon From webhook-mailer at python.org Tue Aug 23 16:53:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 23 Aug 2022 20:53:34 -0000 Subject: [Python-checkins] gh-96189: Fix test_invalid_utf8 on a number of build bots (GH-96190) Message-ID: <mailman.792.1661288015.3313.python-checkins@python.org> https://github.com/python/cpython/commit/054328f0dd3e9ee5a8a026dfcfa606baf7e9f052 commit: 054328f0dd3e9ee5a8a026dfcfa606baf7e9f052 branch: main author: Michael Droettboom <mdboom at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-23T13:52:55-07:00 summary: gh-96189: Fix test_invalid_utf8 on a number of build bots (GH-96190) The clearing of the temporary directory is not working on some platforms and leaving behind files. This has been updated to use the pattern in test_cmd_line.py [1] using the special TESTFN rather than a test directory. [1] https://github.com/python/cpython/blob/main/Lib/test/test_cmd_line.py#L559 files: M Lib/test/test_source_encoding.py diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index e1b0de2adef..8d7b573c7e9 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -239,50 +239,50 @@ def test_invalid_utf8(self): # it's an otherwise valid Python source file. template = b'"%s"\n' - with tempfile.TemporaryDirectory() as tmpd: - fn = os.path.join(tmpd, 'test.py') + fn = TESTFN + self.addCleanup(unlink, fn) + + def check(content): + with open(fn, 'wb') as fp: + fp.write(template % content) + script_helper.assert_python_failure(fn) + + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] + # start bytes of a 2-byte sequence equivalent to code points < 0x7F + invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] + # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF + invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] + ) - def check(content): - with open(fn, 'wb') as fp: - fp.write(template % content) - script_helper.assert_python_failure(fn) - - # continuation bytes in a sequence of 2, 3, or 4 bytes - continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] - # start bytes of a 2-byte sequence equivalent to code points < 0x7F - invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] - # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF - invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] - invalid_start_bytes = ( - continuation_bytes + invalid_2B_seq_start_bytes + - invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] - ) - - for byte in invalid_start_bytes: - check(byte) - - for sb in invalid_2B_seq_start_bytes: - for cb in continuation_bytes: - check(sb + cb) - - for sb in invalid_4B_seq_start_bytes: - for cb1 in continuation_bytes[:3]: - for cb3 in continuation_bytes[:3]: - check(sb+cb1+b'\x80'+cb3) - - for cb in [bytes([x]) for x in range(0x80, 0xA0)]: - check(b'\xE0'+cb+b'\x80') - check(b'\xE0'+cb+b'\xBF') - # surrogates - for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: - check(b'\xED'+cb+b'\x80') - check(b'\xED'+cb+b'\xBF') - for cb in [bytes([x]) for x in range(0x80, 0x90)]: - check(b'\xF0'+cb+b'\x80\x80') - check(b'\xF0'+cb+b'\xBF\xBF') - for cb in [bytes([x]) for x in range(0x90, 0xC0)]: - check(b'\xF4'+cb+b'\x80\x80') - check(b'\xF4'+cb+b'\xBF\xBF') + for byte in invalid_start_bytes: + check(byte) + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + check(sb + cb) + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + check(sb+cb1+b'\x80'+cb3) + + for cb in [bytes([x]) for x in range(0x80, 0xA0)]: + check(b'\xE0'+cb+b'\x80') + check(b'\xE0'+cb+b'\xBF') + # surrogates + for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: + check(b'\xED'+cb+b'\x80') + check(b'\xED'+cb+b'\xBF') + for cb in [bytes([x]) for x in range(0x80, 0x90)]: + check(b'\xF0'+cb+b'\x80\x80') + check(b'\xF0'+cb+b'\xBF\xBF') + for cb in [bytes([x]) for x in range(0x90, 0xC0)]: + check(b'\xF4'+cb+b'\x80\x80') + check(b'\xF4'+cb+b'\xBF\xBF') class BytesSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase): From webhook-mailer at python.org Tue Aug 23 17:22:22 2022 From: webhook-mailer at python.org (rhettinger) Date: Tue, 23 Aug 2022 21:22:22 -0000 Subject: [Python-checkins] GH-96145: Add AttrDict to JSON module for use with object_hook (#96146) Message-ID: <mailman.793.1661289743.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1f0eafa844bf5a380603d55e8d4b42d8c2a3439d commit: 1f0eafa844bf5a380603d55e8d4b42d8c2a3439d branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-23T16:22:00-05:00 summary: GH-96145: Add AttrDict to JSON module for use with object_hook (#96146) files: A Lib/test/test_json/test_attrdict.py A Misc/NEWS.d/next/Library/2022-08-20-12-56-15.gh-issue-96145.8ah3pE.rst M Doc/library/json.rst M Lib/json/__init__.py M Lib/test/test_json/__init__.py diff --git a/Doc/library/json.rst b/Doc/library/json.rst index f65be85d31bf..467d5d9e1544 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -9,6 +9,11 @@ **Source code:** :source:`Lib/json/__init__.py` +.. testsetup:: * + + import json + from json import AttrDict + -------------- `JSON (JavaScript Object Notation) <https://json.org>`_, specified by @@ -532,6 +537,44 @@ Exceptions .. versionadded:: 3.5 +.. class:: AttrDict(**kwargs) + AttrDict(mapping, **kwargs) + AttrDict(iterable, **kwargs) + + Subclass of :class:`dict` object that also supports attribute style dotted access. + + This class is intended for use with the :attr:`object_hook` in + :func:`json.load` and :func:`json.loads`:: + + .. doctest:: + + >>> json_string = '{"mercury": 88, "venus": 225, "earth": 365, "mars": 687}' + >>> orbital_period = json.loads(json_string, object_hook=AttrDict) + >>> orbital_period['earth'] # Dict style lookup + 365 + >>> orbital_period.earth # Attribute style lookup + 365 + >>> orbital_period.keys() # All dict methods are present + dict_keys(['mercury', 'venus', 'earth', 'mars']) + + Attribute style access only works for keys that are valid attribute + names. In contrast, dictionary style access works for all keys. For + example, ``d.two words`` contains a space and is not syntactically + valid Python, so ``d["two words"]`` should be used instead. + + If a key has the same name as a dictionary method, then a dictionary + lookup finds the key and an attribute lookup finds the method: + + .. doctest:: + + >>> d = AttrDict(items=50) + >>> d['items'] # Lookup the key + 50 + >>> d.items() # Call the method + dict_items([('items', 50)]) + + .. versionadded:: 3.12 + Standard Compliance and Interoperability ---------------------------------------- diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index e4c21daaf3e4..d775fb1c1107 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -97,7 +97,7 @@ """ __version__ = '2.0.9' __all__ = [ - 'dump', 'dumps', 'load', 'loads', + 'dump', 'dumps', 'load', 'loads', 'AttrDict', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] @@ -357,3 +357,53 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None, if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) + +class AttrDict(dict): + """Dict like object that supports attribute style dotted access. + + This class is intended for use with the *object_hook* in json.loads(): + + >>> from json import loads, AttrDict + >>> json_string = '{"mercury": 88, "venus": 225, "earth": 365, "mars": 687}' + >>> orbital_period = loads(json_string, object_hook=AttrDict) + >>> orbital_period['earth'] # Dict style lookup + 365 + >>> orbital_period.earth # Attribute style lookup + 365 + >>> orbital_period.keys() # All dict methods are present + dict_keys(['mercury', 'venus', 'earth', 'mars']) + + Attribute style access only works for keys that are valid attribute names. + In contrast, dictionary style access works for all keys. + For example, ``d.two words`` contains a space and is not syntactically + valid Python, so ``d["two words"]`` should be used instead. + + If a key has the same name as dictionary method, then a dictionary + lookup finds the key and an attribute lookup finds the method: + + >>> d = AttrDict(items=50) + >>> d['items'] # Lookup the key + 50 + >>> d.items() # Call the method + dict_items([('items', 50)]) + + """ + __slots__ = () + + def __getattr__(self, attr): + try: + return self[attr] + except KeyError: + raise AttributeError(attr) from None + + def __setattr__(self, attr, value): + self[attr] = value + + def __delattr__(self, attr): + try: + del self[attr] + except KeyError: + raise AttributeError(attr) from None + + def __dir__(self): + return list(self) + dir(type(self)) diff --git a/Lib/test/test_json/__init__.py b/Lib/test/test_json/__init__.py index 74b64ed86a31..37b2e0d5e26d 100644 --- a/Lib/test/test_json/__init__.py +++ b/Lib/test/test_json/__init__.py @@ -18,6 +18,7 @@ class PyTest(unittest.TestCase): json = pyjson loads = staticmethod(pyjson.loads) dumps = staticmethod(pyjson.dumps) + AttrDict = pyjson.AttrDict JSONDecodeError = staticmethod(pyjson.JSONDecodeError) @unittest.skipUnless(cjson, 'requires _json') diff --git a/Lib/test/test_json/test_attrdict.py b/Lib/test/test_json/test_attrdict.py new file mode 100644 index 000000000000..48d14f4db93c --- /dev/null +++ b/Lib/test/test_json/test_attrdict.py @@ -0,0 +1,145 @@ +from test.test_json import PyTest +import pickle +import sys +import unittest + +kepler_dict = { + "orbital_period": { + "mercury": 88, + "venus": 225, + "earth": 365, + "mars": 687, + "jupiter": 4331, + "saturn": 10_756, + "uranus": 30_687, + "neptune": 60_190, + }, + "dist_from_sun": { + "mercury": 58, + "venus": 108, + "earth": 150, + "mars": 228, + "jupiter": 778, + "saturn": 1_400, + "uranus": 2_900, + "neptune": 4_500, + } +} + +class TestAttrDict(PyTest): + + def test_dict_subclass(self): + self.assertTrue(issubclass(self.AttrDict, dict)) + + def test_slots(self): + d = self.AttrDict(x=1, y=2) + with self.assertRaises(TypeError): + vars(d) + + def test_constructor_signatures(self): + AttrDict = self.AttrDict + target = dict(x=1, y=2) + self.assertEqual(AttrDict(x=1, y=2), target) # kwargs + self.assertEqual(AttrDict(dict(x=1, y=2)), target) # mapping + self.assertEqual(AttrDict(dict(x=1, y=0), y=2), target) # mapping, kwargs + self.assertEqual(AttrDict([('x', 1), ('y', 2)]), target) # iterable + self.assertEqual(AttrDict([('x', 1), ('y', 0)], y=2), target) # iterable, kwargs + + def test_getattr(self): + d = self.AttrDict(x=1, y=2) + self.assertEqual(d.x, 1) + with self.assertRaises(AttributeError): + d.z + + def test_setattr(self): + d = self.AttrDict(x=1, y=2) + d.x = 3 + d.z = 5 + self.assertEqual(d, dict(x=3, y=2, z=5)) + + def test_delattr(self): + d = self.AttrDict(x=1, y=2) + del d.x + self.assertEqual(d, dict(y=2)) + with self.assertRaises(AttributeError): + del d.z + + def test_dir(self): + d = self.AttrDict(x=1, y=2) + self.assertTrue(set(dir(d)), set(dir(dict)).union({'x', 'y'})) + + def test_repr(self): + # This repr is doesn't round-trip. It matches a regular dict. + # That seems to be the norm for AttrDict recipes being used + # in the wild. Also it supports the design concept that an + # AttrDict is just like a regular dict but has optional + # attribute style lookup. + self.assertEqual(repr(self.AttrDict(x=1, y=2)), + repr(dict(x=1, y=2))) + + def test_overlapping_keys_and_methods(self): + d = self.AttrDict(items=50) + self.assertEqual(d['items'], 50) + self.assertEqual(d.items(), dict(d).items()) + + def test_invalid_attribute_names(self): + d = self.AttrDict({ + 'control': 'normal case', + 'class': 'keyword', + 'two words': 'contains space', + 'hypen-ate': 'contains a hyphen' + }) + self.assertEqual(d.control, dict(d)['control']) + self.assertEqual(d['class'], dict(d)['class']) + self.assertEqual(d['two words'], dict(d)['two words']) + self.assertEqual(d['hypen-ate'], dict(d)['hypen-ate']) + + def test_object_hook_use_case(self): + AttrDict = self.AttrDict + json_string = self.dumps(kepler_dict) + kepler_ad = self.loads(json_string, object_hook=AttrDict) + + self.assertEqual(kepler_ad, kepler_dict) # Match regular dict + self.assertIsInstance(kepler_ad, AttrDict) # Verify conversion + self.assertIsInstance(kepler_ad.orbital_period, AttrDict) # Nested + + # Exercise dotted lookups + self.assertEqual(kepler_ad.orbital_period, kepler_dict['orbital_period']) + self.assertEqual(kepler_ad.orbital_period.earth, + kepler_dict['orbital_period']['earth']) + self.assertEqual(kepler_ad['orbital_period'].earth, + kepler_dict['orbital_period']['earth']) + + # Dict style error handling and Attribute style error handling + with self.assertRaises(KeyError): + kepler_ad.orbital_period['pluto'] + with self.assertRaises(AttributeError): + kepler_ad.orbital_period.Pluto + + # Order preservation + self.assertEqual(list(kepler_ad.items()), list(kepler_dict.items())) + self.assertEqual(list(kepler_ad.orbital_period.items()), + list(kepler_dict['orbital_period'].items())) + + # Round trip + self.assertEqual(self.dumps(kepler_ad), json_string) + + def test_pickle(self): + AttrDict = self.AttrDict + json_string = self.dumps(kepler_dict) + kepler_ad = self.loads(json_string, object_hook=AttrDict) + + # Pickling requires the cached module to be the real module + cached_module = sys.modules.get('json') + sys.modules['json'] = self.json + try: + for protocol in range(6): + kepler_ad2 = pickle.loads(pickle.dumps(kepler_ad, protocol)) + self.assertEqual(kepler_ad2, kepler_ad) + self.assertEqual(type(kepler_ad2), AttrDict) + finally: + sys.modules['json'] = cached_module + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-08-20-12-56-15.gh-issue-96145.8ah3pE.rst b/Misc/NEWS.d/next/Library/2022-08-20-12-56-15.gh-issue-96145.8ah3pE.rst new file mode 100644 index 000000000000..540ec8b71ebf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-20-12-56-15.gh-issue-96145.8ah3pE.rst @@ -0,0 +1 @@ +Add AttrDict to JSON module for use with object_hook. From webhook-mailer at python.org Tue Aug 23 18:28:56 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 23 Aug 2022 22:28:56 -0000 Subject: [Python-checkins] [3.11] gh-96189: Fix test_invalid_utf8 on a number of build bots (GH-96190) (#96218) Message-ID: <mailman.794.1661293737.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c01fc9d30a2a23c8f9f2bcdd85e0c87acfc57e72 commit: c01fc9d30a2a23c8f9f2bcdd85e0c87acfc57e72 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-23T23:28:44+01:00 summary: [3.11] gh-96189: Fix test_invalid_utf8 on a number of build bots (GH-96190) (#96218) Co-authored-by: Michael Droettboom <mdboom at gmail.com> files: M Lib/test/test_source_encoding.py diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index e1b0de2adef..8d7b573c7e9 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -239,50 +239,50 @@ def test_invalid_utf8(self): # it's an otherwise valid Python source file. template = b'"%s"\n' - with tempfile.TemporaryDirectory() as tmpd: - fn = os.path.join(tmpd, 'test.py') + fn = TESTFN + self.addCleanup(unlink, fn) + + def check(content): + with open(fn, 'wb') as fp: + fp.write(template % content) + script_helper.assert_python_failure(fn) + + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] + # start bytes of a 2-byte sequence equivalent to code points < 0x7F + invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] + # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF + invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] + ) - def check(content): - with open(fn, 'wb') as fp: - fp.write(template % content) - script_helper.assert_python_failure(fn) - - # continuation bytes in a sequence of 2, 3, or 4 bytes - continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] - # start bytes of a 2-byte sequence equivalent to code points < 0x7F - invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] - # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF - invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] - invalid_start_bytes = ( - continuation_bytes + invalid_2B_seq_start_bytes + - invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] - ) - - for byte in invalid_start_bytes: - check(byte) - - for sb in invalid_2B_seq_start_bytes: - for cb in continuation_bytes: - check(sb + cb) - - for sb in invalid_4B_seq_start_bytes: - for cb1 in continuation_bytes[:3]: - for cb3 in continuation_bytes[:3]: - check(sb+cb1+b'\x80'+cb3) - - for cb in [bytes([x]) for x in range(0x80, 0xA0)]: - check(b'\xE0'+cb+b'\x80') - check(b'\xE0'+cb+b'\xBF') - # surrogates - for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: - check(b'\xED'+cb+b'\x80') - check(b'\xED'+cb+b'\xBF') - for cb in [bytes([x]) for x in range(0x80, 0x90)]: - check(b'\xF0'+cb+b'\x80\x80') - check(b'\xF0'+cb+b'\xBF\xBF') - for cb in [bytes([x]) for x in range(0x90, 0xC0)]: - check(b'\xF4'+cb+b'\x80\x80') - check(b'\xF4'+cb+b'\xBF\xBF') + for byte in invalid_start_bytes: + check(byte) + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + check(sb + cb) + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + check(sb+cb1+b'\x80'+cb3) + + for cb in [bytes([x]) for x in range(0x80, 0xA0)]: + check(b'\xE0'+cb+b'\x80') + check(b'\xE0'+cb+b'\xBF') + # surrogates + for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: + check(b'\xED'+cb+b'\x80') + check(b'\xED'+cb+b'\xBF') + for cb in [bytes([x]) for x in range(0x80, 0x90)]: + check(b'\xF0'+cb+b'\x80\x80') + check(b'\xF0'+cb+b'\xBF\xBF') + for cb in [bytes([x]) for x in range(0x90, 0xC0)]: + check(b'\xF4'+cb+b'\x80\x80') + check(b'\xF4'+cb+b'\xBF\xBF') class BytesSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase): From webhook-mailer at python.org Tue Aug 23 18:28:59 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 23 Aug 2022 22:28:59 -0000 Subject: [Python-checkins] [3.10] GH-96071: add regression test for GH-96071 (GH-96137) (#96205) Message-ID: <mailman.795.1661293740.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e3c4a5b8ede2f239c8a3de5e0f0a755b67f6c324 commit: e3c4a5b8ede2f239c8a3de5e0f0a755b67f6c324 branch: 3.10 author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-23T23:28:54+01:00 summary: [3.10] GH-96071: add regression test for GH-96071 (GH-96137) (#96205) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: M Lib/test/test_capi.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 7b208c90063..0adb689beb8 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -825,6 +825,20 @@ def callback(): t.start() t.join() + @threading_helper.reap_threads + def test_gilstate_ensure_no_deadlock(self): + # See https://github.com/python/cpython/issues/96071 + code = textwrap.dedent(f""" + import _testcapi + + def callback(): + print('callback called') + + _testcapi._test_thread_state(callback) + """) + ret = assert_python_ok('-X', 'tracemalloc', '-c', code) + self.assertIn(b'callback called', ret.out) + class Test_testcapi(unittest.TestCase): locals().update((name, getattr(_testcapi, name)) From webhook-mailer at python.org Wed Aug 24 03:14:47 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 24 Aug 2022 07:14:47 -0000 Subject: [Python-checkins] gh-94635: Frame sqlite3 how-to headings as such & move default adapters to reference (#96136) Message-ID: <mailman.796.1661325288.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6bda5b85b53443f3467865fbf85cbe72932e7cd6 commit: 6bda5b85b53443f3467865fbf85cbe72932e7cd6 branch: main author: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-24T09:14:14+02:00 summary: gh-94635: Frame sqlite3 how-to headings as such & move default adapters to reference (#96136) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 798c2d795b1..1e54463c11f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1543,6 +1543,41 @@ and you can let the :mod:`!sqlite3` module convert SQLite types to Python types via :ref:`converters <sqlite3-converters>`. +.. _sqlite3-default-converters: + +Default adapters and converters (deprecated) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: + + The default adapters and converters are deprecated as of Python 3.12. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. + +The deprecated default adapters and converters consist of: + +* An adapter for :class:`datetime.date` objects to :class:`strings <str>` in + `ISO 8601`_ format. +* An adapter for :class:`datetime.datetime` objects to strings in + ISO 8601 format. +* A converter for :ref:`declared <sqlite3-converters>` "date" types to + :class:`datetime.date` objects. +* A converter for declared "timestamp" types to + :class:`datetime.datetime` objects. + Fractional parts will be truncated to 6 digits (microsecond precision). + +.. note:: + + The default "timestamp" converter ignores UTC offsets in the database and + always returns a naive :class:`datetime.datetime` object. To preserve UTC + offsets in timestamps, either leave converters disabled, or register an + offset-aware converter with :func:`register_converter`. + +.. deprecated:: 3.12 + +.. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601 + + .. _sqlite3-cli: Command-line interface @@ -1602,8 +1637,8 @@ both styles: .. _sqlite3-adapters: -Using adapters to store custom Python types in SQLite databases -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to adapt custom Python types to SQLite values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SQLite supports only a limited set of data types natively. To store custom Python types in SQLite databases, *adapt* them to one of the @@ -1620,8 +1655,8 @@ registering custom adapter functions. .. _sqlite3-conform: -Letting your object adapt itself -"""""""""""""""""""""""""""""""" +How to write adaptable objects +"""""""""""""""""""""""""""""" Suppose we have a :class:`!Point` class that represents a pair of coordinates, ``x`` and ``y``, in a Cartesian coordinate system. @@ -1634,8 +1669,8 @@ The object passed to *protocol* will be of type :class:`PrepareProtocol`. .. literalinclude:: ../includes/sqlite3/adapter_point_1.py -Registering an adapter callable -""""""""""""""""""""""""""""""" +How to register adapter callables +""""""""""""""""""""""""""""""""" The other possibility is to create a function that converts the Python object to an SQLite-compatible type. @@ -1646,8 +1681,8 @@ This function can then be registered using :func:`register_adapter`. .. _sqlite3-converters: -Converting SQLite values to custom Python types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to convert SQLite values to custom Python types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Writing an adapter lets you convert *from* custom Python types *to* SQLite values. @@ -1686,41 +1721,6 @@ The following example illustrates the implicit and explicit approaches: .. literalinclude:: ../includes/sqlite3/converter_point.py -.. _sqlite3-default-converters: - -Default adapters and converters (deprecated) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. note:: - - The default adapters and converters are deprecated as of Python 3.12. - Instead, use the :ref:`sqlite3-adapter-converter-recipes` - and tailor them to your needs. - -The deprecated default adapters and converters consist of: - -* An adapter for :class:`datetime.date` objects to :class:`strings <str>` in - `ISO 8601`_ format. -* An adapter for :class:`datetime.datetime` objects to strings in - ISO 8601 format. -* A converter for :ref:`declared <sqlite3-converters>` "date" types to - :class:`datetime.date` objects. -* A converter for declared "timestamp" types to - :class:`datetime.datetime` objects. - Fractional parts will be truncated to 6 digits (microsecond precision). - -.. note:: - - The default "timestamp" converter ignores UTC offsets in the database and - always returns a naive :class:`datetime.datetime` object. To preserve UTC - offsets in timestamps, either leave converters disabled, or register an - offset-aware converter with :func:`register_converter`. - -.. deprecated:: 3.12 - -.. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601 - - .. _sqlite3-adapter-converter-recipes: Adapter and converter recipes @@ -1768,8 +1768,8 @@ This section shows recipes for common adapters and converters. .. _sqlite3-connection-shortcuts: -Using connection shortcut methods -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to use connection shortcut methods +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Using the :meth:`~Connection.execute`, :meth:`~Connection.executemany`, and :meth:`~Connection.executescript` @@ -1785,7 +1785,7 @@ directly using only a single call on the :class:`Connection` object. .. _sqlite3-connection-context-manager: -Using the connection as a context manager +How to use the connection context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A :class:`Connection` object can be used as a context manager that @@ -1810,8 +1810,8 @@ the context manager is a no-op. .. _sqlite3-uri-tricks: -Working with SQLite URIs -^^^^^^^^^^^^^^^^^^^^^^^^ +How to work with SQLite URIs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some useful URI tricks include: From webhook-mailer at python.org Wed Aug 24 03:52:19 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 24 Aug 2022 07:52:19 -0000 Subject: [Python-checkins] [3.11] gh-94635: Frame sqlite3 how-to headings as such & move default adapters to reference (GH-96136) (#96226) Message-ID: <mailman.797.1661327540.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2b8fd745489c0c51f05bba510832687160be7db4 commit: 2b8fd745489c0c51f05bba510832687160be7db4 branch: 3.11 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-24T09:51:46+02:00 summary: [3.11] gh-94635: Frame sqlite3 how-to headings as such & move default adapters to reference (GH-96136) (#96226) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com>. (cherry picked from commit 6bda5b85b53443f3467865fbf85cbe72932e7cd6) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index cf496b7f6a6..4cc8b77f381 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1530,6 +1530,38 @@ and you can let the :mod:`!sqlite3` module convert SQLite types to Python types via :ref:`converters <sqlite3-converters>`. +.. _sqlite3-default-converters: + +Default adapters and converters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are default adapters for the date and datetime types in the datetime +module. They will be sent as ISO dates/ISO timestamps to SQLite. + +The default converters are registered under the name "date" for +:class:`datetime.date` and under the name "timestamp" for +:class:`datetime.datetime`. + +This way, you can use date/timestamps from Python without any additional +fiddling in most cases. The format of the adapters is also compatible with the +experimental SQLite date/time functions. + +The following example demonstrates this. + +.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py + +If a timestamp stored in SQLite has a fractional part longer than 6 +numbers, its value will be truncated to microsecond precision by the +timestamp converter. + +.. note:: + + The default "timestamp" converter ignores UTC offsets in the database and + always returns a naive :class:`datetime.datetime` object. To preserve UTC + offsets in timestamps, either leave converters disabled, or register an + offset-aware converter with :func:`register_converter`. + + .. _sqlite3-howtos: How-to guides @@ -1567,8 +1599,8 @@ both styles: .. _sqlite3-adapters: -Using adapters to store custom Python types in SQLite databases -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to adapt custom Python types to SQLite values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SQLite supports only a limited set of data types natively. To store custom Python types in SQLite databases, *adapt* them to one of the @@ -1585,8 +1617,8 @@ registering custom adapter functions. .. _sqlite3-conform: -Letting your object adapt itself -"""""""""""""""""""""""""""""""" +How to write adaptable objects +"""""""""""""""""""""""""""""" Suppose we have a :class:`!Point` class that represents a pair of coordinates, ``x`` and ``y``, in a Cartesian coordinate system. @@ -1599,8 +1631,8 @@ The object passed to *protocol* will be of type :class:`PrepareProtocol`. .. literalinclude:: ../includes/sqlite3/adapter_point_1.py -Registering an adapter callable -""""""""""""""""""""""""""""""" +How to register adapter callables +""""""""""""""""""""""""""""""""" The other possibility is to create a function that converts the Python object to an SQLite-compatible type. @@ -1611,8 +1643,8 @@ This function can then be registered using :func:`register_adapter`. .. _sqlite3-converters: -Converting SQLite values to custom Python types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to convert SQLite values to custom Python types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Writing an adapter lets you convert *from* custom Python types *to* SQLite values. @@ -1651,36 +1683,6 @@ The following example illustrates the implicit and explicit approaches: .. literalinclude:: ../includes/sqlite3/converter_point.py -Default adapters and converters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -There are default adapters for the date and datetime types in the datetime -module. They will be sent as ISO dates/ISO timestamps to SQLite. - -The default converters are registered under the name "date" for -:class:`datetime.date` and under the name "timestamp" for -:class:`datetime.datetime`. - -This way, you can use date/timestamps from Python without any additional -fiddling in most cases. The format of the adapters is also compatible with the -experimental SQLite date/time functions. - -The following example demonstrates this. - -.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py - -If a timestamp stored in SQLite has a fractional part longer than 6 -numbers, its value will be truncated to microsecond precision by the -timestamp converter. - -.. note:: - - The default "timestamp" converter ignores UTC offsets in the database and - always returns a naive :class:`datetime.datetime` object. To preserve UTC - offsets in timestamps, either leave converters disabled, or register an - offset-aware converter with :func:`register_converter`. - - .. _sqlite3-adapter-converter-recipes: Adapter and converter recipes @@ -1728,8 +1730,8 @@ This section shows recipes for common adapters and converters. .. _sqlite3-connection-shortcuts: -Using connection shortcut methods -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to use connection shortcut methods +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Using the :meth:`~Connection.execute`, :meth:`~Connection.executemany`, and :meth:`~Connection.executescript` @@ -1745,7 +1747,7 @@ directly using only a single call on the :class:`Connection` object. .. _sqlite3-connection-context-manager: -Using the connection as a context manager +How to use the connection context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A :class:`Connection` object can be used as a context manager that @@ -1770,8 +1772,8 @@ the context manager is a no-op. .. _sqlite3-uri-tricks: -Working with SQLite URIs -^^^^^^^^^^^^^^^^^^^^^^^^ +How to work with SQLite URIs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some useful URI tricks include: From webhook-mailer at python.org Wed Aug 24 03:52:21 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 24 Aug 2022 07:52:21 -0000 Subject: [Python-checkins] [3.10] gh-94635: Frame sqlite3 how-to headings as such & move default adapters to reference (GH-96136) (#96227) Message-ID: <mailman.798.1661327543.3313.python-checkins@python.org> https://github.com/python/cpython/commit/203b598e5113f3662bfbaf3474dd62a258b8b6ce commit: 203b598e5113f3662bfbaf3474dd62a258b8b6ce branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-24T09:52:16+02:00 summary: [3.10] gh-94635: Frame sqlite3 how-to headings as such & move default adapters to reference (GH-96136) (#96227) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com>. (cherry picked from commit 6bda5b85b53443f3467865fbf85cbe72932e7cd6) Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index be9a22efad1..94d1e1b0e7a 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1233,6 +1233,38 @@ and you can let the :mod:`!sqlite3` module convert SQLite types to Python types via :ref:`converters <sqlite3-converters>`. +.. _sqlite3-default-converters: + +Default adapters and converters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are default adapters for the date and datetime types in the datetime +module. They will be sent as ISO dates/ISO timestamps to SQLite. + +The default converters are registered under the name "date" for +:class:`datetime.date` and under the name "timestamp" for +:class:`datetime.datetime`. + +This way, you can use date/timestamps from Python without any additional +fiddling in most cases. The format of the adapters is also compatible with the +experimental SQLite date/time functions. + +The following example demonstrates this. + +.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py + +If a timestamp stored in SQLite has a fractional part longer than 6 +numbers, its value will be truncated to microsecond precision by the +timestamp converter. + +.. note:: + + The default "timestamp" converter ignores UTC offsets in the database and + always returns a naive :class:`datetime.datetime` object. To preserve UTC + offsets in timestamps, either leave converters disabled, or register an + offset-aware converter with :func:`register_converter`. + + .. _sqlite3-howtos: How-to guides @@ -1270,8 +1302,8 @@ both styles: .. _sqlite3-adapters: -Using adapters to store custom Python types in SQLite databases -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to adapt custom Python types to SQLite values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SQLite supports only a limited set of data types natively. To store custom Python types in SQLite databases, *adapt* them to one of the @@ -1288,8 +1320,8 @@ registering custom adapter functions. .. _sqlite3-conform: -Letting your object adapt itself -"""""""""""""""""""""""""""""""" +How to write adaptable objects +"""""""""""""""""""""""""""""" Suppose we have a :class:`!Point` class that represents a pair of coordinates, ``x`` and ``y``, in a Cartesian coordinate system. @@ -1302,8 +1334,8 @@ The object passed to *protocol* will be of type :class:`PrepareProtocol`. .. literalinclude:: ../includes/sqlite3/adapter_point_1.py -Registering an adapter callable -""""""""""""""""""""""""""""""" +How to register adapter callables +""""""""""""""""""""""""""""""""" The other possibility is to create a function that converts the Python object to an SQLite-compatible type. @@ -1314,8 +1346,8 @@ This function can then be registered using :func:`register_adapter`. .. _sqlite3-converters: -Converting SQLite values to custom Python types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to convert SQLite values to custom Python types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Writing an adapter lets you convert *from* custom Python types *to* SQLite values. @@ -1354,36 +1386,6 @@ The following example illustrates the implicit and explicit approaches: .. literalinclude:: ../includes/sqlite3/converter_point.py -Default adapters and converters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -There are default adapters for the date and datetime types in the datetime -module. They will be sent as ISO dates/ISO timestamps to SQLite. - -The default converters are registered under the name "date" for -:class:`datetime.date` and under the name "timestamp" for -:class:`datetime.datetime`. - -This way, you can use date/timestamps from Python without any additional -fiddling in most cases. The format of the adapters is also compatible with the -experimental SQLite date/time functions. - -The following example demonstrates this. - -.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py - -If a timestamp stored in SQLite has a fractional part longer than 6 -numbers, its value will be truncated to microsecond precision by the -timestamp converter. - -.. note:: - - The default "timestamp" converter ignores UTC offsets in the database and - always returns a naive :class:`datetime.datetime` object. To preserve UTC - offsets in timestamps, either leave converters disabled, or register an - offset-aware converter with :func:`register_converter`. - - .. _sqlite3-adapter-converter-recipes: Adapter and converter recipes @@ -1431,8 +1433,8 @@ This section shows recipes for common adapters and converters. .. _sqlite3-connection-shortcuts: -Using connection shortcut methods -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to use connection shortcut methods +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Using the :meth:`~Connection.execute`, :meth:`~Connection.executemany`, and :meth:`~Connection.executescript` @@ -1448,7 +1450,7 @@ directly using only a single call on the :class:`Connection` object. .. _sqlite3-connection-context-manager: -Using the connection as a context manager +How to use the connection context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A :class:`Connection` object can be used as a context manager that @@ -1473,8 +1475,8 @@ the context manager is a no-op. .. _sqlite3-uri-tricks: -Working with SQLite URIs -^^^^^^^^^^^^^^^^^^^^^^^^ +How to work with SQLite URIs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some useful URI tricks include: From webhook-mailer at python.org Wed Aug 24 06:03:05 2022 From: webhook-mailer at python.org (iritkatriel) Date: Wed, 24 Aug 2022 10:03:05 -0000 Subject: [Python-checkins] gh-93678: add _testinternalcapi.optimize_cfg() and test utils for compiler optimization unit tests (GH-96007) Message-ID: <mailman.799.1661335387.3313.python-checkins@python.org> https://github.com/python/cpython/commit/420f39f457a97a9379f8423a81776bef428d0746 commit: 420f39f457a97a9379f8423a81776bef428d0746 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-24T11:02:53+01:00 summary: gh-93678: add _testinternalcapi.optimize_cfg() and test utils for compiler optimization unit tests (GH-96007) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-15-20-52-41.gh-issue-93678.X7GuIJ.rst A Modules/clinic/_testinternalcapi.c.h M Include/internal/pycore_compile.h M Include/internal/pycore_global_strings.h M Include/internal/pycore_runtime_init_generated.h M Lib/test/support/bytecode_helper.py M Lib/test/test_peepholer.py M Modules/_testinternalcapi.c M Python/compile.c diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index 06a6082cddae..1a628a08ca4e 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -38,6 +38,11 @@ extern int _PyAST_Optimize( struct _arena *arena, _PyASTOptimizeState *state); +/* Access compiler internals for unit testing */ +PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg( + PyObject *instructions, + PyObject *consts); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index aada22039502..c736bfecd077 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -298,6 +298,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(code) STRUCT_FOR_ID(command) STRUCT_FOR_ID(comment_factory) + STRUCT_FOR_ID(consts) STRUCT_FOR_ID(context) STRUCT_FOR_ID(cookie) STRUCT_FOR_ID(copy) @@ -407,6 +408,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(input) STRUCT_FOR_ID(insert_comments) STRUCT_FOR_ID(insert_pis) + STRUCT_FOR_ID(instructions) STRUCT_FOR_ID(intern) STRUCT_FOR_ID(intersection) STRUCT_FOR_ID(isatty) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 09890cd81201..58d9e934b96c 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -807,6 +807,7 @@ extern "C" { INIT_ID(code), \ INIT_ID(command), \ INIT_ID(comment_factory), \ + INIT_ID(consts), \ INIT_ID(context), \ INIT_ID(cookie), \ INIT_ID(copy), \ @@ -916,6 +917,7 @@ extern "C" { INIT_ID(input), \ INIT_ID(insert_comments), \ INIT_ID(insert_pis), \ + INIT_ID(instructions), \ INIT_ID(intern), \ INIT_ID(intersection), \ INIT_ID(isatty), \ @@ -1916,6 +1918,8 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(comment_factory); PyUnicode_InternInPlace(&string); + string = &_Py_ID(consts); + PyUnicode_InternInPlace(&string); string = &_Py_ID(context); PyUnicode_InternInPlace(&string); string = &_Py_ID(cookie); @@ -2134,6 +2138,8 @@ _PyUnicode_InitStaticStrings(void) { PyUnicode_InternInPlace(&string); string = &_Py_ID(insert_pis); PyUnicode_InternInPlace(&string); + string = &_Py_ID(instructions); + PyUnicode_InternInPlace(&string); string = &_Py_ID(intern); PyUnicode_InternInPlace(&string); string = &_Py_ID(intersection); @@ -5755,6 +5761,10 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(comment_factory)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(consts)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(consts)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(context)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(context)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); @@ -6191,6 +6201,10 @@ _PyStaticObjects_CheckRefcnt(void) { _PyObject_Dump((PyObject *)&_Py_ID(insert_pis)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); }; + if (Py_REFCNT((PyObject *)&_Py_ID(instructions)) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_Dump((PyObject *)&_Py_ID(instructions)); + Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); + }; if (Py_REFCNT((PyObject *)&_Py_ID(intern)) < _PyObject_IMMORTAL_REFCNT) { _PyObject_Dump((PyObject *)&_Py_ID(intern)); Py_FatalError("immortal object has less refcnt than expected _PyObject_IMMORTAL_REFCNT"); diff --git a/Lib/test/support/bytecode_helper.py b/Lib/test/support/bytecode_helper.py index 471d4a68f915..05b54911e3f2 100644 --- a/Lib/test/support/bytecode_helper.py +++ b/Lib/test/support/bytecode_helper.py @@ -3,6 +3,7 @@ import unittest import dis import io +from _testinternalcapi import optimize_cfg _UNSPECIFIED = object() @@ -40,3 +41,95 @@ def assertNotInBytecode(self, x, opname, argval=_UNSPECIFIED): msg = '(%s,%r) occurs in bytecode:\n%s' msg = msg % (opname, argval, disassembly) self.fail(msg) + + +class CfgOptimizationTestCase(unittest.TestCase): + + HAS_ARG = set(dis.hasarg) + HAS_TARGET = set(dis.hasjrel + dis.hasjabs + dis.hasexc) + HAS_ARG_OR_TARGET = HAS_ARG.union(HAS_TARGET) + + def setUp(self): + self.last_label = 0 + + def Label(self): + self.last_label += 1 + return self.last_label + + def complete_insts_info(self, insts): + # fill in omitted fields in location, and oparg 0 for ops with no arg. + instructions = [] + for item in insts: + if isinstance(item, int): + instructions.append(item) + else: + assert isinstance(item, tuple) + inst = list(reversed(item)) + opcode = dis.opmap[inst.pop()] + oparg = inst.pop() if opcode in self.HAS_ARG_OR_TARGET else 0 + loc = inst + [-1] * (4 - len(inst)) + instructions.append((opcode, oparg, *loc)) + return instructions + + def normalize_insts(self, insts): + """ Map labels to instruction index. + Remove labels which are not used as jump targets. + """ + labels_map = {} + targets = set() + idx = 1 + for item in insts: + assert isinstance(item, (int, tuple)) + if isinstance(item, tuple): + opcode, oparg, *_ = item + if dis.opmap.get(opcode, opcode) in self.HAS_TARGET: + targets.add(oparg) + idx += 1 + elif isinstance(item, int): + assert item not in labels_map, "label reused" + labels_map[item] = idx + + res = [] + for item in insts: + if isinstance(item, int) and item in targets: + if not res or labels_map[item] != res[-1]: + res.append(labels_map[item]) + elif isinstance(item, tuple): + opcode, oparg, *loc = item + opcode = dis.opmap.get(opcode, opcode) + if opcode in self.HAS_TARGET: + arg = labels_map[oparg] + else: + arg = oparg if opcode in self.HAS_TARGET else None + opcode = dis.opname[opcode] + res.append((opcode, arg, *loc)) + return res + + def get_optimized(self, insts, consts): + insts = self.complete_insts_info(insts) + insts = optimize_cfg(insts, consts) + return insts, consts + + def compareInstructions(self, actual_, expected_): + # get two lists where each entry is a label or + # an instruction tuple. Compare them, while mapping + # each actual label to a corresponding expected label + # based on their locations. + + self.assertIsInstance(actual_, list) + self.assertIsInstance(expected_, list) + + actual = self.normalize_insts(actual_) + expected = self.normalize_insts(expected_) + self.assertEqual(len(actual), len(expected)) + + # compare instructions + for act, exp in zip(actual, expected): + if isinstance(act, int): + self.assertEqual(exp, act) + continue + self.assertIsInstance(exp, tuple) + self.assertIsInstance(act, tuple) + # pad exp with -1's (if location info is incomplete) + exp += (-1,) * (len(act) - len(exp)) + self.assertEqual(exp, act) diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index e03c42c2f823..7ece468363be 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -4,7 +4,7 @@ import textwrap import unittest -from test.support.bytecode_helper import BytecodeTestCase +from test.support.bytecode_helper import BytecodeTestCase, CfgOptimizationTestCase def compile_pattern_with_fast_locals(pattern): @@ -864,5 +864,81 @@ def trace(frame, event, arg): self.assertNotInBytecode(f, "LOAD_FAST_CHECK") +class DirectiCfgOptimizerTests(CfgOptimizationTestCase): + + def cfg_optimization_test(self, insts, expected_insts, + consts=None, expected_consts=None): + if expected_consts is None: + expected_consts = consts + opt_insts, opt_consts = self.get_optimized(insts, consts) + self.compareInstructions(opt_insts, expected_insts) + self.assertEqual(opt_consts, expected_consts) + + def test_conditional_jump_forward_non_const_condition(self): + insts = [ + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 2, 13), + lbl, + ('LOAD_CONST', 3, 14), + ] + expected = [ + ('LOAD_NAME', '1', 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', '2', 13), + lbl, + ('LOAD_CONST', '3', 14) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_forward_const_condition(self): + # The unreachable branch of the jump is removed + + insts = [ + ('LOAD_CONST', 3, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 2, 13), + lbl, + ('LOAD_CONST', 3, 14), + ] + expected = [ + ('NOP', None, 11), + ('JUMP', lbl := self.Label(), 12), + lbl, + ('LOAD_CONST', '3', 14) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_backward_non_const_condition(self): + insts = [ + lbl1 := self.Label(), + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl1, 12), + ('LOAD_CONST', 2, 13), + ] + expected = [ + lbl := self.Label(), + ('LOAD_NAME', '1', 11), + ('POP_JUMP_IF_TRUE', lbl, 12), + ('LOAD_CONST', '2', 13) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_backward_const_condition(self): + # The unreachable branch of the jump is removed + insts = [ + lbl1 := self.Label(), + ('LOAD_CONST', 1, 11), + ('POP_JUMP_IF_TRUE', lbl1, 12), + ('LOAD_CONST', 2, 13), + ] + expected = [ + lbl := self.Label(), + ('NOP', None, 11), + ('JUMP', lbl, 12) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-15-20-52-41.gh-issue-93678.X7GuIJ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-20-52-41.gh-issue-93678.X7GuIJ.rst new file mode 100644 index 000000000000..9e2b90ba07a4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-15-20-52-41.gh-issue-93678.X7GuIJ.rst @@ -0,0 +1 @@ +Added test a harness for direct unit tests of the compiler's optimization stage. The ``_testinternalcapi.optimize_cfg()`` function runs the optimiser on a sequence of instructions. The ``CfgOptimizationTestCase`` class in ``test.support`` has utilities for invoking the optimizer and checking the output. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 238de749fffc..9d92b076387f 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -14,6 +14,7 @@ #include "Python.h" #include "pycore_atomic_funcs.h" // _Py_atomic_int_get() #include "pycore_bitutils.h" // _Py_bswap32() +#include "pycore_compile.h" // _PyCompile_OptimizeCfg() #include "pycore_fileutils.h" // _Py_normpath #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_gc.h" // PyGC_Head @@ -25,7 +26,12 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #include "osdefs.h" // MAXPATHLEN +#include "clinic/_testinternalcapi.c.h" +/*[clinic input] +module _testinternalcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7bb583d8c9eb9a78]*/ static PyObject * get_configs(PyObject *self, PyObject *Py_UNUSED(args)) { @@ -525,6 +531,25 @@ set_eval_frame_record(PyObject *self, PyObject *list) } +/*[clinic input] + +_testinternalcapi.optimize_cfg -> object + + instructions: object + consts: object + +Apply compiler optimizations to an instruction list. +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions, + PyObject *consts) +/*[clinic end generated code: output=5412aeafca683c8b input=7e8a3de86ebdd0f9]*/ +{ + return _PyCompile_OptimizeCfg(instructions, consts); +} + + static PyMethodDef TestMethods[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, @@ -543,6 +568,7 @@ static PyMethodDef TestMethods[] = { {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, {"set_eval_frame_default", set_eval_frame_default, METH_NOARGS, NULL}, {"set_eval_frame_record", set_eval_frame_record, METH_O, NULL}, + _TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/clinic/_testinternalcapi.c.h b/Modules/clinic/_testinternalcapi.c.h new file mode 100644 index 000000000000..8113fff37997 --- /dev/null +++ b/Modules/clinic/_testinternalcapi.c.h @@ -0,0 +1,68 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testinternalcapi_optimize_cfg__doc__, +"optimize_cfg($module, /, instructions, consts)\n" +"--\n" +"\n" +"Apply compiler optimizations to an instruction list."); + +#define _TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF \ + {"optimize_cfg", _PyCFunction_CAST(_testinternalcapi_optimize_cfg), METH_FASTCALL|METH_KEYWORDS, _testinternalcapi_optimize_cfg__doc__}, + +static PyObject * +_testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions, + PyObject *consts); + +static PyObject * +_testinternalcapi_optimize_cfg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(instructions), &_Py_ID(consts), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"instructions", "consts", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "optimize_cfg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *instructions; + PyObject *consts; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + instructions = args[0]; + consts = args[1]; + return_value = _testinternalcapi_optimize_cfg_impl(module, instructions, consts); + +exit: + return return_value; +} +/*[clinic end generated code: output=3b1fd713290f68a9 input=a9049054013a1b77]*/ diff --git a/Python/compile.c b/Python/compile.c index 339e0e792be4..e5ac162ccc0a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -457,6 +457,7 @@ typedef struct { static int basicblock_next_instr(basicblock *); +static basicblock *cfg_builder_new_block(cfg_builder *g); static int cfg_builder_maybe_start_new_block(cfg_builder *g); static int cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct location loc); @@ -767,8 +768,20 @@ cfg_builder_check(cfg_builder *g) } } +static int +cfg_builder_init(cfg_builder *g) +{ + g->g_block_list = NULL; + basicblock *block = cfg_builder_new_block(g); + if (block == NULL) + return 0; + g->g_curblock = g->g_entryblock = block; + g->g_current_label = NO_LABEL; + return 1; +} + static void -cfg_builder_free(cfg_builder* g) +cfg_builder_fini(cfg_builder* g) { cfg_builder_check(g); basicblock *b = g->g_block_list; @@ -785,7 +798,7 @@ cfg_builder_free(cfg_builder* g) static void compiler_unit_free(struct compiler_unit *u) { - cfg_builder_free(&u->u_cfg_builder); + cfg_builder_fini(&u->u_cfg_builder); Py_CLEAR(u->u_ste); Py_CLEAR(u->u_name); Py_CLEAR(u->u_qualname); @@ -1708,7 +1721,6 @@ compiler_enter_scope(struct compiler *c, identifier name, int scope_type, void *key, int lineno) { struct compiler_unit *u; - basicblock *block; u = (struct compiler_unit *)PyObject_Calloc(1, sizeof( struct compiler_unit)); @@ -1786,12 +1798,9 @@ compiler_enter_scope(struct compiler *c, identifier name, c->c_nestlevel++; cfg_builder *g = CFG_BUILDER(c); - g->g_block_list = NULL; - block = cfg_builder_new_block(g); - if (block == NULL) + if (!cfg_builder_init(g)) { return 0; - g->g_curblock = g->g_entryblock = block; - g->g_current_label = NO_LABEL; + } if (u->u_scope_type == COMPILER_SCOPE_MODULE) { c->u->u_loc.lineno = 0; @@ -8220,7 +8229,7 @@ dump_instr(struct instr *i) sprintf(arg, "arg: %d ", i->i_oparg); } if (HAS_TARGET(i->i_opcode)) { - sprintf(arg, "target: %p ", i->i_target); + sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg); } fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", i->i_loc.lineno, i->i_opcode, arg, jabs, jrel); @@ -8251,7 +8260,7 @@ static int calculate_jump_targets(basicblock *entryblock); static int -optimize_cfg(basicblock *entryblock, PyObject *consts, PyObject *const_cache); +optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache); static int trim_unused_consts(basicblock *entryblock, PyObject *consts); @@ -8465,18 +8474,18 @@ static void propagate_line_numbers(basicblock *entryblock); static void -eliminate_empty_basic_blocks(basicblock *entryblock); +eliminate_empty_basic_blocks(cfg_builder *g); static int -remove_redundant_jumps(basicblock *entryblock) { +remove_redundant_jumps(cfg_builder *g) { /* If a non-empty block ends with a jump instruction, check if the next * non-empty block reached through normal flow control is the target * of that jump. If it is, then the jump instruction is redundant and * can be deleted. */ int removed = 0; - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (b->b_iused > 0) { struct instr *b_last_instr = &b->b_instr[b->b_iused - 1]; assert(!IS_ASSEMBLER_OPCODE(b_last_instr->i_opcode)); @@ -8495,7 +8504,7 @@ remove_redundant_jumps(basicblock *entryblock) { } } if (removed) { - eliminate_empty_basic_blocks(entryblock); + eliminate_empty_basic_blocks(g); } return 0; } @@ -8545,13 +8554,12 @@ assemble(struct compiler *c, int addNone) } cfg_builder *g = CFG_BUILDER(c); - basicblock *entryblock = g->g_entryblock; - assert(entryblock != NULL); + assert(g->g_entryblock != NULL); /* Set firstlineno if it wasn't explicitly set. */ if (!c->u->u_firstlineno) { - if (entryblock->b_instr && entryblock->b_instr->i_loc.lineno) { - c->u->u_firstlineno = entryblock->b_instr->i_loc.lineno; + if (g->g_entryblock->b_instr && g->g_entryblock->b_instr->i_loc.lineno) { + c->u->u_firstlineno = g->g_entryblock->b_instr->i_loc.lineno; } else { c->u->u_firstlineno = 1; @@ -8559,11 +8567,11 @@ assemble(struct compiler *c, int addNone) } // This must be called before fix_cell_offsets(). - if (insert_prefix_instructions(c, entryblock, cellfixedoffsets, nfreevars, code_flags)) { + if (insert_prefix_instructions(c, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) { goto error; } - int numdropped = fix_cell_offsets(c, entryblock, cellfixedoffsets); + int numdropped = fix_cell_offsets(c, g->g_entryblock, cellfixedoffsets); PyMem_Free(cellfixedoffsets); // At this point we're done with it. cellfixedoffsets = NULL; if (numdropped < 0) { @@ -8575,52 +8583,52 @@ assemble(struct compiler *c, int addNone) if (consts == NULL) { goto error; } - if (calculate_jump_targets(entryblock)) { + if (calculate_jump_targets(g->g_entryblock)) { goto error; } - if (optimize_cfg(entryblock, consts, c->c_const_cache)) { + if (optimize_cfg(g, consts, c->c_const_cache)) { goto error; } - if (trim_unused_consts(entryblock, consts)) { + if (trim_unused_consts(g->g_entryblock, consts)) { goto error; } if (duplicate_exits_without_lineno(g)) { return NULL; } - propagate_line_numbers(entryblock); - guarantee_lineno_for_exits(entryblock, c->u->u_firstlineno); + propagate_line_numbers(g->g_entryblock); + guarantee_lineno_for_exits(g->g_entryblock, c->u->u_firstlineno); - int maxdepth = stackdepth(entryblock, code_flags); + int maxdepth = stackdepth(g->g_entryblock, code_flags); if (maxdepth < 0) { goto error; } /* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */ - if (label_exception_targets(entryblock)) { + if (label_exception_targets(g->g_entryblock)) { goto error; } - convert_exception_handlers_to_nops(entryblock); + convert_exception_handlers_to_nops(g->g_entryblock); if (push_cold_blocks_to_end(g, code_flags) < 0) { goto error; } - if (remove_redundant_jumps(entryblock) < 0) { + if (remove_redundant_jumps(g) < 0) { goto error; } - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { clean_basic_block(b); } /* Order of basic blocks must have been determined by now */ - normalize_jumps(entryblock); + normalize_jumps(g->g_entryblock); - if (add_checks_for_loads_of_unknown_variables(entryblock, c) < 0) { + if (add_checks_for_loads_of_unknown_variables(g->g_entryblock, c) < 0) { goto error; } /* Can't modify the bytecode after computing jump offsets. */ - assemble_jump_offsets(entryblock); + assemble_jump_offsets(g->g_entryblock); /* Create assembler */ @@ -8628,7 +8636,7 @@ assemble(struct compiler *c, int addNone) goto error; /* Emit code. */ - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { for (int j = 0; j < b->b_iused; j++) if (!assemble_emit(&a, &b->b_instr[j])) goto error; @@ -8636,13 +8644,13 @@ assemble(struct compiler *c, int addNone) /* Emit location info */ a.a_lineno = c->u->u_firstlineno; - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { for (int j = 0; j < b->b_iused; j++) if (!assemble_emit_location(&a, &b->b_instr[j])) goto error; } - if (!assemble_exception_table(&a, entryblock)) { + if (!assemble_exception_table(&a, g->g_entryblock)) { goto error; } if (_PyBytes_Resize(&a.a_except_table, a.a_except_table_off) < 0) { @@ -9352,16 +9360,19 @@ mark_reachable(basicblock *entryblock) { } static void -eliminate_empty_basic_blocks(basicblock *entryblock) { +eliminate_empty_basic_blocks(cfg_builder *g) { /* Eliminate empty blocks */ - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { basicblock *next = b->b_next; while (next && next->b_iused == 0) { next = next->b_next; } b->b_next = next; } - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + while(g->g_entryblock && g->g_entryblock->b_iused == 0) { + g->g_entryblock = g->g_entryblock->b_next; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { assert(b->b_iused > 0); for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; @@ -9467,42 +9478,42 @@ calculate_jump_targets(basicblock *entryblock) */ static int -optimize_cfg(basicblock *entryblock, PyObject *consts, PyObject *const_cache) +optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache) { assert(PyDict_CheckExact(const_cache)); - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (normalize_basic_block(b)) { return -1; } } - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (extend_block(b)) { return -1; } } - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (optimize_basic_block(const_cache, b, consts)) { return -1; } clean_basic_block(b); assert(b->b_predecessors == 0); } - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (extend_block(b)) { return -1; } } - if (mark_reachable(entryblock)) { + if (mark_reachable(g->g_entryblock)) { return -1; } /* Delete unreachable instructions */ - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (b->b_predecessors == 0) { b->b_iused = 0; } } - eliminate_empty_basic_blocks(entryblock); - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + eliminate_empty_basic_blocks(g); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { clean_basic_block(b); } return 0; @@ -9601,6 +9612,157 @@ duplicate_exits_without_lineno(cfg_builder *g) } +/* Access to compiler optimizations for unit tests. + * + * _PyCompile_OptimizeCfg takes an instruction list, constructs + * a CFG, optimizes it and converts back to an instruction list. + * + * An instruction list is a PyList where each item is either + * a tuple describing a single instruction: + * (opcode, oparg, lineno, end_lineno, col, end_col), or + * a jump target label marking the beginning of a basic block. + */ + +static int +instructions_to_cfg(PyObject *instructions, cfg_builder *g) +{ + assert(PyList_Check(instructions)); + + Py_ssize_t instr_size = PyList_GET_SIZE(instructions); + for (Py_ssize_t i = 0; i < instr_size; i++) { + PyObject *item = PyList_GET_ITEM(instructions, i); + if (PyLong_Check(item)) { + int lbl_id = PyLong_AsLong(item); + if (PyErr_Occurred()) { + return -1; + } + if (lbl_id <= 0 || lbl_id > instr_size) { + /* expect label in a reasonable range */ + PyErr_SetString(PyExc_ValueError, "label out of range"); + return -1; + } + jump_target_label lbl = {lbl_id}; + if (cfg_builder_use_label(g, lbl) < 0) { + return -1; + } + } + else { + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) { + PyErr_SetString(PyExc_ValueError, "expected a 6-tuple"); + return -1; + } + int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0)); + if (PyErr_Occurred()) { + return -1; + } + int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1)); + if (PyErr_Occurred()) { + return -1; + } + struct location loc; + loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2)); + if (PyErr_Occurred()) { + return -1; + } + loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3)); + if (PyErr_Occurred()) { + return -1; + } + loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4)); + if (PyErr_Occurred()) { + return -1; + } + loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5)); + if (PyErr_Occurred()) { + return -1; + } + if (!cfg_builder_addop(g, opcode, oparg, loc)) { + return -1; + } + } + } + return 0; +} + +static PyObject * +cfg_to_instructions(cfg_builder *g) +{ + PyObject *instructions = PyList_New(0); + if (instructions == NULL) { + return NULL; + } + int lbl = 1; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + b->b_label = lbl++; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + PyObject *lbl = PyLong_FromLong(b->b_label); + if (lbl == NULL) { + goto error; + } + if (PyList_Append(instructions, lbl) != 0) { + Py_DECREF(lbl); + goto error; + } + Py_DECREF(lbl); + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + struct location loc = instr->i_loc; + int arg = HAS_TARGET(instr->i_opcode) ? instr->i_target->b_label : instr->i_oparg; + PyObject *inst_tuple = Py_BuildValue( + "(iiiiii)", instr->i_opcode, arg, + loc.lineno, loc.end_lineno, + loc.col_offset, loc.end_col_offset); + if (inst_tuple == NULL) { + goto error; + } + + if (PyList_Append(instructions, inst_tuple) != 0) { + Py_DECREF(inst_tuple); + goto error; + } + Py_DECREF(inst_tuple); + } + } + + return instructions; +error: + Py_DECREF(instructions); + return NULL; +} + + +PyObject * +_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts) +{ + PyObject *res = NULL; + PyObject *const_cache = NULL; + cfg_builder g; + memset(&g, 0, sizeof(cfg_builder)); + if (cfg_builder_init(&g) < 0) { + goto error; + } + if (instructions_to_cfg(instructions, &g) < 0) { + goto error; + } + const_cache = PyDict_New(); + if (const_cache == NULL) { + goto error; + } + if (calculate_jump_targets(g.g_entryblock)) { + goto error; + } + if (optimize_cfg(&g, consts, const_cache) < 0) { + goto error; + } + res = cfg_to_instructions(&g); +error: + Py_XDECREF(const_cache); + cfg_builder_fini(&g); + return res; +} + + /* Retained for API compatibility. * Optimization is now done in optimize_cfg */ From webhook-mailer at python.org Wed Aug 24 08:07:30 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Wed, 24 Aug 2022 12:07:30 -0000 Subject: [Python-checkins] gh-96021: Explicitly close the IsolatedAsyncioTestCase runner in tests (GH-96135) Message-ID: <mailman.800.1661342852.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4de06e3cc0a58d73934f9a2759ad9cd2f6b031b0 commit: 4de06e3cc0a58d73934f9a2759ad9cd2f6b031b0 branch: main author: Serhiy Storchaka <storchaka at gmail.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-24T15:07:20+03:00 summary: gh-96021: Explicitly close the IsolatedAsyncioTestCase runner in tests (GH-96135) Tests for IsolatedAsyncioTestCase.debug() rely on the runner be closed in __del__. It makes tests depending on the GC an unreliable on other implementations. It is better to close the runner explicitly even if currently there is no a public API for this. files: M Lib/test/test_unittest/test_async_case.py diff --git a/Lib/test/test_unittest/test_async_case.py b/Lib/test/test_unittest/test_async_case.py index f59fc760d381..d7d4dc91316c 100644 --- a/Lib/test/test_unittest/test_async_case.py +++ b/Lib/test/test_unittest/test_async_case.py @@ -43,10 +43,10 @@ async def __aenter__(self): class TestAsyncCase(unittest.TestCase): maxDiff = None - def tearDown(self): + def setUp(self): # Ensure that IsolatedAsyncioTestCase instances are destroyed before # starting a new event loop - support.gc_collect() + self.addCleanup(support.gc_collect) def test_full_cycle(self): class Test(unittest.IsolatedAsyncioTestCase): @@ -151,6 +151,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -186,6 +187,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -221,6 +223,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -262,6 +265,7 @@ async def on_cleanup2(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -424,6 +428,7 @@ async def cleanup(self, fut): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: From webhook-mailer at python.org Wed Aug 24 09:21:22 2022 From: webhook-mailer at python.org (markshannon) Date: Wed, 24 Aug 2022 13:21:22 -0000 Subject: [Python-checkins] GH-96177: Move GIL and eval breaker code out of ceval.c into ceval_gil.c. (GH-96204) Message-ID: <mailman.801.1661347283.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a4a9f2e879c0c9572e0cecbc702dc1dd31f80221 commit: a4a9f2e879c0c9572e0cecbc702dc1dd31f80221 branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-24T14:21:01+01:00 summary: GH-96177: Move GIL and eval breaker code out of ceval.c into ceval_gil.c. (GH-96204) files: A Python/ceval_gil.c D Python/ceval_gil.h M Include/internal/pycore_ceval.h M Include/internal/pycore_pystate.h M Makefile.pre.in M PCbuild/_freeze_module.vcxproj M PCbuild/_freeze_module.vcxproj.filters M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters M Python/ceval.c M Tools/c-analyzer/cpython/_parser.py M Tools/gdb/libpython.py diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 1b999301938c..2fcdaad358b0 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -133,6 +133,9 @@ extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); extern PyObject* _Py_MakeCoro(PyFunctionObject *func); +extern int _Py_HandlePending(PyThreadState *tstate); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 51d119c23e73..3d6d400f74dd 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -85,13 +85,14 @@ _PyThreadState_GET(void) return _PyRuntimeState_GetThreadState(&_PyRuntime); } -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func); - static inline void _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate) { if (tstate == NULL) { - _Py_FatalError_TstateNULL(func); + _Py_FatalErrorFunc(func, + "the function must be called with the GIL held, " + "after Python initialization and before Python finalization, " + "but the GIL is released (the current Python thread state is NULL)"); } } diff --git a/Makefile.pre.in b/Makefile.pre.in index 414e6045b4d6..3491e91f43ab 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -388,6 +388,7 @@ PYTHON_OBJS= \ Python/getcopyright.o \ Python/getplatform.o \ Python/getversion.o \ + Python/ceval_gil.o \ Python/hamt.o \ Python/hashtable.o \ Python/import.o \ @@ -1419,8 +1420,7 @@ regen-opcode-targets: $(srcdir)/Python/opcode_targets.h.new $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new -Python/ceval.o: $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h \ - $(srcdir)/Python/condvar.h +Python/ceval.o: $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/condvar.h Python/frozen.o: $(FROZEN_FILES_OUT) diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 5821c3d9e4d8..4c0072971123 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -199,6 +199,7 @@ <ClCompile Include="..\Python\getopt.c" /> <ClCompile Include="..\Python\getplatform.c" /> <ClCompile Include="..\Python\getversion.c" /> + <ClCompile Include="..\Python\ceval_gil.c" /> <ClCompile Include="..\Python\hamt.c" /> <ClCompile Include="..\Python\hashtable.c" /> <ClCompile Include="..\Python\import.c" /> diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index b657f56e28f2..5c984999c0cd 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -184,6 +184,9 @@ <ClCompile Include="..\Python\getversion.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\Python\ceval_gil.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\Python\hamt.c"> <Filter>Source Files</Filter> </ClCompile> diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 3ff4be518724..45e5013e61f6 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -327,7 +327,6 @@ <ClInclude Include="..\Parser\pegen.h" /> <ClInclude Include="..\PC\errmap.h" /> <ClInclude Include="..\PC\pyconfig.h" /> - <ClInclude Include="..\Python\ceval_gil.h" /> <ClInclude Include="..\Python\condvar.h" /> <ClInclude Include="..\Python\importdl.h" /> <ClInclude Include="..\Python\stdlib_module_names.h" /> @@ -502,6 +501,7 @@ <ClCompile Include="..\Python\getopt.c" /> <ClCompile Include="..\Python\getplatform.c" /> <ClCompile Include="..\Python\getversion.c" /> + <ClCompile Include="..\Python\ceval_gil.c" /> <ClCompile Include="..\Python\hamt.c" /> <ClCompile Include="..\Python\hashtable.c" /> <ClCompile Include="..\Python\import.c" /> diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 64d248dfafd8..581ea6e3c58e 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -312,9 +312,6 @@ <ClInclude Include="..\Python\condvar.h"> <Filter>Python</Filter> </ClInclude> - <ClInclude Include="..\Python\ceval_gil.h"> - <Filter>Python</Filter> - </ClInclude> <ClInclude Include="..\Include\pyhash.h"> <Filter>Include</Filter> </ClInclude> @@ -1097,6 +1094,9 @@ <ClCompile Include="..\Python\getversion.c"> <Filter>Python</Filter> </ClCompile> + <ClCompile Include="..\Python\ceval_gil.c"> + <Filter>Python</Filter> + </ClCompile> <ClCompile Include="..\Python\hashtable.c"> <Filter>Modules</Filter> </ClCompile> diff --git a/Python/ceval.c b/Python/ceval.c index 7024addfe626..1ab104c18ed7 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -13,13 +13,11 @@ #include "pycore_ceval.h" // _PyEval_SignalAsyncExc() #include "pycore_code.h" #include "pycore_function.h" -#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_moduleobject.h" // PyModuleObject #include "pycore_opcode.h" // EXTRA_CASES #include "pycore_pyerrors.h" // _PyErr_Fetch() -#include "pycore_pylifecycle.h" // _PyErr_Print() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_range.h" // _PyRangeIterObject @@ -237,582 +235,9 @@ is_tstate_valid(PyThreadState *tstate) #endif -/* This can set eval_breaker to 0 even though gil_drop_request became - 1. We believe this is all right because the eval loop will release - the GIL eventually anyway. */ -static inline void -COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, - struct _ceval_runtime_state *ceval, - struct _ceval_state *ceval2) -{ - _Py_atomic_store_relaxed(&ceval2->eval_breaker, - _Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request) - | (_Py_atomic_load_relaxed_int32(&ceval->signals_pending) - && _Py_ThreadCanHandleSignals(interp)) - | (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do) - && _Py_ThreadCanHandlePendingCalls()) - | ceval2->pending.async_exc); -} - - -static inline void -SET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 1); - if (force) { - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); - } - else { - /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } -} - - -static inline void -UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 1; - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 0; - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - #ifdef HAVE_ERRNO_H #include <errno.h> #endif -#include "ceval_gil.h" - -void _Py_NO_RETURN -_Py_FatalError_TstateNULL(const char *func) -{ - _Py_FatalErrorFunc(func, - "the function must be called with the GIL held, " - "after Python initialization and before Python finalization, " - "but the GIL is released (the current Python thread state is NULL)"); -} - -int -_PyEval_ThreadsInitialized(_PyRuntimeState *runtime) -{ - return gil_created(&runtime->ceval.gil); -} - -int -PyEval_ThreadsInitialized(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - return _PyEval_ThreadsInitialized(runtime); -} - -PyStatus -_PyEval_InitGIL(PyThreadState *tstate) -{ - if (!_Py_IsMainInterpreter(tstate->interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return _PyStatus_OK(); - } - - struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; - assert(!gil_created(gil)); - - PyThread_init_thread(); - create_gil(gil); - - take_gil(tstate); - - assert(gil_created(gil)); - return _PyStatus_OK(); -} - -void -_PyEval_FiniGIL(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return; - } - - struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; - if (!gil_created(gil)) { - /* First Py_InitializeFromConfig() call: the GIL doesn't exist - yet: do nothing. */ - return; - } - - destroy_gil(gil); - assert(!gil_created(gil)); -} - -void -PyEval_InitThreads(void) -{ - /* Do nothing: kept for backward compatibility */ -} - -void -_PyEval_Fini(void) -{ -#ifdef Py_STATS - _Py_PrintSpecializationStats(1); -#endif -} - -void -PyEval_AcquireLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); -} - -void -PyEval_ReleaseLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - /* This function must succeed when the current thread state is NULL. - We therefore avoid PyThreadState_Get() which dumps a fatal error - in debug mode. */ - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -void -_PyEval_ReleaseLock(PyThreadState *tstate) -{ - struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -void -PyEval_AcquireThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - if (_PyThreadState_Swap(gilstate, tstate) != NULL) { - Py_FatalError("non-NULL old thread state"); - } -} - -void -PyEval_ReleaseThread(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - - _PyRuntimeState *runtime = tstate->interp->runtime; - PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); - if (new_tstate != tstate) { - Py_FatalError("wrong thread state"); - } - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -#ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to destroy all threads - which are not running in the child process, and clear internal locks - which might be held by those threads. */ -PyStatus -_PyEval_ReInitThreads(PyThreadState *tstate) -{ - _PyRuntimeState *runtime = tstate->interp->runtime; - - struct _gil_runtime_state *gil = &runtime->ceval.gil; - if (!gil_created(gil)) { - return _PyStatus_OK(); - } - recreate_gil(gil); - - take_gil(tstate); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - return _PyStatus_ERR("Can't reinitialize pending calls lock"); - } - - /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(runtime, tstate); - return _PyStatus_OK(); -} -#endif - -/* This function is used to signal that async exceptions are waiting to be - raised. */ - -void -_PyEval_SignalAsyncExc(PyInterpreterState *interp) -{ - SIGNAL_ASYNC_EXC(interp); -} - -PyThreadState * -PyEval_SaveThread(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); - _Py_EnsureTstateNotNULL(tstate); - - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - assert(gil_created(&ceval->gil)); - drop_gil(ceval, ceval2, tstate); - return tstate; -} - -void -PyEval_RestoreThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - _PyThreadState_Swap(gilstate, tstate); -} - - -/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX - signal handlers or Mac I/O completion routines) can schedule calls - to a function to be called synchronously. - The synchronous function is called with one void* argument. - It should return 0 for success or -1 for failure -- failure should - be accompanied by an exception. - - If registry succeeds, the registry function returns 0; if it fails - (e.g. due to too many pending calls) it returns -1 (without setting - an exception condition). - - Note that because registry may occur from within signal handlers, - or other asynchronous events, calling malloc() is unsafe! - - Any thread can schedule pending calls, but only the main thread - will execute them. - There is no facility to schedule calls to a particular thread, but - that should be easy to change, should that ever be required. In - that case, the static variables here should go into the python - threadstate. -*/ - -void -_PyEval_SignalReceived(PyInterpreterState *interp) -{ -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal - // handler which can run in a thread different than the Python thread, in - // which case _Py_ThreadCanHandleSignals() is wrong. Ignore - // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. - // - // The next eval_frame_handle_pending() call will call - // _Py_ThreadCanHandleSignals() to recompute eval_breaker. - int force = 1; -#else - int force = 0; -#endif - /* bpo-30703: Function called when the C signal handler of Python gets a - signal. We cannot queue a callback using _PyEval_AddPendingCall() since - that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(interp, force); -} - -/* Push one item onto the queue while holding the lock. */ -static int -_push_pending_call(struct _pending_calls *pending, - int (*func)(void *), void *arg) -{ - int i = pending->last; - int j = (i + 1) % NPENDINGCALLS; - if (j == pending->first) { - return -1; /* Queue full */ - } - pending->calls[i].func = func; - pending->calls[i].arg = arg; - pending->last = j; - return 0; -} - -/* Pop one item off the queue while holding the lock. */ -static void -_pop_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) -{ - int i = pending->first; - if (i == pending->last) { - return; /* Queue empty */ - } - - *func = pending->calls[i].func; - *arg = pending->calls[i].arg; - pending->first = (i + 1) % NPENDINGCALLS; -} - -/* This implementation is thread-safe. It allows - scheduling to be made from any thread, and even from an executing - callback. - */ - -int -_PyEval_AddPendingCall(PyInterpreterState *interp, - int (*func)(void *), void *arg) -{ - struct _pending_calls *pending = &interp->ceval.pending; - - /* Ensure that _PyEval_InitState() was called - and that _PyEval_FiniState() is not called yet. */ - assert(pending->lock != NULL); - - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); - PyThread_release_lock(pending->lock); - - /* signal main loop */ - SIGNAL_PENDING_CALLS(interp); - return result; -} - -int -Py_AddPendingCall(int (*func)(void *), void *arg) -{ - /* Best-effort to support subinterpreters and calls with the GIL released. - - First attempt _PyThreadState_GET() since it supports subinterpreters. - - If the GIL is released, _PyThreadState_GET() returns NULL . In this - case, use PyGILState_GetThisThreadState() which works even if the GIL - is released. - - Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters: - see bpo-10915 and bpo-15751. - - Py_AddPendingCall() doesn't require the caller to hold the GIL. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - tstate = PyGILState_GetThisThreadState(); - } - - PyInterpreterState *interp; - if (tstate != NULL) { - interp = tstate->interp; - } - else { - /* Last resort: use the main interpreter */ - interp = _PyInterpreterState_Main(); - } - return _PyEval_AddPendingCall(interp, func, arg); -} - -static int -handle_signals(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - if (!_Py_ThreadCanHandleSignals(tstate->interp)) { - return 0; - } - - UNSIGNAL_PENDING_SIGNALS(tstate->interp); - if (_PyErr_CheckSignalsTstate(tstate) < 0) { - /* On failure, re-schedule a call to handle_signals(). */ - SIGNAL_PENDING_SIGNALS(tstate->interp, 0); - return -1; - } - return 0; -} - -static int -make_pending_calls(PyInterpreterState *interp) -{ - /* only execute pending calls on main thread */ - if (!_Py_ThreadCanHandlePendingCalls()) { - return 0; - } - - /* don't perform recursive pending calls */ - static int busy = 0; - if (busy) { - return 0; - } - busy = 1; - - /* unsignal before starting to call callbacks, so that any callback - added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(interp); - int res = 0; - - /* perform a bounded number of calls, in case of recursion */ - struct _pending_calls *pending = &interp->ceval.pending; - for (int i=0; i<NPENDINGCALLS; i++) { - int (*func)(void *) = NULL; - void *arg = NULL; - - /* pop one item off the queue while holding the lock */ - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); - PyThread_release_lock(pending->lock); - - /* having released the lock, perform the callback */ - if (func == NULL) { - break; - } - res = func(arg); - if (res) { - goto error; - } - } - - busy = 0; - return res; - -error: - busy = 0; - SIGNAL_PENDING_CALLS(interp); - return res; -} - -void -_Py_FinishPendingCalls(PyThreadState *tstate) -{ - assert(PyGILState_Check()); - assert(is_tstate_valid(tstate)); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - - if (!_Py_atomic_load_relaxed_int32(&(pending->calls_to_do))) { - return; - } - - if (make_pending_calls(tstate->interp) < 0) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - PyErr_BadInternalCall(); - _PyErr_ChainExceptions(exc, val, tb); - _PyErr_Print(tstate); - } -} - -/* Py_MakePendingCalls() is a simple wrapper for the sake - of backward-compatibility. */ -int -Py_MakePendingCalls(void) -{ - assert(PyGILState_Check()); - - PyThreadState *tstate = _PyThreadState_GET(); - assert(is_tstate_valid(tstate)); - - /* Python signal handler doesn't really queue a callback: it only signals - that a signal was received, see _PyEval_SignalReceived(). */ - int res = handle_signals(tstate); - if (res != 0) { - return res; - } - - res = make_pending_calls(tstate->interp); - if (res != 0) { - return res; - } - - return 0; -} - -/* The interpreter's recursion limit */ - -void -_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) -{ - _gil_initialize(&ceval->gil); -} - -void -_PyEval_InitState(struct _ceval_state *ceval, PyThread_type_lock pending_lock) -{ - struct _pending_calls *pending = &ceval->pending; - assert(pending->lock == NULL); - - pending->lock = pending_lock; -} - -void -_PyEval_FiniState(struct _ceval_state *ceval) -{ - struct _pending_calls *pending = &ceval->pending; - if (pending->lock != NULL) { - PyThread_free_lock(pending->lock); - pending->lock = NULL; - } -} int Py_GetRecursionLimit(void) @@ -1182,71 +607,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) } -/* Handle signals, pending calls, GIL drop request - and asynchronous exception */ -static int -eval_frame_handle_pending(PyThreadState *tstate) -{ - _PyRuntimeState * const runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - - /* Pending signals */ - if (_Py_atomic_load_relaxed_int32(&ceval->signals_pending)) { - if (handle_signals(tstate) != 0) { - return -1; - } - } - - /* Pending calls */ - struct _ceval_state *ceval2 = &tstate->interp->ceval; - if (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do)) { - if (make_pending_calls(tstate->interp) != 0) { - return -1; - } - } - - /* GIL drop request */ - if (_Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request)) { - /* Give another thread a chance */ - if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { - Py_FatalError("tstate mix-up"); - } - drop_gil(ceval, ceval2, tstate); - - /* Other threads may run now */ - - take_gil(tstate); - - if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { - Py_FatalError("orphan tstate"); - } - } - - /* Check for asynchronous exception. */ - if (tstate->async_exc != NULL) { - PyObject *exc = tstate->async_exc; - tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(tstate->interp); - _PyErr_SetNone(tstate, exc); - Py_DECREF(exc); - return -1; - } - -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() can be called in a - // different thread than the Python thread, in which case - // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the - // current Python thread with the correct _Py_ThreadCanHandleSignals() - // value. It prevents to interrupt the eval loop at every instruction if - // the current Python thread cannot handle signals (if - // _Py_ThreadCanHandleSignals() is false). - COMPUTE_EVAL_BREAKER(tstate->interp, ceval, ceval2); -#endif - - return 0; -} - - /* Computed GOTOs, or the-optimization-commonly-but-improperly-known-as-"threaded code" using gcc's labels-as-values extension @@ -1750,7 +1110,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int * All loops should include a check of the eval breaker. * We also check on return from any builtin function. */ - if (eval_frame_handle_pending(tstate) != 0) { + if (_Py_HandlePending(tstate) != 0) { goto error; } DISPATCH(); diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c new file mode 100644 index 000000000000..a67908667667 --- /dev/null +++ b/Python/ceval_gil.c @@ -0,0 +1,986 @@ + +#include "Python.h" +#include "pycore_atomic.h" // _Py_atomic_int +#include "pycore_ceval.h" // _PyEval_SignalReceived() +#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pylifecycle.h" // _PyErr_Print() +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() + +/* + Notes about the implementation: + + - The GIL is just a boolean variable (locked) whose access is protected + by a mutex (gil_mutex), and whose changes are signalled by a condition + variable (gil_cond). gil_mutex is taken for short periods of time, + and therefore mostly uncontended. + + - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be + able to release the GIL on demand by another thread. A volatile boolean + variable (gil_drop_request) is used for that purpose, which is checked + at every turn of the eval loop. That variable is set after a wait of + `interval` microseconds on `gil_cond` has timed out. + + [Actually, another volatile boolean variable (eval_breaker) is used + which ORs several conditions into one. Volatile booleans are + sufficient as inter-thread signalling means since Python is run + on cache-coherent architectures only.] + + - A thread wanting to take the GIL will first let pass a given amount of + time (`interval` microseconds) before setting gil_drop_request. This + encourages a defined switching period, but doesn't enforce it since + opcodes can take an arbitrary time to execute. + + The `interval` value is available for the user to read and modify + using the Python API `sys.{get,set}switchinterval()`. + + - When a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. + It does so by waiting on a condition variable (switch_cond) until + the value of last_holder is changed to something else than its + own thread state pointer, indicating that another thread was able to + take the GIL. + + This is meant to prohibit the latency-adverse behaviour on multi-core + machines where one thread would speculatively release the GIL, but still + run and end up being the first to re-acquire it, making the "timeslices" + much longer than expected. + (Note: this mechanism is enabled with FORCE_SWITCHING above) +*/ + +// GH-89279: Force inlining by using a macro. +#if defined(_MSC_VER) && SIZEOF_INT == 4 +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) +#else +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) +#endif + +/* This can set eval_breaker to 0 even though gil_drop_request became + 1. We believe this is all right because the eval loop will release + the GIL eventually anyway. */ +static inline void +COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, + struct _ceval_runtime_state *ceval, + struct _ceval_state *ceval2) +{ + _Py_atomic_store_relaxed(&ceval2->eval_breaker, + _Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request) + | (_Py_atomic_load_relaxed_int32(&ceval->signals_pending) + && _Py_ThreadCanHandleSignals(interp)) + | (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do) + && _Py_ThreadCanHandlePendingCalls()) + | ceval2->pending.async_exc); +} + + +static inline void +SET_GIL_DROP_REQUEST(PyInterpreterState *interp) +{ + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); +} + + +static inline void +RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_PENDING_CALLS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval->signals_pending, 1); + if (force) { + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); + } + else { + /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + } +} + + +static inline void +UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval->signals_pending, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_ASYNC_EXC(PyInterpreterState *interp) +{ + struct _ceval_state *ceval2 = &interp->ceval; + ceval2->pending.async_exc = 1; + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); +} + + +static inline void +UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + ceval2->pending.async_exc = 0; + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + +#ifndef NDEBUG +/* Ensure that tstate is valid */ +static int +is_tstate_valid(PyThreadState *tstate) +{ + assert(!_PyMem_IsPtrFreed(tstate)); + assert(!_PyMem_IsPtrFreed(tstate->interp)); + return 1; +} +#endif + +/* + * Implementation of the Global Interpreter Lock (GIL). + */ + +#include <stdlib.h> +#include <errno.h> + +#include "pycore_atomic.h" + + +#include "condvar.h" + +#define MUTEX_INIT(mut) \ + if (PyMUTEX_INIT(&(mut))) { \ + Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; +#define MUTEX_FINI(mut) \ + if (PyMUTEX_FINI(&(mut))) { \ + Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; +#define MUTEX_LOCK(mut) \ + if (PyMUTEX_LOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; +#define MUTEX_UNLOCK(mut) \ + if (PyMUTEX_UNLOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; + +#define COND_INIT(cond) \ + if (PyCOND_INIT(&(cond))) { \ + Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; +#define COND_FINI(cond) \ + if (PyCOND_FINI(&(cond))) { \ + Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; +#define COND_SIGNAL(cond) \ + if (PyCOND_SIGNAL(&(cond))) { \ + Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; +#define COND_WAIT(cond, mut) \ + if (PyCOND_WAIT(&(cond), &(mut))) { \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ + { \ + int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ + if (r < 0) \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ + if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ + timeout_result = 1; \ + else \ + timeout_result = 0; \ + } \ + + +#define DEFAULT_INTERVAL 5000 + +static void _gil_initialize(struct _gil_runtime_state *gil) +{ + _Py_atomic_int uninitialized = {-1}; + gil->locked = uninitialized; + gil->interval = DEFAULT_INTERVAL; +} + +static int gil_created(struct _gil_runtime_state *gil) +{ + return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); +} + +static void create_gil(struct _gil_runtime_state *gil) +{ + MUTEX_INIT(gil->mutex); +#ifdef FORCE_SWITCHING + MUTEX_INIT(gil->switch_mutex); +#endif + COND_INIT(gil->cond); +#ifdef FORCE_SWITCHING + COND_INIT(gil->switch_cond); +#endif + _Py_atomic_store_relaxed(&gil->last_holder, 0); + _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); + _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); +} + +static void destroy_gil(struct _gil_runtime_state *gil) +{ + /* some pthread-like implementations tie the mutex to the cond + * and must have the cond destroyed first. + */ + COND_FINI(gil->cond); + MUTEX_FINI(gil->mutex); +#ifdef FORCE_SWITCHING + COND_FINI(gil->switch_cond); + MUTEX_FINI(gil->switch_mutex); +#endif + _Py_atomic_store_explicit(&gil->locked, -1, + _Py_memory_order_release); + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); +} + +#ifdef HAVE_FORK +static void recreate_gil(struct _gil_runtime_state *gil) +{ + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); + /* XXX should we destroy the old OS resources here? */ + create_gil(gil); +} +#endif + +static void +drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, + PyThreadState *tstate) +{ + struct _gil_runtime_state *gil = &ceval->gil; + if (!_Py_atomic_load_relaxed(&gil->locked)) { + Py_FatalError("drop_gil: GIL is not locked"); + } + + /* tstate is allowed to be NULL (early interpreter init) */ + if (tstate != NULL) { + /* Sub-interpreter support: threads might have been switched + under our feet using PyThreadState_Swap(). Fix the GIL last + holder variable so that our heuristics work. */ + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + } + + MUTEX_LOCK(gil->mutex); + _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); + _Py_atomic_store_relaxed(&gil->locked, 0); + COND_SIGNAL(gil->cond); + MUTEX_UNLOCK(gil->mutex); + +#ifdef FORCE_SWITCHING + if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { + MUTEX_LOCK(gil->switch_mutex); + /* Not switched yet => wait */ + if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) + { + assert(is_tstate_valid(tstate)); + RESET_GIL_DROP_REQUEST(tstate->interp); + /* NOTE: if COND_WAIT does not atomically start waiting when + releasing the mutex, another thread can run through, take + the GIL and drop it again, and reset the condition + before we even had a chance to wait for it. */ + COND_WAIT(gil->switch_cond, gil->switch_mutex); + } + MUTEX_UNLOCK(gil->switch_mutex); + } +#endif +} + + +/* Check if a Python thread must exit immediately, rather than taking the GIL + if Py_Finalize() has been called. + + When this function is called by a daemon thread after Py_Finalize() has been + called, the GIL does no longer exist. + + tstate must be non-NULL. */ +static inline int +tstate_must_exit(PyThreadState *tstate) +{ + /* bpo-39877: Access _PyRuntime directly rather than using + tstate->interp->runtime to support calls from Python daemon threads. + After Py_Finalize() has been called, tstate can be a dangling pointer: + point to PyThreadState freed memory. */ + PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); + return (finalizing != NULL && finalizing != tstate); +} + + +/* Take the GIL. + + The function saves errno at entry and restores its value at exit. + + tstate must be non-NULL. */ +static void +take_gil(PyThreadState *tstate) +{ + int err = errno; + + assert(tstate != NULL); + + if (tstate_must_exit(tstate)) { + /* bpo-39877: If Py_Finalize() has been called and tstate is not the + thread which called Py_Finalize(), exit immediately the thread. + + This code path can be reached by a daemon thread after Py_Finalize() + completes. In this case, tstate is a dangling pointer: points to + PyThreadState freed memory. */ + PyThread_exit_thread(); + } + + assert(is_tstate_valid(tstate)); + PyInterpreterState *interp = tstate->interp; + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + struct _gil_runtime_state *gil = &ceval->gil; + + /* Check that _PyEval_InitThreads() was called to create the lock */ + assert(gil_created(gil)); + + MUTEX_LOCK(gil->mutex); + + if (!_Py_atomic_load_relaxed(&gil->locked)) { + goto _ready; + } + + while (_Py_atomic_load_relaxed(&gil->locked)) { + unsigned long saved_switchnum = gil->switch_number; + + unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); + int timed_out = 0; + COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); + + /* If we timed out and no switch occurred in the meantime, it is time + to ask the GIL-holding thread to drop it. */ + if (timed_out && + _Py_atomic_load_relaxed(&gil->locked) && + gil->switch_number == saved_switchnum) + { + if (tstate_must_exit(tstate)) { + MUTEX_UNLOCK(gil->mutex); + PyThread_exit_thread(); + } + assert(is_tstate_valid(tstate)); + + SET_GIL_DROP_REQUEST(interp); + } + } + +_ready: +#ifdef FORCE_SWITCHING + /* This mutex must be taken before modifying gil->last_holder: + see drop_gil(). */ + MUTEX_LOCK(gil->switch_mutex); +#endif + /* We now hold the GIL */ + _Py_atomic_store_relaxed(&gil->locked, 1); + _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); + + if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + ++gil->switch_number; + } + +#ifdef FORCE_SWITCHING + COND_SIGNAL(gil->switch_cond); + MUTEX_UNLOCK(gil->switch_mutex); +#endif + + if (tstate_must_exit(tstate)) { + /* bpo-36475: If Py_Finalize() has been called and tstate is not + the thread which called Py_Finalize(), exit immediately the + thread. + + This code path can be reached by a daemon thread which was waiting + in take_gil() while the main thread called + wait_for_thread_shutdown() from Py_Finalize(). */ + MUTEX_UNLOCK(gil->mutex); + drop_gil(ceval, ceval2, tstate); + PyThread_exit_thread(); + } + assert(is_tstate_valid(tstate)); + + if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { + RESET_GIL_DROP_REQUEST(interp); + } + else { + /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there + is a pending signal: signal received by another thread which cannot + handle signals. + + Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + } + + /* Don't access tstate if the thread must exit */ + if (tstate->async_exc != NULL) { + _PyEval_SignalAsyncExc(tstate->interp); + } + + MUTEX_UNLOCK(gil->mutex); + + errno = err; +} + +void _PyEval_SetSwitchInterval(unsigned long microseconds) +{ + struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; + gil->interval = microseconds; +} + +unsigned long _PyEval_GetSwitchInterval() +{ + struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; + return gil->interval; +} + + +int +_PyEval_ThreadsInitialized(_PyRuntimeState *runtime) +{ + return gil_created(&runtime->ceval.gil); +} + +int +PyEval_ThreadsInitialized(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + return _PyEval_ThreadsInitialized(runtime); +} + +PyStatus +_PyEval_InitGIL(PyThreadState *tstate) +{ + if (!_Py_IsMainInterpreter(tstate->interp)) { + /* Currently, the GIL is shared by all interpreters, + and only the main interpreter is responsible to create + and destroy it. */ + return _PyStatus_OK(); + } + + struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; + assert(!gil_created(gil)); + + PyThread_init_thread(); + create_gil(gil); + + take_gil(tstate); + + assert(gil_created(gil)); + return _PyStatus_OK(); +} + +void +_PyEval_FiniGIL(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + /* Currently, the GIL is shared by all interpreters, + and only the main interpreter is responsible to create + and destroy it. */ + return; + } + + struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; + if (!gil_created(gil)) { + /* First Py_InitializeFromConfig() call: the GIL doesn't exist + yet: do nothing. */ + return; + } + + destroy_gil(gil); + assert(!gil_created(gil)); +} + +void +PyEval_InitThreads(void) +{ + /* Do nothing: kept for backward compatibility */ +} + +void +_PyEval_Fini(void) +{ +#ifdef Py_STATS + _Py_PrintSpecializationStats(1); +#endif +} +void +PyEval_AcquireLock(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); +} + +void +PyEval_ReleaseLock(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + /* This function must succeed when the current thread state is NULL. + We therefore avoid PyThreadState_Get() which dumps a fatal error + in debug mode. */ + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + drop_gil(ceval, ceval2, tstate); +} + +void +_PyEval_ReleaseLock(PyThreadState *tstate) +{ + struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + drop_gil(ceval, ceval2, tstate); +} + +void +PyEval_AcquireThread(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); + + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; + if (_PyThreadState_Swap(gilstate, tstate) != NULL) { + Py_FatalError("non-NULL old thread state"); + } +} + +void +PyEval_ReleaseThread(PyThreadState *tstate) +{ + assert(is_tstate_valid(tstate)); + + _PyRuntimeState *runtime = tstate->interp->runtime; + PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); + if (new_tstate != tstate) { + Py_FatalError("wrong thread state"); + } + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + drop_gil(ceval, ceval2, tstate); +} + +#ifdef HAVE_FORK +/* This function is called from PyOS_AfterFork_Child to destroy all threads + which are not running in the child process, and clear internal locks + which might be held by those threads. */ +PyStatus +_PyEval_ReInitThreads(PyThreadState *tstate) +{ + _PyRuntimeState *runtime = tstate->interp->runtime; + + struct _gil_runtime_state *gil = &runtime->ceval.gil; + if (!gil_created(gil)) { + return _PyStatus_OK(); + } + recreate_gil(gil); + + take_gil(tstate); + + struct _pending_calls *pending = &tstate->interp->ceval.pending; + if (_PyThread_at_fork_reinit(&pending->lock) < 0) { + return _PyStatus_ERR("Can't reinitialize pending calls lock"); + } + + /* Destroy all threads except the current one */ + _PyThreadState_DeleteExcept(runtime, tstate); + return _PyStatus_OK(); +} +#endif + +/* This function is used to signal that async exceptions are waiting to be + raised. */ + +void +_PyEval_SignalAsyncExc(PyInterpreterState *interp) +{ + SIGNAL_ASYNC_EXC(interp); +} + +PyThreadState * +PyEval_SaveThread(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); + _Py_EnsureTstateNotNULL(tstate); + + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + assert(gil_created(&ceval->gil)); + drop_gil(ceval, ceval2, tstate); + return tstate; +} + +void +PyEval_RestoreThread(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); + + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; + _PyThreadState_Swap(gilstate, tstate); +} + + +/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX + signal handlers or Mac I/O completion routines) can schedule calls + to a function to be called synchronously. + The synchronous function is called with one void* argument. + It should return 0 for success or -1 for failure -- failure should + be accompanied by an exception. + + If registry succeeds, the registry function returns 0; if it fails + (e.g. due to too many pending calls) it returns -1 (without setting + an exception condition). + + Note that because registry may occur from within signal handlers, + or other asynchronous events, calling malloc() is unsafe! + + Any thread can schedule pending calls, but only the main thread + will execute them. + There is no facility to schedule calls to a particular thread, but + that should be easy to change, should that ever be required. In + that case, the static variables here should go into the python + threadstate. +*/ + +void +_PyEval_SignalReceived(PyInterpreterState *interp) +{ +#ifdef MS_WINDOWS + // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal + // handler which can run in a thread different than the Python thread, in + // which case _Py_ThreadCanHandleSignals() is wrong. Ignore + // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. + // + // The next eval_frame_handle_pending() call will call + // _Py_ThreadCanHandleSignals() to recompute eval_breaker. + int force = 1; +#else + int force = 0; +#endif + /* bpo-30703: Function called when the C signal handler of Python gets a + signal. We cannot queue a callback using _PyEval_AddPendingCall() since + that function is not async-signal-safe. */ + SIGNAL_PENDING_SIGNALS(interp, force); +} + +/* Push one item onto the queue while holding the lock. */ +static int +_push_pending_call(struct _pending_calls *pending, + int (*func)(void *), void *arg) +{ + int i = pending->last; + int j = (i + 1) % NPENDINGCALLS; + if (j == pending->first) { + return -1; /* Queue full */ + } + pending->calls[i].func = func; + pending->calls[i].arg = arg; + pending->last = j; + return 0; +} + +/* Pop one item off the queue while holding the lock. */ +static void +_pop_pending_call(struct _pending_calls *pending, + int (**func)(void *), void **arg) +{ + int i = pending->first; + if (i == pending->last) { + return; /* Queue empty */ + } + + *func = pending->calls[i].func; + *arg = pending->calls[i].arg; + pending->first = (i + 1) % NPENDINGCALLS; +} + +/* This implementation is thread-safe. It allows + scheduling to be made from any thread, and even from an executing + callback. + */ + +int +_PyEval_AddPendingCall(PyInterpreterState *interp, + int (*func)(void *), void *arg) +{ + struct _pending_calls *pending = &interp->ceval.pending; + /* Ensure that _PyEval_InitState() was called + and that _PyEval_FiniState() is not called yet. */ + assert(pending->lock != NULL); + + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + int result = _push_pending_call(pending, func, arg); + PyThread_release_lock(pending->lock); + + /* signal main loop */ + SIGNAL_PENDING_CALLS(interp); + return result; +} + +int +Py_AddPendingCall(int (*func)(void *), void *arg) +{ + /* Best-effort to support subinterpreters and calls with the GIL released. + + First attempt _PyThreadState_GET() since it supports subinterpreters. + + If the GIL is released, _PyThreadState_GET() returns NULL . In this + case, use PyGILState_GetThisThreadState() which works even if the GIL + is released. + + Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters: + see bpo-10915 and bpo-15751. + + Py_AddPendingCall() doesn't require the caller to hold the GIL. */ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + tstate = PyGILState_GetThisThreadState(); + } + + PyInterpreterState *interp; + if (tstate != NULL) { + interp = tstate->interp; + } + else { + /* Last resort: use the main interpreter */ + interp = _PyInterpreterState_Main(); + } + return _PyEval_AddPendingCall(interp, func, arg); +} + +static int +handle_signals(PyThreadState *tstate) +{ + assert(is_tstate_valid(tstate)); + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { + return 0; + } + + UNSIGNAL_PENDING_SIGNALS(tstate->interp); + if (_PyErr_CheckSignalsTstate(tstate) < 0) { + /* On failure, re-schedule a call to handle_signals(). */ + SIGNAL_PENDING_SIGNALS(tstate->interp, 0); + return -1; + } + return 0; +} + +static int +make_pending_calls(PyInterpreterState *interp) +{ + /* only execute pending calls on main thread */ + if (!_Py_ThreadCanHandlePendingCalls()) { + return 0; + } + + /* don't perform recursive pending calls */ + static int busy = 0; + if (busy) { + return 0; + } + busy = 1; + + /* unsignal before starting to call callbacks, so that any callback + added in-between re-signals */ + UNSIGNAL_PENDING_CALLS(interp); + int res = 0; + + /* perform a bounded number of calls, in case of recursion */ + struct _pending_calls *pending = &interp->ceval.pending; + for (int i=0; i<NPENDINGCALLS; i++) { + int (*func)(void *) = NULL; + void *arg = NULL; + + /* pop one item off the queue while holding the lock */ + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + _pop_pending_call(pending, &func, &arg); + PyThread_release_lock(pending->lock); + + /* having released the lock, perform the callback */ + if (func == NULL) { + break; + } + res = func(arg); + if (res) { + goto error; + } + } + + busy = 0; + return res; + +error: + busy = 0; + SIGNAL_PENDING_CALLS(interp); + return res; +} + +void +_Py_FinishPendingCalls(PyThreadState *tstate) +{ + assert(PyGILState_Check()); + assert(is_tstate_valid(tstate)); + + struct _pending_calls *pending = &tstate->interp->ceval.pending; + + if (!_Py_atomic_load_relaxed_int32(&(pending->calls_to_do))) { + return; + } + + if (make_pending_calls(tstate->interp) < 0) { + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + PyErr_BadInternalCall(); + _PyErr_ChainExceptions(exc, val, tb); + _PyErr_Print(tstate); + } +} + +/* Py_MakePendingCalls() is a simple wrapper for the sake + of backward-compatibility. */ +int +Py_MakePendingCalls(void) +{ + assert(PyGILState_Check()); + + PyThreadState *tstate = _PyThreadState_GET(); + assert(is_tstate_valid(tstate)); + + /* Python signal handler doesn't really queue a callback: it only signals + that a signal was received, see _PyEval_SignalReceived(). */ + int res = handle_signals(tstate); + if (res != 0) { + return res; + } + + res = make_pending_calls(tstate->interp); + if (res != 0) { + return res; + } + + return 0; +} + +/* The interpreter's recursion limit */ + +void +_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) +{ + _gil_initialize(&ceval->gil); +} + +void +_PyEval_InitState(struct _ceval_state *ceval, PyThread_type_lock pending_lock) +{ + struct _pending_calls *pending = &ceval->pending; + assert(pending->lock == NULL); + + pending->lock = pending_lock; +} + +void +_PyEval_FiniState(struct _ceval_state *ceval) +{ + struct _pending_calls *pending = &ceval->pending; + if (pending->lock != NULL) { + PyThread_free_lock(pending->lock); + pending->lock = NULL; + } +} + +/* Handle signals, pending calls, GIL drop request + and asynchronous exception */ +int +_Py_HandlePending(PyThreadState *tstate) +{ + _PyRuntimeState * const runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + + /* Pending signals */ + if (_Py_atomic_load_relaxed_int32(&ceval->signals_pending)) { + if (handle_signals(tstate) != 0) { + return -1; + } + } + + /* Pending calls */ + struct _ceval_state *ceval2 = &tstate->interp->ceval; + if (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do)) { + if (make_pending_calls(tstate->interp) != 0) { + return -1; + } + } + + /* GIL drop request */ + if (_Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request)) { + /* Give another thread a chance */ + if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { + Py_FatalError("tstate mix-up"); + } + drop_gil(ceval, ceval2, tstate); + + /* Other threads may run now */ + + take_gil(tstate); + + if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { + Py_FatalError("orphan tstate"); + } + } + + /* Check for asynchronous exception. */ + if (tstate->async_exc != NULL) { + PyObject *exc = tstate->async_exc; + tstate->async_exc = NULL; + UNSIGNAL_ASYNC_EXC(tstate->interp); + _PyErr_SetNone(tstate, exc); + Py_DECREF(exc); + return -1; + } + +#ifdef MS_WINDOWS + // bpo-42296: On Windows, _PyEval_SignalReceived() can be called in a + // different thread than the Python thread, in which case + // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the + // current Python thread with the correct _Py_ThreadCanHandleSignals() + // value. It prevents to interrupt the eval loop at every instruction if + // the current Python thread cannot handle signals (if + // _Py_ThreadCanHandleSignals() is false). + COMPUTE_EVAL_BREAKER(tstate->interp, ceval, ceval2); +#endif + + return 0; +} + diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h deleted file mode 100644 index 4c71edd682bf..000000000000 --- a/Python/ceval_gil.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Implementation of the Global Interpreter Lock (GIL). - */ - -#include <stdlib.h> -#include <errno.h> - -#include "pycore_atomic.h" - - -/* - Notes about the implementation: - - - The GIL is just a boolean variable (locked) whose access is protected - by a mutex (gil_mutex), and whose changes are signalled by a condition - variable (gil_cond). gil_mutex is taken for short periods of time, - and therefore mostly uncontended. - - - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be - able to release the GIL on demand by another thread. A volatile boolean - variable (gil_drop_request) is used for that purpose, which is checked - at every turn of the eval loop. That variable is set after a wait of - `interval` microseconds on `gil_cond` has timed out. - - [Actually, another volatile boolean variable (eval_breaker) is used - which ORs several conditions into one. Volatile booleans are - sufficient as inter-thread signalling means since Python is run - on cache-coherent architectures only.] - - - A thread wanting to take the GIL will first let pass a given amount of - time (`interval` microseconds) before setting gil_drop_request. This - encourages a defined switching period, but doesn't enforce it since - opcodes can take an arbitrary time to execute. - - The `interval` value is available for the user to read and modify - using the Python API `sys.{get,set}switchinterval()`. - - - When a thread releases the GIL and gil_drop_request is set, that thread - ensures that another GIL-awaiting thread gets scheduled. - It does so by waiting on a condition variable (switch_cond) until - the value of last_holder is changed to something else than its - own thread state pointer, indicating that another thread was able to - take the GIL. - - This is meant to prohibit the latency-adverse behaviour on multi-core - machines where one thread would speculatively release the GIL, but still - run and end up being the first to re-acquire it, making the "timeslices" - much longer than expected. - (Note: this mechanism is enabled with FORCE_SWITCHING above) -*/ - -#include "condvar.h" - -#define MUTEX_INIT(mut) \ - if (PyMUTEX_INIT(&(mut))) { \ - Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; -#define MUTEX_FINI(mut) \ - if (PyMUTEX_FINI(&(mut))) { \ - Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; -#define MUTEX_LOCK(mut) \ - if (PyMUTEX_LOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; -#define MUTEX_UNLOCK(mut) \ - if (PyMUTEX_UNLOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; - -#define COND_INIT(cond) \ - if (PyCOND_INIT(&(cond))) { \ - Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; -#define COND_FINI(cond) \ - if (PyCOND_FINI(&(cond))) { \ - Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; -#define COND_SIGNAL(cond) \ - if (PyCOND_SIGNAL(&(cond))) { \ - Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; -#define COND_WAIT(cond, mut) \ - if (PyCOND_WAIT(&(cond), &(mut))) { \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; -#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ - { \ - int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ - if (r < 0) \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ - if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ - timeout_result = 1; \ - else \ - timeout_result = 0; \ - } \ - - -#define DEFAULT_INTERVAL 5000 - -static void _gil_initialize(struct _gil_runtime_state *gil) -{ - _Py_atomic_int uninitialized = {-1}; - gil->locked = uninitialized; - gil->interval = DEFAULT_INTERVAL; -} - -static int gil_created(struct _gil_runtime_state *gil) -{ - return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); -} - -static void create_gil(struct _gil_runtime_state *gil) -{ - MUTEX_INIT(gil->mutex); -#ifdef FORCE_SWITCHING - MUTEX_INIT(gil->switch_mutex); -#endif - COND_INIT(gil->cond); -#ifdef FORCE_SWITCHING - COND_INIT(gil->switch_cond); -#endif - _Py_atomic_store_relaxed(&gil->last_holder, 0); - _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); - _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); -} - -static void destroy_gil(struct _gil_runtime_state *gil) -{ - /* some pthread-like implementations tie the mutex to the cond - * and must have the cond destroyed first. - */ - COND_FINI(gil->cond); - MUTEX_FINI(gil->mutex); -#ifdef FORCE_SWITCHING - COND_FINI(gil->switch_cond); - MUTEX_FINI(gil->switch_mutex); -#endif - _Py_atomic_store_explicit(&gil->locked, -1, - _Py_memory_order_release); - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); -} - -#ifdef HAVE_FORK -static void recreate_gil(struct _gil_runtime_state *gil) -{ - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); - /* XXX should we destroy the old OS resources here? */ - create_gil(gil); -} -#endif - -static void -drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, - PyThreadState *tstate) -{ - struct _gil_runtime_state *gil = &ceval->gil; - if (!_Py_atomic_load_relaxed(&gil->locked)) { - Py_FatalError("drop_gil: GIL is not locked"); - } - - /* tstate is allowed to be NULL (early interpreter init) */ - if (tstate != NULL) { - /* Sub-interpreter support: threads might have been switched - under our feet using PyThreadState_Swap(). Fix the GIL last - holder variable so that our heuristics work. */ - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - } - - MUTEX_LOCK(gil->mutex); - _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); - _Py_atomic_store_relaxed(&gil->locked, 0); - COND_SIGNAL(gil->cond); - MUTEX_UNLOCK(gil->mutex); - -#ifdef FORCE_SWITCHING - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { - MUTEX_LOCK(gil->switch_mutex); - /* Not switched yet => wait */ - if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) - { - assert(is_tstate_valid(tstate)); - RESET_GIL_DROP_REQUEST(tstate->interp); - /* NOTE: if COND_WAIT does not atomically start waiting when - releasing the mutex, another thread can run through, take - the GIL and drop it again, and reset the condition - before we even had a chance to wait for it. */ - COND_WAIT(gil->switch_cond, gil->switch_mutex); - } - MUTEX_UNLOCK(gil->switch_mutex); - } -#endif -} - - -/* Check if a Python thread must exit immediately, rather than taking the GIL - if Py_Finalize() has been called. - - When this function is called by a daemon thread after Py_Finalize() has been - called, the GIL does no longer exist. - - tstate must be non-NULL. */ -static inline int -tstate_must_exit(PyThreadState *tstate) -{ - /* bpo-39877: Access _PyRuntime directly rather than using - tstate->interp->runtime to support calls from Python daemon threads. - After Py_Finalize() has been called, tstate can be a dangling pointer: - point to PyThreadState freed memory. */ - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); - return (finalizing != NULL && finalizing != tstate); -} - - -/* Take the GIL. - - The function saves errno at entry and restores its value at exit. - - tstate must be non-NULL. */ -static void -take_gil(PyThreadState *tstate) -{ - int err = errno; - - assert(tstate != NULL); - - if (tstate_must_exit(tstate)) { - /* bpo-39877: If Py_Finalize() has been called and tstate is not the - thread which called Py_Finalize(), exit immediately the thread. - - This code path can be reached by a daemon thread after Py_Finalize() - completes. In this case, tstate is a dangling pointer: points to - PyThreadState freed memory. */ - PyThread_exit_thread(); - } - - assert(is_tstate_valid(tstate)); - PyInterpreterState *interp = tstate->interp; - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - struct _gil_runtime_state *gil = &ceval->gil; - - /* Check that _PyEval_InitThreads() was called to create the lock */ - assert(gil_created(gil)); - - MUTEX_LOCK(gil->mutex); - - if (!_Py_atomic_load_relaxed(&gil->locked)) { - goto _ready; - } - - while (_Py_atomic_load_relaxed(&gil->locked)) { - unsigned long saved_switchnum = gil->switch_number; - - unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); - int timed_out = 0; - COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); - - /* If we timed out and no switch occurred in the meantime, it is time - to ask the GIL-holding thread to drop it. */ - if (timed_out && - _Py_atomic_load_relaxed(&gil->locked) && - gil->switch_number == saved_switchnum) - { - if (tstate_must_exit(tstate)) { - MUTEX_UNLOCK(gil->mutex); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - SET_GIL_DROP_REQUEST(interp); - } - } - -_ready: -#ifdef FORCE_SWITCHING - /* This mutex must be taken before modifying gil->last_holder: - see drop_gil(). */ - MUTEX_LOCK(gil->switch_mutex); -#endif - /* We now hold the GIL */ - _Py_atomic_store_relaxed(&gil->locked, 1); - _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); - - if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - ++gil->switch_number; - } - -#ifdef FORCE_SWITCHING - COND_SIGNAL(gil->switch_cond); - MUTEX_UNLOCK(gil->switch_mutex); -#endif - - if (tstate_must_exit(tstate)) { - /* bpo-36475: If Py_Finalize() has been called and tstate is not - the thread which called Py_Finalize(), exit immediately the - thread. - - This code path can be reached by a daemon thread which was waiting - in take_gil() while the main thread called - wait_for_thread_shutdown() from Py_Finalize(). */ - MUTEX_UNLOCK(gil->mutex); - drop_gil(ceval, ceval2, tstate); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(interp); - } - else { - /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there - is a pending signal: signal received by another thread which cannot - handle signals. - - Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } - - /* Don't access tstate if the thread must exit */ - if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(tstate->interp); - } - - MUTEX_UNLOCK(gil->mutex); - - errno = err; -} - -void _PyEval_SetSwitchInterval(unsigned long microseconds) -{ - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; - gil->interval = microseconds; -} - -unsigned long _PyEval_GetSwitchInterval() -{ - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; - return gil->interval; -} diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index 992d2e5a7c3d..dc8423bfcbad 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -174,7 +174,6 @@ def clean_lines(text): Objects/stringlib/unicode_format.h Py_BUILD_CORE 1 Parser/string_parser.h Py_BUILD_CORE 1 Parser/pegen.h Py_BUILD_CORE 1 -Python/ceval_gil.h Py_BUILD_CORE 1 Python/condvar.h Py_BUILD_CORE 1 Modules/_json.c Py_BUILD_CORE_BUILTIN 1 diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 899cb6c7dea0..303409cb0077 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1752,7 +1752,7 @@ def is_other_python_frame(self): def is_waiting_for_gil(self): '''Is this frame waiting on the GIL?''' - # This assumes the _POSIX_THREADS version of Python/ceval_gil.h: + # This assumes the _POSIX_THREADS version of Python/ceval_gil.c: name = self._gdbframe.name() if name: return (name == 'take_gil') From webhook-mailer at python.org Wed Aug 24 10:04:11 2022 From: webhook-mailer at python.org (corona10) Date: Wed, 24 Aug 2022 14:04:11 -0000 Subject: [Python-checkins] gh-96197: Define the behavior of breakpoint if sys.breakpointhook is lost (gh-96231) Message-ID: <mailman.802.1661349852.3313.python-checkins@python.org> https://github.com/python/cpython/commit/09563a764ebc54f98087c128419f46cf0822b4b7 commit: 09563a764ebc54f98087c128419f46cf0822b4b7 branch: main author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-24T23:03:36+09:00 summary: gh-96197: Define the behavior of breakpoint if sys.breakpointhook is lost (gh-96231) files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index da7de18722f..fbde9129274 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -164,6 +164,8 @@ are always available. They are listed here in alphabetical order. :func:`sys.breakpointhook` can be set to some other function and :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. + If :func:`sys.breakpointhook` is not available to be called, this function will + raise :exc:`RuntimeError`. .. audit-event:: builtins.breakpoint breakpointhook breakpoint From webhook-mailer at python.org Wed Aug 24 10:20:32 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 24 Aug 2022 14:20:32 -0000 Subject: [Python-checkins] gh-96197: Define the behavior of breakpoint if sys.breakpointhook is lost (gh-96231) Message-ID: <mailman.803.1661350834.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bf2728b9f1a9873f22382c72f21adb98046f613c commit: bf2728b9f1a9873f22382c72f21adb98046f613c branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T07:20:22-07:00 summary: gh-96197: Define the behavior of breakpoint if sys.breakpointhook is lost (gh-96231) (cherry picked from commit 09563a764ebc54f98087c128419f46cf0822b4b7) Co-authored-by: Dong-hee Na <donghee.na at python.org> files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index da7de18722f..fbde9129274 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -164,6 +164,8 @@ are always available. They are listed here in alphabetical order. :func:`sys.breakpointhook` can be set to some other function and :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. + If :func:`sys.breakpointhook` is not available to be called, this function will + raise :exc:`RuntimeError`. .. audit-event:: builtins.breakpoint breakpointhook breakpoint From webhook-mailer at python.org Wed Aug 24 10:20:44 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 24 Aug 2022 14:20:44 -0000 Subject: [Python-checkins] gh-96197: Define the behavior of breakpoint if sys.breakpointhook is lost (gh-96231) Message-ID: <mailman.804.1661350845.3313.python-checkins@python.org> https://github.com/python/cpython/commit/83ff85bc593fb34a2bd81fd00656d6dc0fee06fa commit: 83ff85bc593fb34a2bd81fd00656d6dc0fee06fa branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T07:20:38-07:00 summary: gh-96197: Define the behavior of breakpoint if sys.breakpointhook is lost (gh-96231) (cherry picked from commit 09563a764ebc54f98087c128419f46cf0822b4b7) Co-authored-by: Dong-hee Na <donghee.na at python.org> files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index d22cc2812dc..ba5d2cf8033 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -164,6 +164,8 @@ are always available. They are listed here in alphabetical order. :func:`sys.breakpointhook` can be set to some other function and :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. + If :func:`sys.breakpointhook` is not available to be called, this function will + raise :exc:`RuntimeError`. .. audit-event:: builtins.breakpoint breakpointhook breakpoint From webhook-mailer at python.org Wed Aug 24 11:47:26 2022 From: webhook-mailer at python.org (encukou) Date: Wed, 24 Aug 2022 15:47:26 -0000 Subject: [Python-checkins] GH-96179: Fix misleading example on the bisect documentation (GH-96228) Message-ID: <mailman.805.1661356048.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4317b25a2323ae4be04574e45de0e335c571c463 commit: 4317b25a2323ae4be04574e45de0e335c571c463 branch: main author: prego <pedropregueiro at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-24T17:47:13+02:00 summary: GH-96179: Fix misleading example on the bisect documentation (GH-96228) The `movies[bisect(movies, 1960, key=by_year)]` will actually return only movies **after** 1960. files: M Doc/library/bisect.rst M Misc/ACKS diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 76045ea511a..7856bf67a7b 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -216,7 +216,7 @@ records in a table:: ... Movie('Aliens', 1986, 'Scott') ... ] - >>> # Find the first movie released on or after 1960 + >>> # Find the first movie released after 1960 >>> by_year = attrgetter('released') >>> movies.sort(key=by_year) >>> movies[bisect(movies, 1960, key=by_year)] diff --git a/Misc/ACKS b/Misc/ACKS index 16a482e40a5..daa01c1a0f1 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1419,6 +1419,7 @@ John Popplewell Matheus Vieira Portela Davin Potts Guillaume Pratte +Pedro Pregueiro Florian Preinstorfer Alex Preng?re Amrit Prem From webhook-mailer at python.org Wed Aug 24 11:54:25 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 24 Aug 2022 15:54:25 -0000 Subject: [Python-checkins] GH-96179: Fix misleading example on the bisect documentation (GH-96228) Message-ID: <mailman.806.1661356466.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d02e8fbc5a4a9f43ceaacb32dee84f8f661a12d2 commit: d02e8fbc5a4a9f43ceaacb32dee84f8f661a12d2 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T08:54:15-07:00 summary: GH-96179: Fix misleading example on the bisect documentation (GH-96228) The `movies[bisect(movies, 1960, key=by_year)]` will actually return only movies **after** 1960. (cherry picked from commit 4317b25a2323ae4be04574e45de0e335c571c463) Co-authored-by: prego <pedropregueiro at gmail.com> files: M Doc/library/bisect.rst M Misc/ACKS diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 513675d3685..c2927c1ebd0 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -216,7 +216,7 @@ records in a table:: ... Movie('Aliens', 1986, 'Scott') ... ] - >>> # Find the first movie released on or after 1960 + >>> # Find the first movie released after 1960 >>> by_year = attrgetter('released') >>> movies.sort(key=by_year) >>> movies[bisect(movies, 1960, key=by_year)] diff --git a/Misc/ACKS b/Misc/ACKS index 4beb4fd6b3d..6e53d5a7cc4 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1415,6 +1415,7 @@ John Popplewell Matheus Vieira Portela Davin Potts Guillaume Pratte +Pedro Pregueiro Florian Preinstorfer Alex Preng?re Amrit Prem From webhook-mailer at python.org Wed Aug 24 11:55:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 24 Aug 2022 15:55:54 -0000 Subject: [Python-checkins] GH-96179: Fix misleading example on the bisect documentation (GH-96228) Message-ID: <mailman.807.1661356555.3313.python-checkins@python.org> https://github.com/python/cpython/commit/41e8257449c2c44bbe8fc9577cdf5ba0c54b867d commit: 41e8257449c2c44bbe8fc9577cdf5ba0c54b867d branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T08:55:45-07:00 summary: GH-96179: Fix misleading example on the bisect documentation (GH-96228) The `movies[bisect(movies, 1960, key=by_year)]` will actually return only movies **after** 1960. (cherry picked from commit 4317b25a2323ae4be04574e45de0e335c571c463) Co-authored-by: prego <pedropregueiro at gmail.com> files: M Doc/library/bisect.rst M Misc/ACKS diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 513675d3685..c2927c1ebd0 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -216,7 +216,7 @@ records in a table:: ... Movie('Aliens', 1986, 'Scott') ... ] - >>> # Find the first movie released on or after 1960 + >>> # Find the first movie released after 1960 >>> by_year = attrgetter('released') >>> movies.sort(key=by_year) >>> movies[bisect(movies, 1960, key=by_year)] diff --git a/Misc/ACKS b/Misc/ACKS index 8726c0f6e62..fc1dcafcc85 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1405,6 +1405,7 @@ John Popplewell Matheus Vieira Portela Davin Potts Guillaume Pratte +Pedro Pregueiro Florian Preinstorfer Alex Preng?re Amrit Prem From webhook-mailer at python.org Wed Aug 24 11:58:53 2022 From: webhook-mailer at python.org (iritkatriel) Date: Wed, 24 Aug 2022 15:58:53 -0000 Subject: [Python-checkins] gh-87092: use basicblock_last_instr consistently in the compiler (GH-96243) Message-ID: <mailman.808.1661356734.3313.python-checkins@python.org> https://github.com/python/cpython/commit/fba3b67af47723c201fe3425cb615932970a8f28 commit: fba3b67af47723c201fe3425cb615932970a8f28 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-24T16:58:42+01:00 summary: gh-87092: use basicblock_last_instr consistently in the compiler (GH-96243) files: M Python/compile.c diff --git a/Python/compile.c b/Python/compile.c index e5ac162ccc0..627f86a8ce9 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -291,7 +291,9 @@ typedef struct basicblock_ { static struct instr * basicblock_last_instr(const basicblock *b) { - if (b->b_iused) { + assert(b->b_iused >= 0); + if (b->b_iused > 0) { + assert(b->b_instr != NULL); return &b->b_instr[b->b_iused - 1]; } return NULL; @@ -7168,10 +7170,8 @@ assemble_free(struct assembler *a) static int blocksize(basicblock *b) { - int i; int size = 0; - - for (i = 0; i < b->b_iused; i++) { + for (int i = 0; i < b->b_iused; i++) { size += instr_size(&b->b_instr[i]); } return size; @@ -7746,10 +7746,10 @@ normalize_jumps(basicblock *entryblock) } for (basicblock *b = entryblock; b != NULL; b = b->b_next) { b->b_visited = 1; - if (b->b_iused == 0) { + struct instr *last = basicblock_last_instr(b); + if (last == NULL) { continue; } - struct instr *last = &b->b_instr[b->b_iused-1]; assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); if (is_jump(last)) { bool is_forward = last->i_target->b_visited == 0; @@ -7915,8 +7915,8 @@ scan_block_for_local(int target, basicblock *b, bool unsafe_to_start, if (b->b_next && BB_HAS_FALLTHROUGH(b)) { MAYBE_PUSH(b->b_next); } - if (b->b_iused > 0) { - struct instr *last = &b->b_instr[b->b_iused-1]; + struct instr *last = basicblock_last_instr(b); + if (last != NULL) { if (is_jump(last)) { assert(last->i_target != NULL); MAYBE_PUSH(last->i_target); @@ -8405,10 +8405,10 @@ guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) { int lineno = firstlineno; assert(lineno > 0); for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { + struct instr *last = basicblock_last_instr(b); + if (last == NULL) { continue; } - struct instr *last = &b->b_instr[b->b_iused-1]; if (last->i_loc.lineno < 0) { if (last->i_opcode == RETURN_VALUE) { for (int i = 0; i < b->b_iused; i++) { @@ -8486,18 +8486,18 @@ remove_redundant_jumps(cfg_builder *g) { */ int removed = 0; for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { - if (b->b_iused > 0) { - struct instr *b_last_instr = &b->b_instr[b->b_iused - 1]; - assert(!IS_ASSEMBLER_OPCODE(b_last_instr->i_opcode)); - if (b_last_instr->i_opcode == JUMP || - b_last_instr->i_opcode == JUMP_NO_INTERRUPT) { - if (b_last_instr->i_target == NULL) { + struct instr *last = basicblock_last_instr(b); + if (last != NULL) { + assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); + if (last->i_opcode == JUMP || + last->i_opcode == JUMP_NO_INTERRUPT) { + if (last->i_target == NULL) { PyErr_SetString(PyExc_SystemError, "jump with NULL target"); return -1; } - if (b_last_instr->i_target == b->b_next) { + if (last->i_target == b->b_next) { assert(b->b_next->b_iused); - b_last_instr->i_opcode = NOP; + last->i_opcode = NOP; removed++; } } @@ -9215,10 +9215,10 @@ basicblock_has_lineno(const basicblock *bb) { */ static int extend_block(basicblock *bb) { - if (bb->b_iused == 0) { + struct instr *last = basicblock_last_instr(bb); + if (last == NULL) { return 0; } - struct instr *last = &bb->b_instr[bb->b_iused-1]; if (last->i_opcode != JUMP && last->i_opcode != JUMP_FORWARD && last->i_opcode != JUMP_BACKWARD) { @@ -9399,7 +9399,8 @@ eliminate_empty_basic_blocks(cfg_builder *g) { static void propagate_line_numbers(basicblock *entryblock) { for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { + struct instr *last = basicblock_last_instr(b); + if (last == NULL) { continue; } @@ -9418,8 +9419,8 @@ propagate_line_numbers(basicblock *entryblock) { b->b_next->b_instr[0].i_loc = prev_location; } } - if (is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; + if (is_jump(last)) { + basicblock *target = last->i_target; if (target->b_predecessors == 1) { if (target->b_instr[0].i_loc.lineno < 0) { target->b_instr[0].i_loc = prev_location; @@ -9576,15 +9577,16 @@ duplicate_exits_without_lineno(cfg_builder *g) */ basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - if (b->b_iused > 0 && is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; + struct instr *last = basicblock_last_instr(b); + if (last != NULL && is_jump(last)) { + basicblock *target = last->i_target; if (is_exit_without_lineno(target) && target->b_predecessors > 1) { basicblock *new_target = copy_basicblock(g, target); if (new_target == NULL) { return -1; } - new_target->b_instr[0].i_loc = b->b_instr[b->b_iused-1].i_loc; - b->b_instr[b->b_iused-1].i_target = new_target; + new_target->b_instr[0].i_loc = last->i_loc; + last->i_target = new_target; target->b_predecessors--; new_target->b_predecessors = 1; new_target->b_next = target->b_next; @@ -9603,8 +9605,9 @@ duplicate_exits_without_lineno(cfg_builder *g) for (basicblock *b = entryblock; b != NULL; b = b->b_next) { if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) { if (is_exit_without_lineno(b->b_next)) { - assert(b->b_next->b_iused > 0); - b->b_next->b_instr[0].i_loc = b->b_instr[b->b_iused-1].i_loc; + struct instr *last = basicblock_last_instr(b); + assert(last != NULL); + b->b_next->b_instr[0].i_loc = last->i_loc; } } } From webhook-mailer at python.org Wed Aug 24 16:16:50 2022 From: webhook-mailer at python.org (gvanrossum) Date: Wed, 24 Aug 2022 20:16:50 -0000 Subject: [Python-checkins] Add gvanrossum to asyncio experts (#96248) Message-ID: <mailman.809.1661372211.3313.python-checkins@python.org> https://github.com/python/cpython/commit/657976ad950e56b33b7dc15e64a0baecdd184f5a commit: 657976ad950e56b33b7dc15e64a0baecdd184f5a branch: main author: Guido van Rossum <guido at python.org> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-24T13:16:41-07:00 summary: Add gvanrossum to asyncio experts (#96248) files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0e38536ba99..2568560c074 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,7 +5,7 @@ # https://git-scm.com/docs/gitignore#_pattern_format # asyncio -**/*asyncio* @1st1 @asvetlov +**/*asyncio* @1st1 @asvetlov @gvanrossum # Core **/*context* @1st1 From webhook-mailer at python.org Wed Aug 24 18:21:56 2022 From: webhook-mailer at python.org (pablogsal) Date: Wed, 24 Aug 2022 22:21:56 -0000 Subject: [Python-checkins] GH-93503: Add thread-specific APIs to set profiling and tracing functions in the C-API (#93504) Message-ID: <mailman.810.1661379717.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e34c82abeb7ace09e6b5d116585c47cc372996c1 commit: e34c82abeb7ace09e6b5d116585c47cc372996c1 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-24T23:21:39+01:00 summary: GH-93503: Add thread-specific APIs to set profiling and tracing functions in the C-API (#93504) * gh-93503: Add APIs to set profiling and tracing functions in all threads in the C-API * Use a separate API * Fix NEWS entry * Add locks around the loop * Document ignoring exceptions * Use the new APIs in the sys module * Update docs files: A Misc/NEWS.d/next/C API/2022-06-06-16-04-14.gh-issue-93503.MHJTu8.rst M Doc/c-api/init.rst M Doc/data/refcounts.dat M Doc/library/threading.rst M Include/cpython/ceval.h M Lib/test/test_threading.py M Lib/threading.py M Python/ceval.c M Python/clinic/sysmodule.c.h M Python/sysmodule.c diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 038498f325c..2a9cf0ea702 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1774,6 +1774,18 @@ Python-level trace functions in previous versions. The caller must hold the :term:`GIL`. +.. c:function:: void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj) + + Like :c:func:`PyEval_SetProfile` but sets the profile function in all running threads + belonging to the current interpreter instead of the setting it only on the current thread. + + The caller must hold the :term:`GIL`. + + As :c:func:`PyEval_SetProfile`, this function ignores any exceptions raised while + setting the profile functions in all threads. + +.. versionadded:: 3.12 + .. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj) @@ -1788,6 +1800,18 @@ Python-level trace functions in previous versions. The caller must hold the :term:`GIL`. +.. c:function:: void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj) + + Like :c:func:`PyEval_SetTrace` but sets the tracing function in all running threads + belonging to the current interpreter instead of the setting it only on the current thread. + + The caller must hold the :term:`GIL`. + + As :c:func:`PyEval_SetTrace`, this function ignores any exceptions raised while + setting the trace functions in all threads. + +.. versionadded:: 3.12 + .. _advanced-debugging: diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 1694cad6f43..51ccacf13f9 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -796,10 +796,18 @@ PyEval_SetProfile:void::: PyEval_SetProfile:Py_tracefunc:func:: PyEval_SetProfile:PyObject*:obj:+1: +PyEval_SetProfileAllThreads:void::: +PyEval_SetProfileAllThreads:Py_tracefunc:func:: +PyEval_SetProfileAllThreads:PyObject*:obj:+1: + PyEval_SetTrace:void::: PyEval_SetTrace:Py_tracefunc:func:: PyEval_SetTrace:PyObject*:obj:+1: +PyEval_SetTraceAllThreads:void::: +PyEval_SetTraceAllThreads:Py_tracefunc:func:: +PyEval_SetTraceAllThreads:PyObject*:obj:+1: + PyEval_EvalCode:PyObject*::+1: PyEval_EvalCode:PyObject*:co:0: PyEval_EvalCode:PyObject*:globals:0: diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index b22d4876622..b352125551f 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -158,6 +158,15 @@ This module defines the following functions: The *func* will be passed to :func:`sys.settrace` for each thread, before its :meth:`~Thread.run` method is called. +.. function:: settrace_all_threads(func) + + Set a trace function for all threads started from the :mod:`threading` module + and all Python threads that are currently executing. + + The *func* will be passed to :func:`sys.settrace` for each thread, before its + :meth:`~Thread.run` method is called. + + .. versionadded:: 3.12 .. function:: gettrace() @@ -178,6 +187,15 @@ This module defines the following functions: The *func* will be passed to :func:`sys.setprofile` for each thread, before its :meth:`~Thread.run` method is called. +.. function:: setprofile_all_threads(func) + + Set a profile function for all threads started from the :mod:`threading` module + and all Python threads that are currently executing. + + The *func* will be passed to :func:`sys.setprofile` for each thread, before its + :meth:`~Thread.run` method is called. + + .. versionadded:: 3.12 .. function:: getprofile() diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 9d4eeafb427..74665c9fa10 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -3,8 +3,10 @@ #endif PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *); PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); /* Helper to look up a builtin object */ diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index dcd27697bb4..c6649962331 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -853,6 +853,7 @@ def callback(): callback() finally: sys.settrace(old_trace) + threading.settrace(old_trace) def test_gettrace(self): def noop_trace(frame, event, arg): @@ -866,6 +867,35 @@ def noop_trace(frame, event, arg): finally: threading.settrace(old_trace) + def test_gettrace_all_threads(self): + def fn(*args): pass + old_trace = threading.gettrace() + first_check = threading.Event() + second_check = threading.Event() + + trace_funcs = [] + def checker(): + trace_funcs.append(sys.gettrace()) + first_check.set() + second_check.wait() + trace_funcs.append(sys.gettrace()) + + try: + t = threading.Thread(target=checker) + t.start() + first_check.wait() + threading.settrace_all_threads(fn) + second_check.set() + t.join() + self.assertEqual(trace_funcs, [None, fn]) + self.assertEqual(threading.gettrace(), fn) + self.assertEqual(sys.gettrace(), fn) + finally: + threading.settrace_all_threads(old_trace) + + self.assertEqual(threading.gettrace(), old_trace) + self.assertEqual(sys.gettrace(), old_trace) + def test_getprofile(self): def fn(*args): pass old_profile = threading.getprofile() @@ -875,6 +905,35 @@ def fn(*args): pass finally: threading.setprofile(old_profile) + def test_getprofile_all_threads(self): + def fn(*args): pass + old_profile = threading.getprofile() + first_check = threading.Event() + second_check = threading.Event() + + profile_funcs = [] + def checker(): + profile_funcs.append(sys.getprofile()) + first_check.set() + second_check.wait() + profile_funcs.append(sys.getprofile()) + + try: + t = threading.Thread(target=checker) + t.start() + first_check.wait() + threading.setprofile_all_threads(fn) + second_check.set() + t.join() + self.assertEqual(profile_funcs, [None, fn]) + self.assertEqual(threading.getprofile(), fn) + self.assertEqual(sys.getprofile(), fn) + finally: + threading.setprofile_all_threads(old_profile) + + self.assertEqual(threading.getprofile(), old_profile) + self.assertEqual(sys.getprofile(), old_profile) + @cpython_only def test_shutdown_locks(self): for daemon in (False, True): diff --git a/Lib/threading.py b/Lib/threading.py index e32ad1418d9..f28597c9930 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -28,7 +28,8 @@ 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', 'setprofile', 'settrace', 'local', 'stack_size', - 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile'] + 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile', + 'setprofile_all_threads','settrace_all_threads'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread @@ -60,11 +61,20 @@ def setprofile(func): The func will be passed to sys.setprofile() for each thread, before its run() method is called. - """ global _profile_hook _profile_hook = func +def setprofile_all_threads(func): + """Set a profile function for all threads started from the threading module + and all Python threads that are currently executing. + + The func will be passed to sys.setprofile() for each thread, before its + run() method is called. + """ + setprofile(func) + _sys._setprofileallthreads(func) + def getprofile(): """Get the profiler function as set by threading.setprofile().""" return _profile_hook @@ -74,11 +84,20 @@ def settrace(func): The func will be passed to sys.settrace() for each thread, before its run() method is called. - """ global _trace_hook _trace_hook = func +def settrace_all_threads(func): + """Set a trace function for all threads started from the threading module + and all Python threads that are currently executing. + + The func will be passed to sys.settrace() for each thread, before its run() + method is called. + """ + settrace(func) + _sys._settraceallthreads(func) + def gettrace(): """Get the trace function as set by threading.settrace().""" return _trace_hook diff --git a/Misc/NEWS.d/next/C API/2022-06-06-16-04-14.gh-issue-93503.MHJTu8.rst b/Misc/NEWS.d/next/C API/2022-06-06-16-04-14.gh-issue-93503.MHJTu8.rst new file mode 100644 index 00000000000..6df9f95fc94 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-06-06-16-04-14.gh-issue-93503.MHJTu8.rst @@ -0,0 +1,7 @@ +Add two new public functions to the public C-API, +:c:func:`PyEval_SetProfileAllThreads` and +:c:func:`PyEval_SetTraceAllThreads`, that allow to set tracking and +profiling functions in all running threads in addition to the calling one. +Also, add a new *running_threads* parameter to :func:`threading.setprofile` +and :func:`threading.settrace` that allows to do the same from Python. Patch +by Pablo Galindo diff --git a/Python/ceval.c b/Python/ceval.c index 1ab104c18ed..ac77ab8e869 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -96,6 +96,10 @@ #define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) #endif +#define HEAD_LOCK(runtime) \ + PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) +#define HEAD_UNLOCK(runtime) \ + PyThread_release_lock((runtime)->interpreters.mutex) /* Forward declarations */ static PyObject *trace_call_function( @@ -6455,6 +6459,27 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) } } +void +PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg) +{ + PyThreadState *this_tstate = _PyThreadState_GET(); + PyInterpreterState* interp = this_tstate->interp; + + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); + + while (ts) { + if (_PyEval_SetProfile(ts, func, arg) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL); + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); + } +} + int _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) { @@ -6508,6 +6533,26 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) } } +void +PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg) +{ + PyThreadState *this_tstate = _PyThreadState_GET(); + PyInterpreterState* interp = this_tstate->interp; + + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); + + while (ts) { + if (_PyEval_SetTrace(ts, func, arg) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL); + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); + } +} int _PyEval_SetCoroutineOriginTrackingDepth(int depth) diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index beaf21c85bc..0f9636690a4 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -292,6 +292,18 @@ sys_intern(PyObject *module, PyObject *arg) return return_value; } +PyDoc_STRVAR(sys__settraceallthreads__doc__, +"_settraceallthreads($module, arg, /)\n" +"--\n" +"\n" +"Set the global debug tracing function in all running threads belonging to the current interpreter.\n" +"\n" +"It will be called on each function call. See the debugger chapter\n" +"in the library manual."); + +#define SYS__SETTRACEALLTHREADS_METHODDEF \ + {"_settraceallthreads", (PyCFunction)sys__settraceallthreads, METH_O, sys__settraceallthreads__doc__}, + PyDoc_STRVAR(sys_gettrace__doc__, "gettrace($module, /)\n" "--\n" @@ -312,6 +324,18 @@ sys_gettrace(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys_gettrace_impl(module); } +PyDoc_STRVAR(sys__setprofileallthreads__doc__, +"_setprofileallthreads($module, arg, /)\n" +"--\n" +"\n" +"Set the profiling function in all running threads belonging to the current interpreter.\n" +"\n" +"It will be called on each function call and return. See the profiler chapter\n" +"in the library manual."); + +#define SYS__SETPROFILEALLTHREADS_METHODDEF \ + {"_setprofileallthreads", (PyCFunction)sys__setprofileallthreads, METH_O, sys__setprofileallthreads__doc__}, + PyDoc_STRVAR(sys_getprofile__doc__, "getprofile($module, /)\n" "--\n" @@ -1170,4 +1194,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=38446a4c76e2f3b6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=322fb0409e376ad4 input=a9049054013a1b77]*/ diff --git a/Python/sysmodule.c b/Python/sysmodule.c index b8009b2db45..c2864387941 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1021,6 +1021,36 @@ Set the global debug tracing function. It will be called on each\n\ function call. See the debugger chapter in the library manual." ); +/*[clinic input] +sys._settraceallthreads + + arg: object + / + +Set the global debug tracing function in all running threads belonging to the current interpreter. + +It will be called on each function call. See the debugger chapter +in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys__settraceallthreads(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=161cca30207bf3ca input=5906aa1485a50289]*/ +{ + PyObject* argument = NULL; + Py_tracefunc func = NULL; + + if (arg != Py_None) { + func = trace_trampoline; + argument = arg; + } + + + PyEval_SetTraceAllThreads(func, argument); + + Py_RETURN_NONE; +} + /*[clinic input] sys.gettrace @@ -1066,6 +1096,35 @@ Set the profiling function. It will be called on each function call\n\ and return. See the profiler chapter in the library manual." ); +/*[clinic input] +sys._setprofileallthreads + + arg: object + / + +Set the profiling function in all running threads belonging to the current interpreter. + +It will be called on each function call and return. See the profiler chapter +in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys__setprofileallthreads(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=2d61319e27b309fe input=d1a356d3f4f9060a]*/ +{ + PyObject* argument = NULL; + Py_tracefunc func = NULL; + + if (arg != Py_None) { + func = profile_trampoline; + argument = arg; + } + + PyEval_SetProfileAllThreads(func, argument); + + Py_RETURN_NONE; +} + /*[clinic input] sys.getprofile @@ -2035,9 +2094,11 @@ static PyMethodDef sys_methods[] = { SYS_GETSWITCHINTERVAL_METHODDEF SYS_SETDLOPENFLAGS_METHODDEF {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + SYS__SETPROFILEALLTHREADS_METHODDEF SYS_GETPROFILE_METHODDEF SYS_SETRECURSIONLIMIT_METHODDEF {"settrace", sys_settrace, METH_O, settrace_doc}, + SYS__SETTRACEALLTHREADS_METHODDEF SYS_GETTRACE_METHODDEF SYS_CALL_TRACING_METHODDEF SYS__DEBUGMALLOCSTATS_METHODDEF From webhook-mailer at python.org Wed Aug 24 21:37:26 2022 From: webhook-mailer at python.org (gpshead) Date: Thu, 25 Aug 2022 01:37:26 -0000 Subject: [Python-checkins] gh-95243: Mitigate the race condition in testSockName (#96173) Message-ID: <mailman.811.1661391447.3313.python-checkins@python.org> https://github.com/python/cpython/commit/df110126971d0271a977ce10779083b3e335b4da commit: df110126971d0271a977ce10779083b3e335b4da branch: main author: Ross Burton <ross.burton at arm.com> committer: gpshead <greg at krypto.org> date: 2022-08-24T18:37:18-07:00 summary: gh-95243: Mitigate the race condition in testSockName (#96173) find_unused_port() has an inherent race condition, but we can't use bind_port() as that uses .getsockname() which this test is exercising. Try binding to unused ports a few times before failing. Signed-off-by: Ross Burton <ross.burton at arm.com> files: A Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst M Lib/test/test_socket.py diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index f1b57fc4071..d808f3f62b9 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1398,10 +1398,21 @@ def testStringToIPv6(self): def testSockName(self): # Testing getsockname() - port = socket_helper.find_unused_port() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.addCleanup(sock.close) - sock.bind(("0.0.0.0", port)) + + # Since find_unused_port() is inherently subject to race conditions, we + # call it a couple times if necessary. + for i in itertools.count(): + port = socket_helper.find_unused_port() + try: + sock.bind(("0.0.0.0", port)) + except OSError as e: + if e.errno != errno.EADDRINUSE or i == 5: + raise + else: + break + name = sock.getsockname() # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate # it reasonable to get the host's addr in addition to 0.0.0.0. diff --git a/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst b/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst new file mode 100644 index 00000000000..a9ca1f8b867 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst @@ -0,0 +1,3 @@ +Mitigate the inherent race condition from using find_unused_port() in +testSockName() by trying to find an unused port a few times before failing. +Patch by Ross Burton. From webhook-mailer at python.org Wed Aug 24 22:01:55 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 25 Aug 2022 02:01:55 -0000 Subject: [Python-checkins] gh-95243: Mitigate the race condition in testSockName (GH-96173) Message-ID: <mailman.812.1661392915.3313.python-checkins@python.org> https://github.com/python/cpython/commit/979a3b8cd3861c2a40b560f891e5828500f35416 commit: 979a3b8cd3861c2a40b560f891e5828500f35416 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T19:01:50-07:00 summary: gh-95243: Mitigate the race condition in testSockName (GH-96173) find_unused_port() has an inherent race condition, but we can't use bind_port() as that uses .getsockname() which this test is exercising. Try binding to unused ports a few times before failing. Signed-off-by: Ross Burton <ross.burton at arm.com> (cherry picked from commit df110126971d0271a977ce10779083b3e335b4da) Co-authored-by: Ross Burton <ross.burton at arm.com> files: A Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst M Lib/test/test_socket.py diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 9c5f6d3dc9a..e0e0f2437bb 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1374,10 +1374,21 @@ def testStringToIPv6(self): def testSockName(self): # Testing getsockname() - port = socket_helper.find_unused_port() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.addCleanup(sock.close) - sock.bind(("0.0.0.0", port)) + + # Since find_unused_port() is inherently subject to race conditions, we + # call it a couple times if necessary. + for i in itertools.count(): + port = socket_helper.find_unused_port() + try: + sock.bind(("0.0.0.0", port)) + except OSError as e: + if e.errno != errno.EADDRINUSE or i == 5: + raise + else: + break + name = sock.getsockname() # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate # it reasonable to get the host's addr in addition to 0.0.0.0. diff --git a/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst b/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst new file mode 100644 index 00000000000..a9ca1f8b867 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst @@ -0,0 +1,3 @@ +Mitigate the inherent race condition from using find_unused_port() in +testSockName() by trying to find an unused port a few times before failing. +Patch by Ross Burton. From webhook-mailer at python.org Wed Aug 24 22:03:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 25 Aug 2022 02:03:34 -0000 Subject: [Python-checkins] gh-95243: Mitigate the race condition in testSockName (GH-96173) Message-ID: <mailman.813.1661393015.3313.python-checkins@python.org> https://github.com/python/cpython/commit/915ee9ed43b199de6f9fb371c2224ef4593522ab commit: 915ee9ed43b199de6f9fb371c2224ef4593522ab branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T19:03:29-07:00 summary: gh-95243: Mitigate the race condition in testSockName (GH-96173) find_unused_port() has an inherent race condition, but we can't use bind_port() as that uses .getsockname() which this test is exercising. Try binding to unused ports a few times before failing. Signed-off-by: Ross Burton <ross.burton at arm.com> (cherry picked from commit df110126971d0271a977ce10779083b3e335b4da) Co-authored-by: Ross Burton <ross.burton at arm.com> files: A Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst M Lib/test/test_socket.py diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 72e3394df2d..b07954989fd 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1389,10 +1389,21 @@ def testStringToIPv6(self): def testSockName(self): # Testing getsockname() - port = socket_helper.find_unused_port() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.addCleanup(sock.close) - sock.bind(("0.0.0.0", port)) + + # Since find_unused_port() is inherently subject to race conditions, we + # call it a couple times if necessary. + for i in itertools.count(): + port = socket_helper.find_unused_port() + try: + sock.bind(("0.0.0.0", port)) + except OSError as e: + if e.errno != errno.EADDRINUSE or i == 5: + raise + else: + break + name = sock.getsockname() # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate # it reasonable to get the host's addr in addition to 0.0.0.0. diff --git a/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst b/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst new file mode 100644 index 00000000000..a9ca1f8b867 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst @@ -0,0 +1,3 @@ +Mitigate the inherent race condition from using find_unused_port() in +testSockName() by trying to find an unused port a few times before failing. +Patch by Ross Burton. From webhook-mailer at python.org Thu Aug 25 00:53:57 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 25 Aug 2022 04:53:57 -0000 Subject: [Python-checkins] gh-96021: Explicitly close the IsolatedAsyncioTestCase runner in tests (GH-96135) Message-ID: <mailman.814.1661403238.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f51216df073310c783f1890993fe9b67ccb3c6b4 commit: f51216df073310c783f1890993fe9b67ccb3c6b4 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-24T21:53:39-07:00 summary: gh-96021: Explicitly close the IsolatedAsyncioTestCase runner in tests (GH-96135) Tests for IsolatedAsyncioTestCase.debug() rely on the runner be closed in __del__. It makes tests depending on the GC an unreliable on other implementations. It is better to close the runner explicitly even if currently there is no a public API for this. (cherry picked from commit 4de06e3cc0a58d73934f9a2759ad9cd2f6b031b0) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M Lib/unittest/test/test_async_case.py diff --git a/Lib/unittest/test/test_async_case.py b/Lib/unittest/test/test_async_case.py index f59fc760d38..d7d4dc91316 100644 --- a/Lib/unittest/test/test_async_case.py +++ b/Lib/unittest/test/test_async_case.py @@ -43,10 +43,10 @@ async def __aenter__(self): class TestAsyncCase(unittest.TestCase): maxDiff = None - def tearDown(self): + def setUp(self): # Ensure that IsolatedAsyncioTestCase instances are destroyed before # starting a new event loop - support.gc_collect() + self.addCleanup(support.gc_collect) def test_full_cycle(self): class Test(unittest.IsolatedAsyncioTestCase): @@ -151,6 +151,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -186,6 +187,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -221,6 +223,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -262,6 +265,7 @@ async def on_cleanup2(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -424,6 +428,7 @@ async def cleanup(self, fut): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: From webhook-mailer at python.org Thu Aug 25 03:27:47 2022 From: webhook-mailer at python.org (vsajip) Date: Thu, 25 Aug 2022 07:27:47 -0000 Subject: [Python-checkins] gh-91070: Add note about SysLogHandler on macOS 12.x (Monterey). (GH-94803) Message-ID: <mailman.815.1661412467.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8db7693bbff55f5ed4bfc194c77c561e71471bf3 commit: 8db7693bbff55f5ed4bfc194c77c561e71471bf3 branch: main author: Vinay Sajip <vinay_sajip at yahoo.co.uk> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-25T08:27:30+01:00 summary: gh-91070: Add note about SysLogHandler on macOS 12.x (Monterey). (GH-94803) files: M Doc/library/logging.handlers.rst diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 0dc05255db9..f125dfe64a0 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -629,6 +629,12 @@ supports sending logging messages to a remote or local Unix syslog. application needs to run on several platforms). On Windows, you pretty much have to use the UDP option. + .. note:: On macOS 12.x (Monterey), Apple has changed the behaviour of their + syslog daemon - it no longer listens on a domain socket. Therefore, you cannot + expect :class:`SysLogHandler` to work on this system. + + See :gh:`91070` for more information. + .. versionchanged:: 3.2 *socktype* was added. From webhook-mailer at python.org Thu Aug 25 03:37:47 2022 From: webhook-mailer at python.org (vsajip) Date: Thu, 25 Aug 2022 07:37:47 -0000 Subject: [Python-checkins] [3.10] gh-91070: Add note about SysLogHandler on macOS 12.x (Monterey). (GH-94803) (GH-96261) Message-ID: <mailman.816.1661413068.3313.python-checkins@python.org> https://github.com/python/cpython/commit/147b8312eac0647a5b2d74812acf7f51054488a3 commit: 147b8312eac0647a5b2d74812acf7f51054488a3 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-25T08:37:42+01:00 summary: [3.10] gh-91070: Add note about SysLogHandler on macOS 12.x (Monterey). (GH-94803) (GH-96261) files: M Doc/library/logging.handlers.rst diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 0dc05255db9c..f125dfe64a03 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -629,6 +629,12 @@ supports sending logging messages to a remote or local Unix syslog. application needs to run on several platforms). On Windows, you pretty much have to use the UDP option. + .. note:: On macOS 12.x (Monterey), Apple has changed the behaviour of their + syslog daemon - it no longer listens on a domain socket. Therefore, you cannot + expect :class:`SysLogHandler` to work on this system. + + See :gh:`91070` for more information. + .. versionchanged:: 3.2 *socktype* was added. From webhook-mailer at python.org Thu Aug 25 03:38:11 2022 From: webhook-mailer at python.org (vsajip) Date: Thu, 25 Aug 2022 07:38:11 -0000 Subject: [Python-checkins] [3.11] gh-91070: Add note about SysLogHandler on macOS 12.x (Monterey). (GH-94803) (GH-96260) Message-ID: <mailman.817.1661413093.3313.python-checkins@python.org> https://github.com/python/cpython/commit/888054ae8a357d2df0f62aadf1840be1d4eaee9e commit: 888054ae8a357d2df0f62aadf1840be1d4eaee9e branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-25T08:38:02+01:00 summary: [3.11] gh-91070: Add note about SysLogHandler on macOS 12.x (Monterey). (GH-94803) (GH-96260) files: M Doc/library/logging.handlers.rst diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 026f14153cbe..1e61a519bc06 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -629,6 +629,12 @@ supports sending logging messages to a remote or local Unix syslog. application needs to run on several platforms). On Windows, you pretty much have to use the UDP option. + .. note:: On macOS 12.x (Monterey), Apple has changed the behaviour of their + syslog daemon - it no longer listens on a domain socket. Therefore, you cannot + expect :class:`SysLogHandler` to work on this system. + + See :gh:`91070` for more information. + .. versionchanged:: 3.2 *socktype* was added. From webhook-mailer at python.org Thu Aug 25 05:17:38 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 25 Aug 2022 09:17:38 -0000 Subject: [Python-checkins] GH-96237: Allow non-functions as reference-holder in frames. (GH-96238) Message-ID: <mailman.818.1661419059.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c09fa7542c6d9b724e423b14c6fb5f4338eabd12 commit: c09fa7542c6d9b724e423b14c6fb5f4338eabd12 branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-25T10:16:55+01:00 summary: GH-96237: Allow non-functions as reference-holder in frames. (GH-96238) files: A Misc/NEWS.d/next/Core and Builtins/2022-08-24-14-30-26.gh-issue-96237.msif5f.rst M Include/internal/pycore_frame.h M Modules/_testinternalcapi.c M Objects/frameobject.c M Python/ceval.c M Python/frame.c diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 994c205c3d16..decaafd141e9 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -47,7 +47,7 @@ enum _frameowner { typedef struct _PyInterpreterFrame { /* "Specials" section */ - PyFunctionObject *f_func; /* Strong reference */ + PyObject *f_funcobj; /* Strong reference */ PyObject *f_globals; /* Borrowed reference */ PyObject *f_builtins; /* Borrowed reference */ PyObject *f_locals; /* Strong reference, may be NULL */ @@ -101,7 +101,7 @@ _PyFrame_InitializeSpecials( _PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals, PyCodeObject *code) { - frame->f_func = func; + frame->f_funcobj = (PyObject *)func; frame->f_code = (PyCodeObject *)Py_NewRef(code); frame->f_builtins = func->func_builtins; frame->f_globals = func->func_globals; diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-24-14-30-26.gh-issue-96237.msif5f.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-24-14-30-26.gh-issue-96237.msif5f.rst new file mode 100644 index 000000000000..cb8a1c0eb7c2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-24-14-30-26.gh-issue-96237.msif5f.rst @@ -0,0 +1,5 @@ +The internal field ``_PyInterpreterFrame.f_func`` is renamed to +``_PyInterpreterFrame.f_funcobj`` and may be any object. The ``f_globals`` +and ``f_builtin`` fields may hold junk values. + +It is safest to treat the ``_PyInterpreterFrame`` struct as opaque. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 9d92b076387f..02a061b84f85 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -511,7 +511,9 @@ set_eval_frame_default(PyObject *self, PyObject *Py_UNUSED(args)) static PyObject * record_eval(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc) { - PyList_Append(record_list, f->f_func->func_name); + if (PyFunction_Check(f->f_funcobj)) { + PyList_Append(record_list, ((PyFunctionObject *)f->f_funcobj)->func_name); + } return _PyEval_EvalFrameDefault(tstate, f, exc); } diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 26b38bae780c..d2647bd12288 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -910,7 +910,7 @@ frame_dealloc(PyFrameObject *f) /* Don't clear code object until the end */ co = frame->f_code; frame->f_code = NULL; - Py_CLEAR(frame->f_func); + Py_CLEAR(frame->f_funcobj); Py_CLEAR(frame->f_locals); PyObject **locals = _PyFrame_GetLocalsArray(frame); for (int i = 0; i < frame->stacktop; i++) { @@ -1154,10 +1154,12 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt // here: int lasti = _PyInterpreterFrame_LASTI(frame); - if (lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS) { + if (lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS + && PyFunction_Check(frame->f_funcobj)) + { /* Free vars have not been initialized -- Do that */ PyCodeObject *co = frame->f_code; - PyObject *closure = frame->f_func->func_closure; + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; int offset = co->co_nlocals + co->co_nplaincellvars; for (int i = 0; i < co->co_nfreevars; ++i) { PyObject *o = PyTuple_GET_ITEM(closure, i); diff --git a/Python/ceval.c b/Python/ceval.c index ac77ab8e8692..b3a0a3640eb9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -154,11 +154,12 @@ lltrace_instruction(_PyInterpreterFrame *frame, static void lltrace_resume_frame(_PyInterpreterFrame *frame) { - PyFunctionObject *f = frame->f_func; - if (f == NULL) { + PyObject *fobj = frame->f_funcobj; + if (fobj == NULL || !PyFunction_Check(fobj)) { printf("\nResuming frame."); return; } + PyFunctionObject *f = (PyFunctionObject *)fobj; PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); PyObject *name = f->func_qualname; @@ -2619,7 +2620,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(COPY_FREE_VARS) { /* Copy closure variables to free variables */ PyCodeObject *co = frame->f_code; - PyObject *closure = frame->f_func->func_closure; + assert(PyFunction_Check(frame->f_funcobj)); + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; int offset = co->co_nlocals + co->co_nplaincellvars; assert(oparg == co->co_nfreevars); for (int i = 0; i < oparg; ++i) { @@ -4897,7 +4899,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(RETURN_GENERATOR) { - PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(frame->f_func); + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); if (gen == NULL) { goto error; } @@ -4919,7 +4923,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Make sure that frame is in a valid state */ frame->stacktop = 0; frame->f_locals = NULL; - Py_INCREF(frame->f_func); + Py_INCREF(frame->f_funcobj); Py_INCREF(frame->f_code); /* Restore previous cframe and return. */ tstate->cframe = cframe.previous; diff --git a/Python/frame.c b/Python/frame.c index 7c6705e208f3..14464df0a8d5 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -13,7 +13,7 @@ _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg) { Py_VISIT(frame->frame_obj); Py_VISIT(frame->f_locals); - Py_VISIT(frame->f_func); + Py_VISIT(frame->f_funcobj); Py_VISIT(frame->f_code); /* locals */ PyObject **locals = _PyFrame_GetLocalsArray(frame); @@ -114,7 +114,7 @@ _PyFrame_Clear(_PyInterpreterFrame *frame) } Py_XDECREF(frame->frame_obj); Py_XDECREF(frame->f_locals); - Py_DECREF(frame->f_func); + Py_DECREF(frame->f_funcobj); Py_DECREF(frame->f_code); } From webhook-mailer at python.org Thu Aug 25 06:14:05 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 25 Aug 2022 10:14:05 -0000 Subject: [Python-checkins] gh-76728: Coerce DictReader and DictWriter fieldnames argument to a list (GH-32225) Message-ID: <mailman.819.1661422446.3313.python-checkins@python.org> https://github.com/python/cpython/commit/cd492d43a2980faf0ef4a3f99c665023a506414c commit: cd492d43a2980faf0ef4a3f99c665023a506414c branch: main author: Sam Ezeh <sam.z.ezeh at gmail.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-25T05:13:24-05:00 summary: gh-76728: Coerce DictReader and DictWriter fieldnames argument to a list (GH-32225) files: A Misc/NEWS.d/next/Library/2022-04-01-09-43-54.bpo-32547.NIUiNC.rst M Doc/library/csv.rst M Lib/csv.py M Lib/test/test_csv.py diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 9dec7240d9c5..0cab95e1500a 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -167,6 +167,8 @@ The :mod:`csv` module defines the following classes: All other optional or keyword arguments are passed to the underlying :class:`reader` instance. + If the argument passed to *fieldnames* is an iterator, it will be coerced to a :class:`list`. + .. versionchanged:: 3.6 Returned rows are now of type :class:`OrderedDict`. @@ -209,6 +211,8 @@ The :mod:`csv` module defines the following classes: Note that unlike the :class:`DictReader` class, the *fieldnames* parameter of the :class:`DictWriter` class is not optional. + If the argument passed to *fieldnames* is an iterator, it will be coerced to a :class:`list`. + A short usage example:: import csv diff --git a/Lib/csv.py b/Lib/csv.py index bfc850ee96da..0de5656a4eed 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -81,6 +81,8 @@ class unix_dialect(Dialect): class DictReader: def __init__(self, f, fieldnames=None, restkey=None, restval=None, dialect="excel", *args, **kwds): + if fieldnames is not None and iter(fieldnames) is fieldnames: + fieldnames = list(fieldnames) self._fieldnames = fieldnames # list of keys for the dict self.restkey = restkey # key to catch long rows self.restval = restval # default value for short rows @@ -133,6 +135,8 @@ def __next__(self): class DictWriter: def __init__(self, f, fieldnames, restval="", extrasaction="raise", dialect="excel", *args, **kwds): + if fieldnames is not None and iter(fieldnames) is fieldnames: + fieldnames = list(fieldnames) self.fieldnames = fieldnames # list of keys for the dict self.restval = restval # for writing short dicts if extrasaction.lower() not in ("raise", "ignore"): diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 95a19dd46cb4..51ca1f2ab292 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -736,6 +736,34 @@ def test_write_field_not_in_field_names_ignore(self): csv.DictWriter.writerow(writer, dictrow) self.assertEqual(fileobj.getvalue(), "1,2\r\n") + def test_dict_reader_fieldnames_accepts_iter(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + reader = csv.DictReader(f, iter(fieldnames)) + self.assertEqual(reader.fieldnames, fieldnames) + + def test_dict_reader_fieldnames_accepts_list(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + reader = csv.DictReader(f, fieldnames) + self.assertEqual(reader.fieldnames, fieldnames) + + def test_dict_writer_fieldnames_rejects_iter(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + writer = csv.DictWriter(f, iter(fieldnames)) + self.assertEqual(writer.fieldnames, fieldnames) + + def test_dict_writer_fieldnames_accepts_list(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + writer = csv.DictWriter(f, fieldnames) + self.assertEqual(writer.fieldnames, fieldnames) + + def test_dict_reader_fieldnames_is_optional(self): + f = StringIO() + reader = csv.DictReader(f, fieldnames=None) + def test_read_dict_fields(self): with TemporaryFile("w+", encoding="utf-8") as fileobj: fileobj.write("1,2,abc\r\n") diff --git a/Misc/NEWS.d/next/Library/2022-04-01-09-43-54.bpo-32547.NIUiNC.rst b/Misc/NEWS.d/next/Library/2022-04-01-09-43-54.bpo-32547.NIUiNC.rst new file mode 100644 index 000000000000..4599b73cc342 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-01-09-43-54.bpo-32547.NIUiNC.rst @@ -0,0 +1 @@ +The constructors for :class:`~csv.DictWriter` and :class:`~csv.DictReader` now coerce the ``fieldnames`` argument to a :class:`list` if it is an iterator. From webhook-mailer at python.org Thu Aug 25 07:19:21 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 25 Aug 2022 11:19:21 -0000 Subject: [Python-checkins] gh-92445 Improve interaction between nargs="*" and choices() (GH-92565) Message-ID: <mailman.820.1661426362.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ad7340e8c56f61edc1ff4724fe32c9d831db51a7 commit: ad7340e8c56f61edc1ff4724fe32c9d831db51a7 branch: main author: Harry <harry.lees at gmail.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-25T06:18:38-05:00 summary: gh-92445 Improve interaction between nargs="*" and choices() (GH-92565) files: A Misc/NEWS.d/next/Library/2022-05-09-21-31-41.gh-issue-92445.tJosdm.rst M Lib/argparse.py M Lib/test/test_argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index 02e98bbf920c..fe48f8670fa2 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2477,9 +2477,11 @@ def _get_values(self, action, arg_strings): not action.option_strings): if action.default is not None: value = action.default + self._check_value(action, value) else: + # since arg_strings is always [] at this point + # there is no need to use self._check_value(action, value) value = arg_strings - self._check_value(action, value) # single argument or optional argument produces a single value elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 425b6bb3e0b4..2b7f008d3856 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5230,6 +5230,13 @@ def test_mixed(self): self.assertEqual(NS(v=3, spam=True, badger="B"), args) self.assertEqual(["C", "--foo", "4"], extras) + def test_zero_or_more_optional(self): + parser = argparse.ArgumentParser() + parser.add_argument('x', nargs='*', choices=('x', 'y')) + args = parser.parse_args([]) + self.assertEqual(NS(x=[]), args) + + # =========================== # parse_intermixed_args tests # =========================== diff --git a/Misc/NEWS.d/next/Library/2022-05-09-21-31-41.gh-issue-92445.tJosdm.rst b/Misc/NEWS.d/next/Library/2022-05-09-21-31-41.gh-issue-92445.tJosdm.rst new file mode 100644 index 000000000000..ba69a011601f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-09-21-31-41.gh-issue-92445.tJosdm.rst @@ -0,0 +1,3 @@ +Fix a bug in :mod:`argparse` where `nargs="*"` would raise an error instead of returning +an empty list when 0 arguments were supplied if choice was also defined in +``parser.add_argument``. From webhook-mailer at python.org Thu Aug 25 09:32:50 2022 From: webhook-mailer at python.org (encukou) Date: Thu, 25 Aug 2022 13:32:50 -0000 Subject: [Python-checkins] Clarify API stability of PyTypeObject in relation to static types. (GH-96217) Message-ID: <mailman.821.1661434372.3313.python-checkins@python.org> https://github.com/python/cpython/commit/caa2a9799a47294441e4206037620322eea9ed06 commit: caa2a9799a47294441e4206037620322eea9ed06 branch: main author: ov2k <ov2k.github at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-25T15:32:12+02:00 summary: Clarify API stability of PyTypeObject in relation to static types. (GH-96217) Fixes: https://github.com/python/cpython/issues/95300 Related: https://github.com/python/cpython/issues/91271 files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index b8baa7c7dc3..dfe91ee358d 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2062,9 +2062,9 @@ This results in types that are limited relative to types defined in Python: :ref:`sub-interpreters <sub-interpreter-support>`, so they should not include any subinterpreter-specific state. -Also, since :c:type:`PyTypeObject` is not part of the :ref:`stable ABI <stable>`, -any extension modules using static types must be compiled for a specific -Python minor version. +Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API +<stable>` as an opaque struct, any extension modules using static types must be +compiled for a specific Python minor version. .. _heap-types: From webhook-mailer at python.org Thu Aug 25 09:42:24 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 25 Aug 2022 13:42:24 -0000 Subject: [Python-checkins] Clarify API stability of PyTypeObject in relation to static types. (GH-96217) Message-ID: <mailman.822.1661434945.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3d14b4fecb859c31123ffc07f278e9cce6b80e2d commit: 3d14b4fecb859c31123ffc07f278e9cce6b80e2d branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-25T06:42:14-07:00 summary: Clarify API stability of PyTypeObject in relation to static types. (GH-96217) Fixes: https://github.com/python/cpython/issues/95300 Related: https://github.com/python/cpython/issues/91271 (cherry picked from commit caa2a9799a47294441e4206037620322eea9ed06) Co-authored-by: ov2k <ov2k.github at gmail.com> files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 47e1c8602197..01d67a5a498f 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2041,9 +2041,9 @@ This results in types that are limited relative to types defined in Python: :ref:`sub-interpreters <sub-interpreter-support>`, so they should not include any subinterpreter-specific state. -Also, since :c:type:`PyTypeObject` is not part of the :ref:`stable ABI <stable>`, -any extension modules using static types must be compiled for a specific -Python minor version. +Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API +<stable>` as an opaque struct, any extension modules using static types must be +compiled for a specific Python minor version. .. _heap-types: From webhook-mailer at python.org Thu Aug 25 09:42:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 25 Aug 2022 13:42:38 -0000 Subject: [Python-checkins] Clarify API stability of PyTypeObject in relation to static types. (GH-96217) Message-ID: <mailman.823.1661434959.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2f88289cf59d7f0941534e40bdd41a5f26f1c605 commit: 2f88289cf59d7f0941534e40bdd41a5f26f1c605 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-25T06:42:32-07:00 summary: Clarify API stability of PyTypeObject in relation to static types. (GH-96217) Fixes: https://github.com/python/cpython/issues/95300 Related: https://github.com/python/cpython/issues/91271 (cherry picked from commit caa2a9799a47294441e4206037620322eea9ed06) Co-authored-by: ov2k <ov2k.github at gmail.com> files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 8d7a2ed75fc9..9bb0e6dbbcf8 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2047,9 +2047,9 @@ This results in types that are limited relative to types defined in Python: :ref:`sub-interpreters <sub-interpreter-support>`, so they should not include any subinterpreter-specific state. -Also, since :c:type:`PyTypeObject` is not part of the :ref:`stable ABI <stable>`, -any extension modules using static types must be compiled for a specific -Python minor version. +Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API +<stable>` as an opaque struct, any extension modules using static types must be +compiled for a specific Python minor version. .. _heap-types: From webhook-mailer at python.org Thu Aug 25 15:19:50 2022 From: webhook-mailer at python.org (zware) Date: Thu, 25 Aug 2022 19:19:50 -0000 Subject: [Python-checkins] gh-96272: Replace `test_source_encoding`'s `test_pep263` with `test_import_encoded_module` from `test_imp` (GH-96275) Message-ID: <mailman.824.1661455191.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ce1e73fbfd9ed165b20ff1c25367f1b9f0674263 commit: ce1e73fbfd9ed165b20ff1c25367f1b9f0674263 branch: main author: Michael Droettboom <mdboom at gmail.com> committer: zware <zachary.ware at gmail.com> date: 2022-08-25T14:19:16-05:00 summary: gh-96272: Replace `test_source_encoding`'s `test_pep263` with `test_import_encoded_module` from `test_imp` (GH-96275) Editors don't agree that `test_source_encoding.py` was valid koi8-r, making it hard to edit that file without the editor breaking it in some way (see gh-96272). Only one test actually relied on the koi8-r encoding and it was a duplicate of a test from the deprecated `imp` module's `test_imp`, so here we replace `test_pep263` with `test_import_encoded_module` stolen from `test_imp` and set `test_source_encoding.py`'s encoding to utf-8 to make editing it easier going forward. files: M Lib/test/test_imp.py M Lib/test/test_source_encoding.py diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index d44dc6b49f2..35b6afa91eb 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -66,11 +66,7 @@ def setUp(self): self.test_strings = mod.test_strings self.test_path = mod.__path__ - def test_import_encoded_module(self): - for modname, encoding, teststr in self.test_strings: - mod = importlib.import_module('test.encoded_modules.' - 'module_' + modname) - self.assertEqual(teststr, mod.test) + # test_import_encoded_module moved to test_source_encoding.py def test_find_module_encoding(self): for mod, encoding, _ in self.test_strings: diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index 8d7b573c7e9..8e68b4eae33 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -1,4 +1,4 @@ -# -*- coding: koi8-r -*- +# -*- coding: utf-8 -*- import unittest from test.support import script_helper, captured_stdout, requires_subprocess @@ -12,15 +12,14 @@ class MiscSourceEncodingTest(unittest.TestCase): - def test_pep263(self): - self.assertEqual( - "?????".encode("utf-8"), - b'\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd' - ) - self.assertEqual( - "\?".encode("utf-8"), - b'\\\xd0\x9f' - ) + def test_import_encoded_module(self): + from test.encoded_modules import test_strings + # Make sure we're actually testing something + self.assertGreaterEqual(len(test_strings), 1) + for modname, encoding, teststr in test_strings: + mod = importlib.import_module('test.encoded_modules.' + 'module_' + modname) + self.assertEqual(teststr, mod.test) def test_compilestring(self): # see #1882 From webhook-mailer at python.org Thu Aug 25 15:23:53 2022 From: webhook-mailer at python.org (zooba) Date: Thu, 25 Aug 2022 19:23:53 -0000 Subject: [Python-checkins] bpo-46744: Support "-Win32" and make platform flags case insensitive in Windows build scripts. (GH-31803) Message-ID: <mailman.825.1661455434.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1288097088dcf3bad3799bd5867e7675515a5b18 commit: 1288097088dcf3bad3799bd5867e7675515a5b18 branch: main author: conioh <10606081+conioh at users.noreply.github.com> committer: zooba <steve.dower at microsoft.com> date: 2022-08-25T20:23:42+01:00 summary: bpo-46744: Support "-Win32" and make platform flags case insensitive in Windows build scripts. (GH-31803) files: M Tools/msi/build.bat M Tools/msi/buildrelease.bat diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 425558f99d59..8771d004211e 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -12,15 +12,16 @@ set BUILDPACK= set REBUILD= :CheckOpts -if "%~1" EQU "-h" goto Help -if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts -if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts -if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts -if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts -if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts +if "%~1" EQU "-h" goto Help +if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if /I "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts +if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts +if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts +if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts +if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 0373c9f7b836..ccec4da12c42 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -44,27 +44,28 @@ set BUILDZIP=1 :CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts -if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts -if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts -if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts -if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if /I "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts +if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts +if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts +if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts +if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 From webhook-mailer at python.org Thu Aug 25 15:50:57 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 25 Aug 2022 19:50:57 -0000 Subject: [Python-checkins] bpo-46744: Support "-Win32" and make platform flags case insensitive in Windows build scripts. (GH-31803) Message-ID: <mailman.826.1661457058.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7604456f24af51e2df3c60ef6f1fe63bd06632ae commit: 7604456f24af51e2df3c60ef6f1fe63bd06632ae branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-25T12:50:48-07:00 summary: bpo-46744: Support "-Win32" and make platform flags case insensitive in Windows build scripts. (GH-31803) (cherry picked from commit 1288097088dcf3bad3799bd5867e7675515a5b18) Co-authored-by: conioh <10606081+conioh at users.noreply.github.com> files: M Tools/msi/build.bat M Tools/msi/buildrelease.bat diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 425558f99d59..8771d004211e 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -12,15 +12,16 @@ set BUILDPACK= set REBUILD= :CheckOpts -if "%~1" EQU "-h" goto Help -if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts -if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts -if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts -if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts -if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts +if "%~1" EQU "-h" goto Help +if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if /I "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts +if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts +if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts +if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts +if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 0373c9f7b836..ccec4da12c42 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -44,27 +44,28 @@ set BUILDZIP=1 :CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts -if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts -if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts -if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts -if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if /I "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts +if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts +if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts +if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts +if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 From webhook-mailer at python.org Thu Aug 25 16:16:22 2022 From: webhook-mailer at python.org (zooba) Date: Thu, 25 Aug 2022 20:16:22 -0000 Subject: [Python-checkins] bpo-46744: Support "-Win32" and make platform flags case insensitive in Windows build scripts. (GH-31803) Message-ID: <mailman.827.1661458583.3313.python-checkins@python.org> https://github.com/python/cpython/commit/fa118f0cd32e9b6cba68df10a176b502407243c8 commit: fa118f0cd32e9b6cba68df10a176b502407243c8 branch: 3.10 author: Steve Dower <steve.dower at python.org> committer: zooba <steve.dower at microsoft.com> date: 2022-08-25T21:16:15+01:00 summary: bpo-46744: Support "-Win32" and make platform flags case insensitive in Windows build scripts. (GH-31803) Co-authored-by: conioh <10606081+conioh at users.noreply.github.com> files: M Tools/msi/build.bat M Tools/msi/buildrelease.bat diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 2bdaca23f95b..99c0767fe938 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -11,14 +11,15 @@ set BUILDPACK= set REBUILD= :CheckOpts -if "%~1" EQU "-h" goto Help -if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts -if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts -if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts -if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts +if "%~1" EQU "-h" goto Help +if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts +if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts +if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts +if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 69dd145aaf26..7def39fdc810 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -43,26 +43,27 @@ set BUILDZIP=1 :CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts -if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts -if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts -if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts +if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts +if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts +if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 From webhook-mailer at python.org Thu Aug 25 17:23:17 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 25 Aug 2022 21:23:17 -0000 Subject: [Python-checkins] gh-96276: suppress SyntaxWarning in test_compile (GH-96277) Message-ID: <mailman.828.1661462598.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1e743616ac3f9466bc50768ecaf0860116bf4e59 commit: 1e743616ac3f9466bc50768ecaf0860116bf4e59 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-25T22:23:06+01:00 summary: gh-96276: suppress SyntaxWarning in test_compile (GH-96277) files: M Lib/test/test_compile.py diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index c64e4e55f44..d7b78f686ef 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -8,6 +8,7 @@ import tempfile import types import textwrap +import warnings from test import support from test.support import script_helper, requires_debug_ranges from test.support.os_helper import FakePath @@ -1231,7 +1232,9 @@ def f(): with self.subTest(body): namespace = {} source = textwrap.dedent(source_template.format(body)) - exec(source, namespace) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', SyntaxWarning) + exec(source, namespace) code = namespace["f"].__code__ self.assertOpcodeSourcePositionIs( code, From webhook-mailer at python.org Thu Aug 25 17:46:26 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Thu, 25 Aug 2022 21:46:26 -0000 Subject: [Python-checkins] gh-90110: Update the c-analyzer Tool (gh-96255) Message-ID: <mailman.829.1661463988.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d45d5c277a386aa694d582aafc6d1f06da5eab3f commit: d45d5c277a386aa694d582aafc6d1f06da5eab3f branch: main author: Eric Snow <ericsnowcurrently at gmail.com> committer: ericsnowcurrently <ericsnowcurrently at gmail.com> date: 2022-08-25T15:46:08-06:00 summary: gh-90110: Update the c-analyzer Tool (gh-96255) Here we automatically ignore uses of _PyArg_Parser, "kwlist" arrays, and module/type defs. That way new uses don't trigger false positives in the c-analyzer check script. files: M Tools/c-analyzer/c_parser/info.py M Tools/c-analyzer/cpython/_analyzer.py M Tools/c-analyzer/cpython/globals-to-fix.tsv M Tools/c-analyzer/cpython/ignored.tsv diff --git a/Tools/c-analyzer/c_parser/info.py b/Tools/c-analyzer/c_parser/info.py index e9783ccc9535..3fa9fefbd5ec 100644 --- a/Tools/c-analyzer/c_parser/info.py +++ b/Tools/c-analyzer/c_parser/info.py @@ -792,6 +792,7 @@ def _from_row(cls, row): if kind is not cls.kind: raise TypeError(f'expected kind {cls.kind.value!r}, got {row!r}') fileinfo = FileInfo.from_raw(filename) + extra = None if isinstance(data, str): data, extra = cls._parse_data(data, fmt='row') if extra: diff --git a/Tools/c-analyzer/cpython/_analyzer.py b/Tools/c-analyzer/cpython/_analyzer.py index 741fbaddf16d..4a11fc99a406 100644 --- a/Tools/c-analyzer/cpython/_analyzer.py +++ b/Tools/c-analyzer/cpython/_analyzer.py @@ -60,6 +60,46 @@ # {ID => reason} } +# XXX We should be handling these through known.tsv. +_OTHER_SUPPORTED_TYPES = { + # Holds tuple of strings, which we statically initialize: + '_PyArg_Parser', + # Uses of these should be const, but we don't worry about it. + 'PyModuleDef', + 'PyModuleDef_Slot[]', + 'PyType_Spec', + 'PyType_Slot[]', + 'PyMethodDef', + 'PyMethodDef[]', + 'PyMemberDef[]', + 'PyGetSetDef[]', + 'PyNumberMethods', + 'PySequenceMethods', + 'PyMappingMethods', + 'PyAsyncMethods', + 'PyBufferProcs', + 'PyStructSequence_Field[]', + 'PyStructSequence_Desc', +} + +# XXX We should normalize all cases to a single name, +# e.g. "kwlist" (currently the most common). +_KWLIST_VARIANTS = [ + ('*', 'kwlist'), + ('*', 'keywords'), + ('*', 'kwargs'), + ('Modules/_csv.c', 'dialect_kws'), + ('Modules/_datetimemodule.c', 'date_kws'), + ('Modules/_datetimemodule.c', 'datetime_kws'), + ('Modules/_datetimemodule.c', 'time_kws'), + ('Modules/_datetimemodule.c', 'timezone_kws'), + ('Modules/_lzmamodule.c', 'optnames'), + ('Modules/_lzmamodule.c', 'arg_names'), + ('Modules/cjkcodecs/multibytecodec.c', 'incnewkwarglist'), + ('Modules/cjkcodecs/multibytecodec.c', 'streamkwarglist'), + ('Modules/socketmodule.c', 'kwnames'), +] + KINDS = frozenset((*KIND.TYPES, KIND.VARIABLE)) @@ -202,6 +242,8 @@ def _check_typedep(decl, typedecl, types, knowntypes): # XXX Fail? return 'typespec (missing)' elif typedecl is _info.UNKNOWN: + if _has_other_supported_type(decl): + return None # XXX Is this right? return 'typespec (unknown)' elif not isinstance(typedecl, TypeDeclaration): @@ -216,12 +258,42 @@ def _check_typedep(decl, typedecl, types, knowntypes): elif decl.kind is KIND.VARIABLE: if not is_process_global(decl): return None + if _is_kwlist(decl): + return None + if _has_other_supported_type(decl): + return None checked = _check_vartype(decl, typedecl, types, knowntypes) return 'mutable' if checked is FIXED_TYPE else checked else: raise NotImplementedError(decl) +def _is_kwlist(decl): + # keywords for PyArg_ParseTupleAndKeywords() + # "static char *name[]" -> "static const char * const name[]" + # XXX These should be made const. + for relpath, name in _KWLIST_VARIANTS: + if decl.name == name: + if relpath == '*': + break + assert os.path.isabs(decl.file.filename) + relpath = os.path.normpath(relpath) + if decl.file.filename.endswith(os.path.sep + relpath): + break + else: + return False + vartype = ''.join(str(decl.vartype).split()) + return vartype == 'char*[]' + + +def _has_other_supported_type(decl): + vartype = str(decl.vartype).split() + if vartype[0] == 'struct': + vartype = vartype[1:] + vartype = ''.join(vartype) + return vartype in _OTHER_SUPPORTED_TYPES + + def _check_vartype(decl, typedecl, types, knowntypes): """Return failure reason.""" checked = _check_typespec(decl, typedecl, types, knowntypes) diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index d760d6012c0e..e3a0f1a37604 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -455,7 +455,7 @@ Objects/typeobject.c - next_version_tag - Objects/typeobject.c resolve_slotdups ptrs - Parser/pegen.c - memo_statistics - Python/bootstrap_hash.c - urandom_cache - -Python/ceval.c make_pending_calls busy - +Python/ceval_gil.c make_pending_calls busy - Python/ceval.c _PyEval_SetProfile reentrant - Python/ceval.c _PyEval_SetTrace reentrant - Python/import.c - import_lock_level - @@ -534,6 +534,8 @@ Modules/_io/winconsoleio.c - _PyWindowsConsoleIO_Type - # initialized once Modules/_functoolsmodule.c - kwd_mark - Modules/_io/_iomodule.c - _PyIO_empty_bytes - +Modules/_testcapi/heaptype.c - _testcapimodule - +Modules/_testcapi/unicode.c - _testcapimodule - Modules/_tracemalloc.c - tracemalloc_empty_traceback - Modules/signalmodule.c - DefaultHandler - Modules/signalmodule.c - IgnoreHandler - diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 04c540f8864d..b6508a0c4991 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -6,242 +6,14 @@ filename funcname name reason Python/pylifecycle.c - _PyRuntime - -#----------------------- -# _PyArg_Parser (holds tuple of strings) -# XXX The analyzer should ignore these. - -# core -Objects/clinic/bytearrayobject.c.h bytearray___init__ _parser - -Objects/clinic/bytearrayobject.c.h bytearray_decode _parser - -Objects/clinic/bytearrayobject.c.h bytearray_hex _parser - -Objects/clinic/bytearrayobject.c.h bytearray_rsplit _parser - -Objects/clinic/bytearrayobject.c.h bytearray_split _parser - -Objects/clinic/bytearrayobject.c.h bytearray_splitlines _parser - -Objects/clinic/bytearrayobject.c.h bytearray_translate _parser - -Objects/clinic/bytesobject.c.h bytes_decode _parser - -Objects/clinic/bytesobject.c.h bytes_hex _parser - -Objects/clinic/bytesobject.c.h bytes_new _parser - -Objects/clinic/bytesobject.c.h bytes_rsplit _parser - -Objects/clinic/bytesobject.c.h bytes_split _parser - -Objects/clinic/bytesobject.c.h bytes_splitlines _parser - -Objects/clinic/bytesobject.c.h bytes_translate _parser - -Objects/clinic/codeobject.c.h code__varname_from_oparg _parser - -Objects/clinic/codeobject.c.h code_replace _parser - -Objects/clinic/complexobject.c.h complex_new _parser - -Objects/clinic/descrobject.c.h mappingproxy_new _parser - -Objects/clinic/descrobject.c.h property_init _parser - -Objects/clinic/enumobject.c.h enum_new _parser - -Objects/clinic/funcobject.c.h func_new _parser - -Objects/clinic/listobject.c.h list_sort _parser - -Objects/clinic/longobject.c.h int_from_bytes _parser - -Objects/clinic/longobject.c.h int_to_bytes _parser - -Objects/clinic/longobject.c.h long_new _parser - -Objects/clinic/memoryobject.c.h memoryview _parser - -Objects/clinic/memoryobject.c.h memoryview_cast _parser - -Objects/clinic/memoryobject.c.h memoryview_hex _parser - -Objects/clinic/memoryobject.c.h memoryview_tobytes _parser - -Objects/clinic/moduleobject.c.h module___init__ _parser - -Objects/clinic/odictobject.c.h OrderedDict_fromkeys _parser - -Objects/clinic/odictobject.c.h OrderedDict_move_to_end _parser - -Objects/clinic/odictobject.c.h OrderedDict_pop _parser - -Objects/clinic/odictobject.c.h OrderedDict_popitem _parser - -Objects/clinic/odictobject.c.h OrderedDict_setdefault _parser - -Objects/clinic/structseq.c.h structseq_new _parser - -Objects/clinic/unicodeobject.c.h unicode_encode _parser - -Objects/clinic/unicodeobject.c.h unicode_expandtabs _parser - -Objects/clinic/unicodeobject.c.h unicode_new _parser - -Objects/clinic/unicodeobject.c.h unicode_rsplit _parser - -Objects/clinic/unicodeobject.c.h unicode_split _parser - -Objects/clinic/unicodeobject.c.h unicode_splitlines _parser - -Python/clinic/Python-tokenize.c.h tokenizeriter_new _parser - -Python/clinic/_warnings.c.h warnings_warn _parser - -Python/clinic/_warnings.c.h warnings_warn_explicit _parser - -Python/clinic/bltinmodule.c.h builtin___import__ _parser - -Python/clinic/bltinmodule.c.h builtin_compile _parser - -Python/clinic/bltinmodule.c.h builtin_exec _parser - -Python/clinic/bltinmodule.c.h builtin_pow _parser - -Python/clinic/bltinmodule.c.h builtin_print _parser - -Python/clinic/bltinmodule.c.h builtin_round _parser - -Python/clinic/bltinmodule.c.h builtin_sum _parser - -Python/clinic/import.c.h _imp_find_frozen _parser - -Python/clinic/import.c.h _imp_source_hash _parser - -Python/clinic/sysmodule.c.h sys_addaudithook _parser - -Python/clinic/sysmodule.c.h sys_set_coroutine_origin_tracking_depth _parser - -Python/clinic/traceback.c.h tb_new _parser - - -# builtin modules -Modules/clinic/_codecsmodule.c.h _codecs_decode _parser - -Modules/clinic/_codecsmodule.c.h _codecs_encode _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_expand _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_groupdict _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_groups _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_findall _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_finditer _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_fullmatch _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_match _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_scanner _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_search _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_split _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_sub _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_subn _parser - -Modules/clinic/_sre.c.h _sre_SRE_Scanner_match _parser - -Modules/clinic/_sre.c.h _sre_SRE_Scanner_search _parser - -Modules/clinic/_sre.c.h _sre_compile _parser - -Modules/clinic/gcmodule.c.h gc_collect _parser - -Modules/clinic/gcmodule.c.h gc_get_objects _parser - -Modules/clinic/itertoolsmodule.c.h itertools_accumulate _parser - -Modules/clinic/itertoolsmodule.c.h itertools_combinations _parser - -Modules/clinic/itertoolsmodule.c.h itertools_combinations_with_replacement _parser - -Modules/clinic/itertoolsmodule.c.h itertools_compress _parser - -Modules/clinic/itertoolsmodule.c.h itertools_count _parser - -Modules/clinic/itertoolsmodule.c.h itertools_groupby _parser - -Modules/clinic/itertoolsmodule.c.h itertools_permutations _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_dir _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_file _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_symlink _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_stat _parser - -Modules/clinic/posixmodule.c.h os__exit _parser - -Modules/clinic/posixmodule.c.h os__path_normpath _parser - -Modules/clinic/posixmodule.c.h os_access _parser - -Modules/clinic/posixmodule.c.h os_chdir _parser - -Modules/clinic/posixmodule.c.h os_chmod _parser - -Modules/clinic/posixmodule.c.h os_close _parser - -Modules/clinic/posixmodule.c.h os_device_encoding _parser - -Modules/clinic/posixmodule.c.h os_dup2 _parser - -Modules/clinic/posixmodule.c.h os_fspath _parser - -Modules/clinic/posixmodule.c.h os_fstat _parser - -Modules/clinic/posixmodule.c.h os_listdir _parser - -Modules/clinic/posixmodule.c.h os_lstat _parser - -Modules/clinic/posixmodule.c.h os_mkdir _parser - -Modules/clinic/posixmodule.c.h os_open _parser - -Modules/clinic/posixmodule.c.h os_remove _parser - -Modules/clinic/posixmodule.c.h os_rename _parser - -Modules/clinic/posixmodule.c.h os_replace _parser - -Modules/clinic/posixmodule.c.h os_rmdir _parser - -Modules/clinic/posixmodule.c.h os_scandir _parser - -Modules/clinic/posixmodule.c.h os_stat _parser - -Modules/clinic/posixmodule.c.h os_unlink _parser - -Modules/clinic/posixmodule.c.h os_utime _parser - - -# extension modules -Modules/clinic/_asynciomodule.c.h _asyncio_Task__check_future _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future___init__ _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future_add_done_callback _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future_cancel _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task___init__ _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_cancel _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_get_stack _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_print_stack _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__enter_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__get_event_loop _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__leave_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__register_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__unregister_task _parser - -Modules/clinic/_bisectmodule.c.h _bisect_bisect_left _parser - -Modules/clinic/_bisectmodule.c.h _bisect_bisect_right _parser - -Modules/clinic/_bisectmodule.c.h _bisect_insort_left _parser - -Modules/clinic/_bisectmodule.c.h _bisect_insort_right _parser - -Modules/clinic/_bz2module.c.h _bz2_BZ2Decompressor_decompress _parser - -Modules/clinic/_csv.c.h _csv_unregister_dialect _parser - -Modules/clinic/_csv.c.h _csv_get_dialect _parser - -Modules/clinic/_csv.c.h _csv_field_size_limit _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_move _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_replace _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_set_userptr _parser - -Modules/clinic/_cursesmodule.c.h _curses_setupterm _parser - -Modules/clinic/_datetimemodule.c.h datetime_datetime_now _parser - -Modules/clinic/_datetimemodule.c.h iso_calendar_date_new _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_get _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_setdefault _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_find _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_findall _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_findtext _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_get _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_iter _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_iterfind _parser - -Modules/clinic/_elementtree.c.h _elementtree_TreeBuilder___init__ _parser - -Modules/clinic/_elementtree.c.h _elementtree_XMLParser___init__ _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_nextkey _parser - -Modules/clinic/_hashopenssl.c.h EVP_new _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_HMAC_update _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_hmac_new _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_hmac_singleshot _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_md5 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha1 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha224 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha256 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha384 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha512 _parser - -Modules/clinic/_hashopenssl.c.h pbkdf2_hmac _parser - -Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor___init__ _parser - -Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor_decompress _parser - -Modules/clinic/_opcode.c.h _opcode_stack_effect _parser - -Modules/clinic/_pickle.c.h _pickle_Pickler___init__ _parser - -Modules/clinic/_pickle.c.h _pickle_Unpickler___init__ _parser - -Modules/clinic/_pickle.c.h _pickle_dump _parser - -Modules/clinic/_pickle.c.h _pickle_dumps _parser - -Modules/clinic/_pickle.c.h _pickle_load _parser - -Modules/clinic/_pickle.c.h _pickle_loads _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_get _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put_nowait _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_bio _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_socket _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_get_ca_certs _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_load_cert_chain _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_load_verify_locations _parser - -Modules/clinic/_ssl.c.h _ssl__SSLSocket_get_channel_binding _parser - -Modules/clinic/_ssl.c.h _ssl_txt2obj _parser - -Modules/clinic/_struct.c.h Struct___init__ _parser - -Modules/clinic/_struct.c.h Struct_unpack_from _parser - -Modules/clinic/_struct.c.h unpack_from _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_increment_count_clinic _parser - -Modules/clinic/_winapi.c.h _winapi_ConnectNamedPipe _parser - -Modules/clinic/_winapi.c.h _winapi_GetFileType _parser - -Modules/clinic/_winapi.c.h _winapi_LCMapStringEx _parser - -Modules/clinic/_winapi.c.h _winapi_ReadFile _parser - -Modules/clinic/_winapi.c.h _winapi_WriteFile _parser - -Modules/clinic/_winapi.c.h _winapi__mimetypes_read_windows_registry _parser - -Modules/clinic/arraymodule.c.h array_array_extend _parser - -Modules/clinic/arraymodule.c.h array_array_fromfile _parser - -Modules/clinic/arraymodule.c.h array_array_tofile _parser - -Modules/clinic/arraymodule.c.h array_array___reduce_ex__ _parser - -Modules/clinic/binascii.c.h binascii_a2b_base64 _parser - -Modules/clinic/binascii.c.h binascii_a2b_qp _parser - -Modules/clinic/binascii.c.h binascii_b2a_base64 _parser - -Modules/clinic/binascii.c.h binascii_b2a_hex _parser - -Modules/clinic/binascii.c.h binascii_b2a_qp _parser - -Modules/clinic/binascii.c.h binascii_b2a_uu _parser - -Modules/clinic/binascii.c.h binascii_hexlify _parser - -Modules/clinic/cmathmodule.c.h cmath_isclose _parser - -Modules/clinic/grpmodule.c.h grp_getgrgid _parser - -Modules/clinic/grpmodule.c.h grp_getgrnam _parser - -Modules/clinic/mathmodule.c.h math_isclose _parser - -Modules/clinic/mathmodule.c.h math_prod _parser - -Modules/clinic/md5module.c.h _md5_md5 _parser - -Modules/clinic/overlapped.c.h _overlapped_Overlapped _parser - -Modules/clinic/pyexpat.c.h pyexpat_ParserCreate _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ExternalEntityParserCreate _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_Parse _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ParseFile _parser - -Modules/clinic/sha1module.c.h _sha1_sha1 _parser - -Modules/clinic/sha256module.c.h _sha256_sha224 _parser - -Modules/clinic/sha256module.c.h _sha256_sha256 _parser - -Modules/clinic/sha512module.c.h _sha512_sha384 _parser - -Modules/clinic/sha512module.c.h _sha512_sha512 _parser - -Modules/clinic/socketmodule.c.h sock_initobj _parser - -Modules/clinic/zlibmodule.c.h zlib_Compress_compress _parser - -Modules/clinic/zlibmodule.c.h zlib_Compress_flush _parser - -Modules/clinic/zlibmodule.c.h zlib_Decompress_decompress _parser - -Modules/clinic/zlibmodule.c.h zlib_Decompress_flush _parser - -Modules/clinic/zlibmodule.c.h zlib_compress _parser - -Modules/clinic/zlibmodule.c.h zlib_compressobj _parser - -Modules/clinic/zlibmodule.c.h zlib_decompress _parser - -Modules/clinic/zlibmodule.c.h zlib_decompressobj _parser - +# All uses of _PyArg_Parser are handled in c-analyzr/cpython/_analyzer.py. #----------------------- # others +# XXX The analyzer should have ignored these. +Modules/_io/_iomodule.c - _PyIO_Module - +Modules/_sqlite/module.c - _sqlite3module - ################################## # forward/extern references @@ -562,1307 +334,8 @@ Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput AST_LITERAL_EVAL_INITIALIZED # These are all variables that we will be leaving global. -#----------------------- -# keywords for PyArg_ParseTupleAndKeywords() -# "static char *name[]" -> "static const char * const name[]" - -Modules/cjkcodecs/multibytecodec.c - incnewkwarglist - -Modules/cjkcodecs/multibytecodec.c - streamkwarglist - -Modules/_csv.c - dialect_kws - -Modules/_datetimemodule.c date_fromisocalendar keywords - -Modules/_datetimemodule.c - date_kws - -Modules/_datetimemodule.c date_strftime keywords - -Modules/_datetimemodule.c datetime_astimezone keywords - -Modules/_datetimemodule.c datetime_combine keywords - -Modules/_datetimemodule.c datetime_fromtimestamp keywords - -Modules/_datetimemodule.c datetime_isoformat keywords - -Modules/_datetimemodule.c - datetime_kws - -Modules/_datetimemodule.c delta_new keywords - -Modules/_datetimemodule.c time_isoformat keywords - -Modules/_datetimemodule.c - time_kws - -Modules/_datetimemodule.c time_strftime keywords - -Modules/_datetimemodule.c - timezone_kws - -Modules/_decimal/_decimal.c context_init kwlist - -Modules/_decimal/_decimal.c ctxmanager_new kwlist - -Modules/_decimal/_decimal.c ctx_mpd_qpow kwlist - -Modules/_decimal/_decimal.c dec_mpd_class kwlist - -Modules/_decimal/_decimal.c dec_mpd_compare_total kwlist - -Modules/_decimal/_decimal.c dec_mpd_compare_total_mag kwlist - -Modules/_decimal/_decimal.c dec_mpd_isnormal kwlist - -Modules/_decimal/_decimal.c dec_mpd_issubnormal kwlist - -Modules/_decimal/_decimal.c dec_mpd_qand kwlist - -Modules/_decimal/_decimal.c dec_mpd_qcompare kwlist - -Modules/_decimal/_decimal.c dec_mpd_qcompare_signal kwlist - -Modules/_decimal/_decimal.c dec_mpd_qcopy_sign kwlist - -Modules/_decimal/_decimal.c dec_mpd_qexp kwlist - -Modules/_decimal/_decimal.c dec_mpd_qfma kwlist - -Modules/_decimal/_decimal.c dec_mpd_qinvert kwlist - -Modules/_decimal/_decimal.c dec_mpd_qln kwlist - -Modules/_decimal/_decimal.c dec_mpd_qlog10 kwlist - -Modules/_decimal/_decimal.c dec_mpd_qlogb kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmax kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmax_mag kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmin kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmin_mag kwlist - -Modules/_decimal/_decimal.c dec_mpd_qnext_minus kwlist - -Modules/_decimal/_decimal.c dec_mpd_qnext_plus kwlist - -Modules/_decimal/_decimal.c dec_mpd_qnext_toward kwlist - -Modules/_decimal/_decimal.c dec_mpd_qor kwlist - -Modules/_decimal/_decimal.c dec_mpd_qquantize kwlist - -Modules/_decimal/_decimal.c dec_mpd_qreduce kwlist - -Modules/_decimal/_decimal.c dec_mpd_qrem_near kwlist - -Modules/_decimal/_decimal.c dec_mpd_qrotate kwlist - -Modules/_decimal/_decimal.c dec_mpd_qscaleb kwlist - -Modules/_decimal/_decimal.c dec_mpd_qshift kwlist - -Modules/_decimal/_decimal.c dec_mpd_qsqrt kwlist - -Modules/_decimal/_decimal.c dec_mpd_qxor kwlist - -Modules/_decimal/_decimal.c dec_mpd_same_quantum kwlist - -Modules/_decimal/_decimal.c dec_mpd_to_eng kwlist - -Modules/_decimal/_decimal.c dec_new kwlist - -Modules/_decimal/_decimal.c PyDec_ToIntegralExact kwlist - -Modules/_decimal/_decimal.c PyDec_ToIntegralValue kwlist - -Modules/_elementtree.c element_setstate_from_Python kwlist - -Modules/faulthandler.c faulthandler_dump_traceback_later kwlist - -Modules/faulthandler.c faulthandler_dump_traceback_py kwlist - -Modules/faulthandler.c faulthandler_py_enable kwlist - -Modules/faulthandler.c faulthandler_register_py kwlist - -Modules/_functoolsmodule.c functools_cmp_to_key kwargs - -Modules/_functoolsmodule.c keyobject_call kwargs - -Modules/_functoolsmodule.c lru_cache_new keywords - -Modules/itertoolsmodule.c repeat_new kwargs - -Modules/_json.c encoder_call kwlist - -Modules/_json.c encoder_new kwlist - -Modules/_json.c scanner_call kwlist - -Modules/_json.c scanner_new kwlist - -Modules/_lsprof.c profiler_enable kwlist - -Modules/_lsprof.c profiler_init kwlist - -Modules/_lzmamodule.c Compressor_init arg_names - -Modules/_lzmamodule.c parse_filter_spec_bcj optnames - -Modules/_lzmamodule.c parse_filter_spec_delta optnames - -Modules/_lzmamodule.c parse_filter_spec_lzma optnames - -Modules/mmapmodule.c new_mmap_object keywords - -Modules/nismodule.c nis_cat kwlist - -Modules/nismodule.c nis_maps kwlist - -Modules/nismodule.c nis_match kwlist - -Modules/signalmodule.c signal_set_wakeup_fd kwlist - -Modules/socketmodule.c sock_initobj keywords - -Modules/socketmodule.c sock_recvfrom_into kwlist - -Modules/socketmodule.c sock_recv_into kwlist - -Modules/socketmodule.c sock_sendmsg_afalg keywords - -Modules/socketmodule.c socket_getaddrinfo kwnames - -Modules/_sqlite/connection.c pysqlite_connection_backup keywords - -Modules/_sqlite/connection.c pysqlite_connection_create_aggregate kwlist - -Modules/_sqlite/connection.c pysqlite_connection_create_function kwlist - -Modules/_sqlite/connection.c pysqlite_connection_cursor kwlist - -Modules/_sqlite/connection.c pysqlite_connection_init kwlist - -Modules/_sqlite/connection.c pysqlite_connection_set_authorizer kwlist - -Modules/_sqlite/connection.c pysqlite_connection_set_progress_handler kwlist - -Modules/_sqlite/connection.c pysqlite_connection_set_trace_callback kwlist - -Modules/_sqlite/cursor.c pysqlite_cursor_fetchmany kwlist - -Modules/_sqlite/module.c module_complete kwlist - -Modules/_sqlite/module.c module_connect kwlist - -Modules/_sqlite/module.c module_enable_shared_cache kwlist - -Modules/syslogmodule.c syslog_openlog keywords - -Modules/_xxsubinterpretersmodule.c channel_close kwlist - -Modules/_xxsubinterpretersmodule.c channel_destroy kwlist - -Modules/_xxsubinterpretersmodule.c channelid_new kwlist - -Modules/_xxsubinterpretersmodule.c channel_list_interpreters kwlist - -Modules/_xxsubinterpretersmodule.c channel_recv kwlist - -Modules/_xxsubinterpretersmodule.c channel_release kwlist - -Modules/_xxsubinterpretersmodule.c channel_send kwlist - -Modules/_xxsubinterpretersmodule.c interp_create kwlist - -Modules/_xxsubinterpretersmodule.c interp_destroy kwlist - -Modules/_xxsubinterpretersmodule.c interp_is_running kwlist - -Modules/_xxsubinterpretersmodule.c interp_run_string kwlist - -Modules/_xxsubinterpretersmodule.c object_is_shareable kwlist - -Modules/_zoneinfo.c zoneinfo_clear_cache kwlist - -Modules/_zoneinfo.c zoneinfo_from_file kwlist - -Modules/_zoneinfo.c zoneinfo_new kwlist - -Modules/_zoneinfo.c zoneinfo_no_cache kwlist - -Objects/exceptions.c ImportError_init kwlist - -Objects/interpreteridobject.c interpid_new kwlist - -Objects/weakrefobject.c weakref_call kwlist - -Objects/exceptions.c NameError_init kwlist - -Objects/exceptions.c AttributeError_init kwlist - -Python/_warnings.c warnings_warn_explicit kwd_list - -Python/bltinmodule.c builtin___import__ kwlist - -Python/bltinmodule.c min_max kwlist - -Python/bltinmodule.c zip_new kwlist - -Python/context.c contextvar_tp_new kwlist - -Python/sysmodule.c sys_getsizeof kwlist - -Python/sysmodule.c sys_set_asyncgen_hooks keywords - - -#----------------------- -# PyModuleDef - -# builtin modules -Modules/_abc.c - _abcmodule - -Modules/_codecsmodule.c - codecsmodule - -Modules/_collectionsmodule.c - _collectionsmodule - -Modules/_functoolsmodule.c - _functools_module - -Modules/_io/_iomodule.c - _PyIO_Module - -Modules/_localemodule.c - _localemodule - -Modules/_multiprocessing/posixshmem.c - _posixshmemmodule - -Modules/_sqlite/module.h - _sqlite3module - -Modules/_sre/sre.c - sremodule - -Modules/_ssl.c - _sslmodule_def - -Modules/_ssl.h - _sslmodule_def - -Modules/_stat.c - statmodule - -Modules/_testcapi/heaptype.c - _testcapimodule - -Modules/_testmultiphase.c - def_module_state_shared - -Modules/_threadmodule.c - thread_module - -Modules/_tracemalloc.c - module_def - -Modules/_typingmodule.c - typingmodule - -Modules/_weakref.c - weakrefmodule - -Modules/atexitmodule.c - atexitmodule - -Modules/errnomodule.c - errnomodule - -Modules/faulthandler.c - module_def - -Modules/gcmodule.c - gcmodule - -Modules/itertoolsmodule.c - itertoolsmodule - -Modules/posixmodule.c - posixmodule - -Modules/pwdmodule.c - pwdmodule - -Modules/signalmodule.c - signal_module - -Modules/symtablemodule.c - symtablemodule - -Modules/timemodule.c - timemodule - -Modules/xxlimited_35.c - xxmodule - -Python/Python-ast.c - _astmodule - -Python/Python-tokenize.c - _tokenizemodule - -Python/_warnings.c - warnings_module - -Python/bltinmodule.c - builtinsmodule - -Python/import.c - imp_module - -Python/marshal.c - marshalmodule - -Python/sysmodule.c - sysmodule - - -# extension modules -Modules/_asynciomodule.c - _asynciomodule - -Modules/_bisectmodule.c - _bisectmodule - -Modules/_blake2/blake2module.c - blake2_module - -Modules/_bz2module.c - _bz2module - -Modules/_contextvarsmodule.c - _contextvarsmodule - -Modules/_cryptmodule.c - cryptmodule - -Modules/_csv.c - _csvmodule - -Modules/_ctypes/_ctypes.c - _ctypesmodule - -Modules/_curses_panel.c - _curses_panelmodule - -Modules/_cursesmodule.c - _cursesmodule - -Modules/_datetimemodule.c - datetimemodule - -Modules/_decimal/_decimal.c - _decimal_module - -Modules/_elementtree.c - elementtreemodule - -Modules/_gdbmmodule.c - _gdbmmodule - -Modules/_hashopenssl.c - _hashlibmodule - -Modules/_heapqmodule.c - _heapqmodule - -Modules/_json.c - jsonmodule - -Modules/_lsprof.c - _lsprofmodule - -Modules/_lzmamodule.c - _lzmamodule - -Modules/_multiprocessing/multiprocessing.c - multiprocessing_module - -Modules/_opcode.c - opcodemodule - -Modules/_operator.c - operatormodule - -Modules/_pickle.c - _picklemodule - -Modules/_posixsubprocess.c - _posixsubprocessmodule - -Modules/_queuemodule.c - queuemodule - -Modules/_randommodule.c - _randommodule - -Modules/_sha3/sha3module.c - _sha3module - -Modules/_sqlite/module.c - _sqlite3module - -Modules/_statisticsmodule.c - statisticsmodule - -Modules/_struct.c - _structmodule - -Modules/_testcapi/unicode.c - _testcapimodule - -Modules/_tkinter.c - _tkintermodule - -Modules/_uuidmodule.c - uuidmodule - -Modules/_xxsubinterpretersmodule.c - interpretersmodule - -Modules/_zoneinfo.c - zoneinfomodule - -Modules/arraymodule.c - arraymodule - -Modules/audioop.c - audioopmodule - -Modules/binascii.c - binasciimodule - -Modules/cjkcodecs/multibytecodec.c - _multibytecodecmodule - -Modules/cmathmodule.c - cmathmodule - -Modules/fcntlmodule.c - fcntlmodule - -Modules/grpmodule.c - grpmodule - -Modules/mathmodule.c - mathmodule - -Modules/md5module.c - _md5module - -Modules/mmapmodule.c - mmapmodule - -Modules/nismodule.c - nismodule - -Modules/ossaudiodev.c - ossaudiodevmodule - -Modules/pyexpat.c - pyexpatmodule - -Modules/readline.c - readlinemodule - -Modules/resource.c - resourcemodule - -Modules/selectmodule.c - selectmodule - -Modules/sha1module.c - _sha1module - -Modules/sha256module.c - _sha256module - -Modules/sha512module.c - _sha512module - -Modules/socketmodule.c - socketmodule - -Modules/spwdmodule.c - spwdmodule - -Modules/syslogmodule.c - syslogmodule - -Modules/termios.c - termiosmodule - -Modules/unicodedata.c - unicodedata_module - -Modules/xxlimited.c - xxmodule - -Modules/xxmodule.c - xxmodule - -Modules/xxsubtype.c - xxsubtypemodule - -Modules/zlibmodule.c - zlibmodule - - -#----------------------- -# PyModuleDef_Slot - -Modules/_abc.c - _abcmodule_slots - -Modules/_bisectmodule.c - bisect_slots - -Modules/_blake2/blake2module.c - _blake2_slots - -Modules/_bz2module.c - _bz2_slots - -Modules/_codecsmodule.c - _codecs_slots - -Modules/_collectionsmodule.c - collections_slots - -Modules/_contextvarsmodule.c - _contextvars_slots - -Modules/_cryptmodule.c - _crypt_slots - -Modules/_csv.c - csv_slots - -Modules/_curses_panel.c - _curses_slots - -Modules/_dbmmodule.c - _dbmmodule_slots - -Modules/_functoolsmodule.c - _functools_slots - -Modules/_gdbmmodule.c - _gdbm_module_slots - -Modules/_hashopenssl.c - hashlib_slots - -Modules/_heapqmodule.c - heapq_slots - -Modules/_json.c - _json_slots - -Modules/_localemodule.c - _locale_slots - -Modules/_lsprof.c - _lsprofslots - -Modules/_lzmamodule.c - lzma_slots - -Modules/_multiprocessing/multiprocessing.c - multiprocessing_slots - -Modules/_operator.c - operator_slots - -Modules/_posixsubprocess.c - _posixsubprocess_slots - -Modules/_queuemodule.c - queuemodule_slots - -Modules/_randommodule.c - _random_slots - -Modules/_scproxy.c - _scproxy_slots - -Modules/_sha3/sha3module.c - _sha3_slots - -Modules/_sqlite/module.c - module_slots - -Modules/_sre.c - sre_slots - -Modules/_sre/sre.c - sre_slots - -Modules/_ssl.c - sslmodule_slots - -Modules/_stat.c - stat_slots - -Modules/_statisticsmodule.c - _statisticsmodule_slots - -Modules/_struct.c - _structmodule_slots - -Modules/_threadmodule.c - thread_module_slots - -Modules/_typingmodule.c - _typingmodule_slots - -Modules/_uuidmodule.c - uuid_slots - -Modules/_weakref.c - weakref_slots - -Modules/_winapi.c - winapi_slots - -Modules/_zoneinfo.c - zoneinfomodule_slots - -Modules/arraymodule.c - arrayslots - -Modules/atexitmodule.c - atexit_slots - -Modules/audioop.c - audioop_slots - -Modules/binascii.c - binascii_slots - -Modules/cjkcodecs/cjkcodecs.h - _cjk_slots - -Modules/cjkcodecs/multibytecodec.c - _multibytecodec_slots - -Modules/cmathmodule.c - cmath_slots - -Modules/errnomodule.c - errno_slots - -Modules/faulthandler.c - faulthandler_slots - -Modules/fcntlmodule.c - fcntl_slots - -Modules/gcmodule.c - gcmodule_slots - -Modules/gcmodule.c - gcmodule_slots - -Modules/grpmodule.c - grpmodule_slots - -Modules/itertoolsmodule.c - itertoolsmodule_slots - -Modules/mathmodule.c - math_slots - -Modules/md5module.c - _md5_slots - -Modules/mmapmodule.c - mmap_slots - -Modules/nismodule.c - nis_slots - -Modules/overlapped.c - overlapped_slots - -Modules/posixmodule.c - posixmodile_slots - -Modules/pwdmodule.c - pwdmodule_slots - -Modules/pyexpat.c - pyexpat_slots - -Modules/resource.c - resource_slots - -Modules/selectmodule.c - _select_slots - -Modules/sha1module.c - _sha1_slots - -Modules/sha256module.c - _sha256_slots - -Modules/sha512module.c - _sha512_slots - -Modules/signalmodule.c - signal_slots - -Modules/spwdmodule.c - spwdmodule_slots - -Modules/symtablemodule.c - symtable_slots - -Modules/syslogmodule.c - syslog_slots - -Modules/termios.c - termios_slots - -Modules/timemodule.c - time_slots - -Modules/unicodedata.c - unicodedata_slots - -Modules/xxlimited.c - xx_slots - -Modules/xxlimited_35.c - xx_slots - -Modules/xxmodule.c - xx_slots - -Modules/xxsubtype.c - xxsubtype_slots - -Modules/zlibmodule.c - zlib_slots - -Python/Python-ast.c - astmodule_slots - -Python/Python-tokenize.c - tokenizemodule_slots - -Python/_warnings.c - warnings_slots - -Python/marshal.c - marshalmodule_slots - - -#----------------------- -# PyMethodDef and PyMethodDef[], for static types and modules - -Modules/_abc.c - _abcmodule_methods - -Modules/_abc.c - _destroy_def - -Modules/_asynciomodule.c - FutureIter_methods - -Modules/_asynciomodule.c - FutureType_methods - -Modules/_asynciomodule.c - TaskType_methods - -Modules/_asynciomodule.c - TaskWakeupDef - -Modules/_asynciomodule.c - asyncio_methods - -Modules/_bisectmodule.c - bisect_methods - -Modules/_blake2/blake2b_impl.c - py_blake2b_methods - -Modules/_blake2/blake2module.c - blake2mod_functions - -Modules/_blake2/blake2s_impl.c - py_blake2s_methods - -Modules/_bz2module.c - BZ2Compressor_methods - -Modules/_bz2module.c - BZ2Decompressor_methods - -Modules/_codecsmodule.c - _codecs_functions - -Modules/_collectionsmodule.c - collections_methods - -Modules/_collectionsmodule.c - defdict_methods - -Modules/_collectionsmodule.c - deque_methods - -Modules/_collectionsmodule.c - dequeiter_methods - -Modules/_collectionsmodule.c - tuplegetter_methods - -Modules/_contextvarsmodule.c - _contextvars_methods - -Modules/_cryptmodule.c - crypt_methods - -Modules/_csv.c - Reader_methods - -Modules/_csv.c - Writer_methods - -Modules/_csv.c - csv_methods - -Modules/_csv.c - dialect_methods - -Modules/_ctypes/_ctypes.c - Array_methods - -Modules/_ctypes/_ctypes.c - CDataType_methods - -Modules/_ctypes/_ctypes.c - PyCData_methods - -Modules/_ctypes/_ctypes.c - PyCPointerType_methods - -Modules/_ctypes/_ctypes.c - PyCSimpleType_methods - -Modules/_ctypes/_ctypes.c - Simple_methods - -Modules/_ctypes/_ctypes.c - c_char_p_method - -Modules/_ctypes/_ctypes.c - c_void_p_method - -Modules/_ctypes/_ctypes.c - c_wchar_p_method - -Modules/_ctypes/callproc.c - _ctypes_module_methods - -Modules/_ctypes/stgdict.c - PyCStgDict_methods - -Modules/_curses_panel.c - PyCursesPanel_Methods - -Modules/_curses_panel.c - PyCurses_methods - -Modules/_cursesmodule.c - PyCursesWindow_Methods - -Modules/_cursesmodule.c - PyCurses_methods - -Modules/_datetimemodule.c - date_methods - -Modules/_datetimemodule.c - datetime_methods - -Modules/_datetimemodule.c - delta_methods - -Modules/_datetimemodule.c - iso_calendar_date_methods - -Modules/_datetimemodule.c - module_methods - -Modules/_datetimemodule.c - time_methods - -Modules/_datetimemodule.c - timezone_methods - -Modules/_datetimemodule.c - tzinfo_methods - -Modules/_dbmmodule.c - dbm_methods - -Modules/_dbmmodule.c - dbmmodule_methods - -Modules/_decimal/_decimal.c - _decimal_methods - -Modules/_decimal/_decimal.c - context_methods - -Modules/_decimal/_decimal.c - ctxmanager_methods - -Modules/_decimal/_decimal.c - dec_methods - -Modules/_decimal/_decimal.c - signaldict_methods - -Modules/_elementtree.c - _functions - -Modules/_elementtree.c - element_methods - -Modules/_elementtree.c - treebuilder_methods - -Modules/_elementtree.c - xmlparser_methods - -Modules/_functoolsmodule.c - _functools_methods - -Modules/_functoolsmodule.c - lru_cache_methods - -Modules/_functoolsmodule.c - partial_methods - -Modules/_gdbmmodule.c - _gdbm_module_methods - -Modules/_gdbmmodule.c - gdbm_methods - -Modules/_hashopenssl.c - EVPXOF_methods - -Modules/_hashopenssl.c - EVP_functions - -Modules/_hashopenssl.c - EVP_methods - -Modules/_hashopenssl.c - HMAC_methods - -Modules/_heapqmodule.c - heapq_methods - -Modules/_io/_iomodule.c - module_methods - -Modules/_io/bufferedio.c - bufferediobase_methods - -Modules/_io/bufferedio.c - bufferedrandom_methods - -Modules/_io/bufferedio.c - bufferedreader_methods - -Modules/_io/bufferedio.c - bufferedrwpair_methods - -Modules/_io/bufferedio.c - bufferedwriter_methods - -Modules/_io/bytesio.c - bytesio_methods - -Modules/_io/fileio.c - fileio_methods - -Modules/_io/iobase.c - iobase_methods - -Modules/_io/iobase.c - rawiobase_methods - -Modules/_io/stringio.c - stringio_methods - -Modules/_io/textio.c - incrementalnewlinedecoder_methods - -Modules/_io/textio.c - textiobase_methods - -Modules/_io/textio.c - textiowrapper_methods - -Modules/_io/winconsoleio.c - winconsoleio_methods - -Modules/_json.c - speedups_methods - -Modules/_localemodule.c - PyLocale_Methods - -Modules/_lsprof.c - moduleMethods - -Modules/_lsprof.c - profiler_methods - -Modules/_lzmamodule.c - Compressor_methods - -Modules/_lzmamodule.c - Decompressor_methods - -Modules/_lzmamodule.c - lzma_methods - -Modules/_multiprocessing/multiprocessing.c - module_methods - -Modules/_multiprocessing/posixshmem.c - module_methods - -Modules/_multiprocessing/semaphore.c - semlock_methods - -Modules/_opcode.c - opcode_functions - -Modules/_operator.c - attrgetter_methods - -Modules/_operator.c - itemgetter_methods - -Modules/_operator.c - methodcaller_methods - -Modules/_operator.c - operator_methods - -Modules/_pickle.c - Pickler_methods - -Modules/_pickle.c - Unpickler_methods - -Modules/_pickle.c - pickle_methods - -Modules/_pickle.c - picklerproxy_methods - -Modules/_pickle.c - unpicklerproxy_methods - -Modules/_posixsubprocess.c - module_methods - -Modules/_queuemodule.c - simplequeue_methods - -Modules/_randommodule.c - random_methods - -Modules/_scproxy.c - mod_methods - -Modules/_sha3/sha3module.c - SHA3_methods - -Modules/_sha3/sha3module.c - SHAKE_methods - -Modules/_sqlite/blob.c - blob_methods static PyMethodDef[] -Modules/_sqlite/connection.c - connection_methods - -Modules/_sqlite/cursor.c - cursor_methods - -Modules/_sqlite/module.c - module_methods - -Modules/_sqlite/row.c - row_methods - -Modules/_sre.c - _functions - -Modules/_sre.c - match_methods - -Modules/_sre.c - pattern_methods - -Modules/_sre.c - scanner_methods - -Modules/_sre/sre.c - _functions - -Modules/_sre/sre.c - match_methods - -Modules/_sre/sre.c - pattern_methods - -Modules/_sre/sre.c - scanner_methods - -Modules/_ssl.c - PySSLMethods - -Modules/_ssl.c - PySSL_methods - -Modules/_ssl.c - context_methods - -Modules/_ssl.c - memory_bio_methods - -Modules/_ssl/cert.c - certificate_methods - -Modules/_stat.c - stat_methods - -Modules/_statisticsmodule.c - statistics_methods - -Modules/_struct.c - module_functions - -Modules/_struct.c - s_methods - -Modules/_struct.c - unpackiter_methods - -Modules/_testcapi/heaptype.c - TestMethods - -Modules/_testcapi/unicode.c - TestMethods - -Modules/_testcapi/vectorcall.c - TestMethods - -Modules/_testcapi/vectorcall.c - VectorCallClass_methods - -Modules/_testcapi/vectorcall_limited.c - TestMethods - -Modules/_threadmodule.c - lock_methods - -Modules/_threadmodule.c - rlock_methods - -Modules/_threadmodule.c - thread_methods - -Modules/_threadmodule.c local_new wr_callback_def - -Modules/_tkinter.c - Tkapp_methods - -Modules/_tkinter.c - Tktt_methods - -Modules/_tkinter.c - moduleMethods - -Modules/_tracemalloc.c - module_methods - -Modules/_typingmodule.c - typing_methods - -Modules/_uuidmodule.c - uuid_methods - -Modules/_weakref.c - weakref_functions - -Modules/_winapi.c - overlapped_methods - -Modules/_winapi.c - winapi_functions - -Modules/_xxsubinterpretersmodule.c - module_functions - -Modules/_zoneinfo.c - module_methods - -Modules/_zoneinfo.c - zoneinfo_methods - -Modules/arraymodule.c - a_methods - -Modules/arraymodule.c - array_methods - -Modules/arraymodule.c - arrayiter_methods - -Modules/atexitmodule.c - atexit_methods - -Modules/audioop.c - audioop_methods - -Modules/binascii.c - binascii_module_methods - -Modules/cjkcodecs/cjkcodecs.h - __methods - -Modules/cjkcodecs/cjkcodecs.h - _cjk_methods - -Modules/cjkcodecs/multibytecodec.c - __methods - -Modules/cjkcodecs/multibytecodec.c - _multibytecodec_methods - -Modules/cjkcodecs/multibytecodec.c - mbidecoder_methods - -Modules/cjkcodecs/multibytecodec.c - mbiencoder_methods - -Modules/cjkcodecs/multibytecodec.c - mbstreamreader_methods - -Modules/cjkcodecs/multibytecodec.c - mbstreamwriter_methods - -Modules/cjkcodecs/multibytecodec.c - multibytecodec_methods - -Modules/cmathmodule.c - cmath_methods - -Modules/errnomodule.c - errno_methods - -Modules/faulthandler.c - module_methods - -Modules/fcntlmodule.c - fcntl_methods - -Modules/gcmodule.c - GcMethods - -Modules/getpath.c - getpath_methods - -Modules/getpath.c - getpath_nowarn_method - -Modules/getpath.c - getpath_warn_method - -Modules/grpmodule.c - grp_methods - -Modules/itertoolsmodule.c - _grouper_methods - -Modules/itertoolsmodule.c - accumulate_methods - -Modules/itertoolsmodule.c - chain_methods - -Modules/itertoolsmodule.c - combinations_methods - -Modules/itertoolsmodule.c - compress_methods - -Modules/itertoolsmodule.c - count_methods - -Modules/itertoolsmodule.c - cwr_methods - -Modules/itertoolsmodule.c - cycle_methods - -Modules/itertoolsmodule.c - dropwhile_methods - -Modules/itertoolsmodule.c - filterfalse_methods - -Modules/itertoolsmodule.c - groupby_methods - -Modules/itertoolsmodule.c - islice_methods - -Modules/itertoolsmodule.c - module_methods - -Modules/itertoolsmodule.c - permuations_methods - -Modules/itertoolsmodule.c - product_methods - -Modules/itertoolsmodule.c - repeat_methods - -Modules/itertoolsmodule.c - starmap_methods - -Modules/itertoolsmodule.c - takewhile_reduce_methods - -Modules/itertoolsmodule.c - tee_methods - -Modules/itertoolsmodule.c - teedataobject_methods - -Modules/itertoolsmodule.c - zip_longest_methods - -Modules/mathmodule.c - math_methods - -Modules/md5module.c - MD5_functions - -Modules/md5module.c - MD5_methods - -Modules/mmapmodule.c - mmap_object_methods - -Modules/nismodule.c - nis_methods - -Modules/ossaudiodev.c - oss_methods - -Modules/ossaudiodev.c - oss_mixer_methods - -Modules/ossaudiodev.c - ossaudiodev_methods - -Modules/overlapped.c - Overlapped_methods - -Modules/overlapped.c - overlapped_functions - -Modules/posixmodule.c - DirEntry_methods - -Modules/posixmodule.c - ScandirIterator_methods - -Modules/posixmodule.c - posix_methods - -Modules/pwdmodule.c - pwd_methods - -Modules/pyexpat.c - pyexpat_methods - -Modules/pyexpat.c - xmlparse_methods - -Modules/readline.c - readline_methods - -Modules/resource.c - resource_methods - -Modules/selectmodule.c - devpoll_methods - -Modules/selectmodule.c - kqueue_queue_methods - -Modules/selectmodule.c - poll_methods - -Modules/selectmodule.c - pyepoll_methods - -Modules/selectmodule.c - select_methods - -Modules/sha1module.c - SHA1_functions - -Modules/sha1module.c - SHA1_methods - -Modules/sha256module.c - SHA_functions - -Modules/sha256module.c - SHA_methods - -Modules/sha512module.c - SHA_functions - -Modules/sha512module.c - SHA_methods - -Modules/signalmodule.c - signal_methods - -Modules/socketmodule.c - sock_methods - -Modules/socketmodule.c - socket_methods - -Modules/spwdmodule.c - spwd_methods - -Modules/symtablemodule.c - symtable_methods - -Modules/syslogmodule.c - syslog_methods - -Modules/termios.c - termios_methods - -Modules/timemodule.c - time_methods - -Modules/unicodedata.c - unicodedata_functions - -Modules/xxlimited.c - Xxo_methods - -Modules/xxlimited.c - xx_methods - -Modules/xxlimited_35.c - Xxo_methods - -Modules/xxlimited_35.c - xx_methods - -Modules/xxmodule.c - Xxo_methods - -Modules/xxmodule.c - xx_methods - -Modules/xxsubtype.c - spamdict_methods - -Modules/xxsubtype.c - spamlist_methods - -Modules/xxsubtype.c - xxsubtype_functions - -Modules/zlibmodule.c - Decomp_methods - -Modules/zlibmodule.c - comp_methods - -Modules/zlibmodule.c - zlib_methods - -Objects/bytearrayobject.c - bytearray_methods - -Objects/bytearrayobject.c - bytearrayiter_methods - -Objects/bytesobject.c - bytes_methods - -Objects/bytesobject.c - striter_methods - -Objects/classobject.c - method_methods - -Objects/codeobject.c - code_methods - -Objects/complexobject.c - complex_methods - -Objects/descrobject.c - descr_methods - -Objects/descrobject.c - mappingproxy_methods - -Objects/descrobject.c - property_methods - -Objects/descrobject.c - wrapper_methods - -Objects/dictobject.c - dictitems_methods - -Objects/dictobject.c - dictiter_methods - -Objects/dictobject.c - dictkeys_methods - -Objects/dictobject.c - dictvalues_methods - -Objects/dictobject.c - mapp_methods - -Objects/enumobject.c - enum_methods - -Objects/enumobject.c - reversediter_methods - -Objects/exceptions.c - AttributeError_methods - -Objects/exceptions.c - BaseExceptionGroup_methods - -Objects/exceptions.c - BaseException_methods - -Objects/exceptions.c - ImportError_methods - -Objects/exceptions.c - NameError_methods - -Objects/exceptions.c - OSError_methods - -Objects/fileobject.c - stdprinter_methods - -Objects/floatobject.c - float_methods - -Objects/frameobject.c - frame_methods - -Objects/genericaliasobject.c - ga_iter_methods - -Objects/genericaliasobject.c - ga_methods - -Objects/genobject.c - async_gen_asend_methods - -Objects/genobject.c - async_gen_athrow_methods - -Objects/genobject.c - async_gen_methods - -Objects/genobject.c - coro_methods - -Objects/genobject.c - coro_wrapper_methods - -Objects/genobject.c - gen_methods - -Objects/iterobject.c - anextawaitable_methods - -Objects/iterobject.c - calliter_methods - -Objects/iterobject.c - seqiter_methods - -Objects/listobject.c - list_methods - -Objects/listobject.c - listiter_methods - -Objects/listobject.c - listreviter_methods - -Objects/longobject.c - long_methods - -Objects/memoryobject.c - memory_methods - -Objects/methodobject.c - meth_methods - -Objects/moduleobject.c - module_methods - -Objects/namespaceobject.c - namespace_methods - -Objects/object.c - notimplemented_methods - -Objects/odictobject.c - odict_methods - -Objects/odictobject.c - odictitems_methods - -Objects/odictobject.c - odictiter_methods - -Objects/odictobject.c - odictkeys_methods - -Objects/odictobject.c - odictvalues_methods - -Objects/picklebufobject.c - picklebuf_methods - -Objects/rangeobject.c - longrangeiter_methods - -Objects/rangeobject.c - range_methods - -Objects/rangeobject.c - rangeiter_methods - -Objects/setobject.c - frozenset_methods - -Objects/setobject.c - set_methods - -Objects/setobject.c - setiter_methods - -Objects/sliceobject.c - ellipsis_methods - -Objects/sliceobject.c - slice_methods - -Objects/stringlib/unicode_format.h - fieldnameiter_methods - -Objects/stringlib/unicode_format.h - formatteriter_methods - -Objects/structseq.c - structseq_methods - -Objects/tupleobject.c - tuple_methods - -Objects/tupleobject.c - tupleiter_methods - -Objects/typeobject.c - object_methods - -Objects/typeobject.c - tp_new_methoddef - -Objects/typeobject.c - type_methods - -Objects/unicodeobject.c - _string_methods - -Objects/unicodeobject.c - encoding_map_methods - -Objects/unicodeobject.c - unicode_methods - -Objects/unicodeobject.c - unicodeiter_methods - -Objects/unionobject.c - union_methods - -Objects/weakrefobject.c - proxy_methods - -Objects/weakrefobject.c - weakref_methods - -Python/Python-ast.c - ast_type_methods - -Python/Python-tokenize.c - tokenize_methods - -Python/_warnings.c - warnings_functions - -Python/bltinmodule.c - builtin_methods - -Python/bltinmodule.c - filter_methods - -Python/bltinmodule.c - map_methods - -Python/bltinmodule.c - zip_methods - -Python/context.c - PyContextTokenType_methods - -Python/context.c - PyContextVar_methods - -Python/context.c - PyContext_methods - -Python/hamt.c - PyHamt_methods - -Python/import.c - imp_methods - -Python/import.c - imp_slots - -Python/marshal.c - marshal_methods - -Python/sysmodule.c - sys_methods - -Python/traceback.c - tb_methods - - -#----------------------- -# PyMemberDef[], for static types and strucseq - -Modules/_bz2module.c - BZ2Decompressor_members - -Modules/_collectionsmodule.c - defdict_members - -Modules/_collectionsmodule.c - tuplegetter_members - -Modules/_csv.c - Dialect_memberlist - -Modules/_csv.c - Reader_memberlist - -Modules/_csv.c - Writer_memberlist - -Modules/_ctypes/_ctypes.c - PyCData_members - -Modules/_ctypes/callproc.c - PyCArgType_members - -Modules/_datetimemodule.c - delta_members - -Modules/_elementtree.c - xmlparser_members - -Modules/_functoolsmodule.c - keyobject_members - -Modules/_functoolsmodule.c - lru_cache_memberlist - -Modules/_functoolsmodule.c - partial_memberlist - -Modules/_io/bufferedio.c - bufferedrandom_members - -Modules/_io/bufferedio.c - bufferedreader_members - -Modules/_io/bufferedio.c - bufferedwriter_members - -Modules/_io/fileio.c - fileio_members - -Modules/_io/textio.c - textiowrapper_members - -Modules/_io/winconsoleio.c - winconsoleio_members - -Modules/_json.c - encoder_members - -Modules/_json.c - scanner_members - -Modules/_lzmamodule.c - Decompressor_members - -Modules/_multiprocessing/semaphore.c - semlock_members - -Modules/_operator.c - attrgetter_members - -Modules/_operator.c - itemgetter_members - -Modules/_pickle.c - Pickler_members - -Modules/_queuemodule.c - simplequeue_members - -Modules/_sqlite/blob.c - blob_members - -Modules/_sqlite/connection.c - connection_members - -Modules/_sqlite/cursor.c - cursor_members - -Modules/_sqlite/statement.c - stmt_members - -Modules/_sre.c - match_members - -Modules/_sre.c - pattern_members - -Modules/_sre.c - scanner_members - -Modules/_sre/sre.c - match_members - -Modules/_sre/sre.c - pattern_members - -Modules/_sre/sre.c - scanner_members - -Modules/_struct.c - s_members - -Modules/_testcapi/heaptype.c - heapctype_members - -Modules/_testcapi/heaptype.c - heapctypesetattr_members - -Modules/_testcapi/heaptype.c - heapctypesubclass_members - -Modules/_testcapi/heaptype.c - heapctypewithdict_members - -Modules/_testcapi/heaptype.c - heapctypewithnegativedict_members - -Modules/_testcapi/heaptype.c - heapctypewithweakref_members - -Modules/_testcapi/heaptype.c - members_to_repeat - -Modules/_testcapi/vectorcall.c - VectorCallClass_members - -Modules/_testcapi/vectorcall_limited.c - LimitedVectorCallClass_members - -Modules/_threadmodule.c - local_dummy_type_members - -Modules/_threadmodule.c - local_type_members - -Modules/_threadmodule.c - lock_type_members - -Modules/_threadmodule.c - rlock_type_members - -Modules/_winapi.c - overlapped_members - -Modules/_zoneinfo.c - zoneinfo_members - -Modules/arraymodule.c - array_members - -Modules/cjkcodecs/multibytecodec.c - mbstreamreader_members - -Modules/cjkcodecs/multibytecodec.c - mbstreamwriter_members - -Modules/mmapmodule.c - mmap_object_members - -Modules/ossaudiodev.c - oss_members - -Modules/overlapped.c - Overlapped_members - -Modules/posixmodule.c - DirEntry_members - -Modules/pyexpat.c - xmlparse_members - -Modules/selectmodule.c - kqueue_event_members - -Modules/sha256module.c - SHA_members - -Modules/sha512module.c - SHA_members - -Modules/socketmodule.c - sock_memberlist - -Modules/unicodedata.c - DB_members - -Modules/xxsubtype.c - spamdict_members - -Modules/zlibmodule.c - Decomp_members - -Objects/classobject.c - instancemethod_memberlist - -Objects/classobject.c - method_memberlist - -Objects/codeobject.c - code_memberlist - -Objects/complexobject.c - complex_members - -Objects/descrobject.c - descr_members - -Objects/descrobject.c - property_members - -Objects/descrobject.c - wrapper_members - -Objects/exceptions.c - AttributeError_members - -Objects/exceptions.c - BaseExceptionGroup_members - -Objects/exceptions.c - BaseException_members - -Objects/exceptions.c - ImportError_members - -Objects/exceptions.c - NameError_members - -Objects/exceptions.c - OSError_members - -Objects/exceptions.c - StopIteration_members - -Objects/exceptions.c - SyntaxError_members - -Objects/exceptions.c - SystemExit_members - -Objects/exceptions.c - UnicodeError_members - -Objects/frameobject.c - frame_memberlist - -Objects/funcobject.c - cm_memberlist - -Objects/funcobject.c - func_memberlist - -Objects/funcobject.c - sm_memberlist - -Objects/genericaliasobject.c - ga_members - -Objects/genobject.c - async_gen_memberlist - -Objects/genobject.c - coro_memberlist - -Objects/genobject.c - gen_memberlist - -Objects/methodobject.c - meth_members - -Objects/moduleobject.c - module_members - -Objects/namespaceobject.c - namespace_members - -Objects/rangeobject.c - range_members - -Objects/sliceobject.c - slice_members - -Objects/typeobject.c - super_members - -Objects/typeobject.c - type_members - -Objects/unionobject.c - union_members - -Objects/weakrefobject.c - weakref_members - -Python/Python-ast.c - ast_type_members - -Python/context.c - PyContextVar_members - -Python/symtable.c - ste_memberlist - -Python/traceback.c - tb_memberlist - - -#----------------------- -# for static types - -# PyNumberMethods -Modules/_collectionsmodule.c - deque_as_number - -Modules/_collectionsmodule.c - defdict_as_number - -Modules/_ctypes/_ctypes.c - PyCFuncPtr_as_number - -Modules/_ctypes/_ctypes.c - Simple_as_number - -Modules/_ctypes/_ctypes.c - Pointer_as_number - -Modules/_datetimemodule.c - delta_as_number - -Modules/_datetimemodule.c - date_as_number - -Modules/_datetimemodule.c - datetime_as_number - -Modules/_decimal/_decimal.c - dec_number_methods - -Modules/_xxsubinterpretersmodule.c - channelid_as_number - -Objects/boolobject.c - bool_as_number - -Objects/bytearrayobject.c - bytearray_as_number - -Objects/bytesobject.c - bytes_as_number - -Objects/complexobject.c - complex_as_number - -Objects/descrobject.c - mappingproxy_as_number - -Objects/dictobject.c - dict_as_number - -Objects/dictobject.c - dictviews_as_number - -Objects/floatobject.c - float_as_number - -Objects/genericaliasobject.c - ga_as_number - -Objects/interpreteridobject.c - interpid_as_number - -Objects/longobject.c - long_as_number - -Objects/object.c - none_as_number - -Objects/object.c - notimplemented_as_number - -Objects/odictobject.c - odict_as_number - -Objects/rangeobject.c - range_as_number - -Objects/setobject.c - set_as_number - -Objects/setobject.c - frozenset_as_number - -Objects/typeobject.c - type_as_number - -Objects/unicodeobject.c - unicode_as_number - -Objects/unionobject.c - union_as_number - -Objects/weakrefobject.c - proxy_as_number - - -# PySequenceMethods -Modules/arraymodule.c - array_as_sequence - -Modules/_collectionsmodule.c - deque_as_sequence - -Modules/_ctypes/_ctypes.c - CDataType_as_sequence - -Modules/_ctypes/_ctypes.c - Array_as_sequence - -Modules/_ctypes/_ctypes.c - Pointer_as_sequence - -Modules/_elementtree.c - element_as_sequence - -Modules/mmapmodule.c - mmap_as_sequence - -Objects/bytearrayobject.c - bytearray_as_sequence - -Objects/bytesobject.c - bytes_as_sequence - -Objects/descrobject.c - mappingproxy_as_sequence - -Objects/dictobject.c - dict_as_sequence - -Objects/dictobject.c - dictkeys_as_sequence - -Objects/dictobject.c - dictitems_as_sequence - -Objects/dictobject.c - dictvalues_as_sequence - -Objects/listobject.c - list_as_sequence - -Objects/memoryobject.c - memory_as_sequence - -Objects/rangeobject.c - range_as_sequence - -Objects/setobject.c - set_as_sequence - -Objects/tupleobject.c - tuple_as_sequence - -Objects/unicodeobject.c - unicode_as_sequence - -Objects/weakrefobject.c - proxy_as_sequence - -Python/context.c - PyContext_as_sequence - -Python/hamt.c - PyHamt_as_sequence - - -# PyMappingMethods -Modules/arraymodule.c - array_as_mapping - -Modules/_ctypes/_ctypes.c - Array_as_mapping - -Modules/_ctypes/_ctypes.c - Pointer_as_mapping - -Modules/_decimal/_decimal.c - signaldict_as_mapping - -Modules/_elementtree.c - element_as_mapping - -Modules/mmapmodule.c - mmap_as_mapping - -Modules/_sre.c - match_as_mapping - -Objects/bytearrayobject.c - bytearray_as_mapping - -Objects/bytesobject.c - bytes_as_mapping - -Objects/descrobject.c - mappingproxy_as_mapping - -Objects/dictobject.c - dict_as_mapping - -Objects/genericaliasobject.c - ga_as_mapping - -Objects/listobject.c - list_as_mapping - -Objects/memoryobject.c - memory_as_mapping - -Objects/odictobject.c - odict_as_mapping - -Objects/rangeobject.c - range_as_mapping - -Objects/tupleobject.c - tuple_as_mapping - -Objects/unicodeobject.c - unicode_as_mapping - -Objects/unionobject.c - union_as_mapping - -Objects/weakrefobject.c - proxy_as_mapping - -Python/context.c - PyContext_as_mapping - -Python/hamt.c - PyHamtIterator_as_mapping - -Python/hamt.c - PyHamt_as_mapping - - -# PyAsyncMethods -Modules/_asynciomodule.c - FutureIterType_as_async - -Modules/_asynciomodule.c - FutureType_as_async - -Objects/genobject.c - async_gen_as_async - -Objects/genobject.c - async_gen_asend_as_async - -Objects/genobject.c - async_gen_athrow_as_async - -Objects/genobject.c - coro_as_async - -Objects/genobject.c - gen_as_async - -Objects/iterobject.c - anextawaitable_as_async - - -# PyBufferProcs -Modules/arraymodule.c - array_as_buffer - -Modules/_ctypes/_ctypes.c - PyCData_as_buffer - -Modules/_io/bytesio.c - bytesiobuf_as_buffer - -Modules/mmapmodule.c - mmap_as_buffer - -Objects/bytearrayobject.c - bytearray_as_buffer - -Objects/bytesobject.c - bytes_as_buffer - -Objects/memoryobject.c - memory_as_buffer - -Objects/picklebufobject.c - picklebuf_as_buffer - - -# PyGetSetDef -Modules/_asynciomodule.c - FutureType_getsetlist - -Modules/_asynciomodule.c - TaskStepMethWrapper_getsetlist - -Modules/_asynciomodule.c - TaskType_getsetlist - -Modules/_blake2/blake2b_impl.c - py_blake2b_getsetters - -Modules/_blake2/blake2s_impl.c - py_blake2s_getsetters - -Modules/_collectionsmodule.c - deque_getset - -Modules/_csv.c - Dialect_getsetlist - -Modules/_ctypes/_ctypes.c - CharArray_getsets - -Modules/_ctypes/_ctypes.c - Pointer_getsets - -Modules/_ctypes/_ctypes.c - PyCFuncPtr_getsets - -Modules/_ctypes/_ctypes.c - Simple_getsets - -Modules/_ctypes/_ctypes.c - WCharArray_getsets - -Modules/_ctypes/cfield.c - PyCField_getset - -Modules/_cursesmodule.c - PyCursesWindow_getsets - -Modules/_datetimemodule.c - date_getset - -Modules/_datetimemodule.c - datetime_getset - -Modules/_datetimemodule.c - iso_calendar_date_getset - -Modules/_datetimemodule.c - time_getset - -Modules/_decimal/_decimal.c - context_getsets - -Modules/_decimal/_decimal.c - dec_getsets - -Modules/_elementtree.c - element_getsetlist - -Modules/_elementtree.c - xmlparser_getsetlist - -Modules/_functoolsmodule.c - lru_cache_getsetlist - -Modules/_functoolsmodule.c - partial_getsetlist - -Modules/_hashopenssl.c - EVPXOF_getseters - -Modules/_hashopenssl.c - EVP_getseters - -Modules/_hashopenssl.c - HMAC_getset - -Modules/_io/bufferedio.c - bufferedrandom_getset - -Modules/_io/bufferedio.c - bufferedreader_getset - -Modules/_io/bufferedio.c - bufferedrwpair_getset - -Modules/_io/bufferedio.c - bufferedwriter_getset - -Modules/_io/bytesio.c - bytesio_getsetlist - -Modules/_io/fileio.c - fileio_getsetlist - -Modules/_io/iobase.c - iobase_getset - -Modules/_io/stringio.c - stringio_getset - -Modules/_io/textio.c - incrementalnewlinedecoder_getset - -Modules/_io/textio.c - textiobase_getset - -Modules/_io/textio.c - textiowrapper_getset - -Modules/_io/winconsoleio.c - winconsoleio_getsetlist - -Modules/_pickle.c - Pickler_getsets - -Modules/_pickle.c - Unpickler_getsets - -Modules/_sha3/sha3module.c - SHA3_getseters - -Modules/_sha3/sha3module.c - SHAKE_getseters - -Modules/_sqlite/connection.c - connection_getset - -Modules/_sre/sre.c - pattern_getset - -Modules/_sre/sre.c - match_getset - -Modules/_sre.c - match_getset - -Modules/_sre.c - pattern_getset - -Modules/_ssl.c - PySSLSession_getsetlist - -Modules/_ssl.c - context_getsetlist - -Modules/_ssl.c - memory_bio_getsetlist - -Modules/_ssl.c - ssl_getsetlist - -Modules/_struct.c - s_getsetlist - -Modules/_testcapi/heaptype.c - heapctypewithdict_getsetlist - -Modules/_tkinter.c - PyTclObject_getsetlist - -Modules/_xxsubinterpretersmodule.c - channelid_getsets - -Modules/arraymodule.c - array_getsets - -Modules/cjkcodecs/multibytecodec.c - codecctx_getsets - -Modules/md5module.c - MD5_getseters - -Modules/mmapmodule.c - mmap_object_getset - -Modules/ossaudiodev.c - oss_getsetlist - -Modules/overlapped.c - Overlapped_getsets - -Modules/pyexpat.c - xmlparse_getsetlist - -Modules/selectmodule.c - devpoll_getsetlist - -Modules/selectmodule.c - kqueue_queue_getsetlist - -Modules/selectmodule.c - pyepoll_getsetlist - -Modules/sha1module.c - SHA1_getseters - -Modules/sha256module.c - SHA_getseters - -Modules/sha512module.c - SHA_getseters - -Modules/socketmodule.c - sock_getsetlist - -Modules/xxlimited.c - Xxo_getsetlist - -Modules/xxsubtype.c - spamlist_getsets - -Objects/cellobject.c - cell_getsetlist - -Objects/classobject.c - instancemethod_getset - -Objects/classobject.c - method_getset - -Objects/codeobject.c - code_getsetlist - -Objects/descrobject.c - getset_getset - -Objects/descrobject.c - member_getset - -Objects/descrobject.c - method_getset - -Objects/descrobject.c - property_getsetlist - -Objects/descrobject.c - wrapper_getsets - -Objects/descrobject.c - wrapperdescr_getset - -Objects/dictobject.c - dictview_getset - -Objects/exceptions.c - BaseException_getset - -Objects/exceptions.c - OSError_getset - -Objects/fileobject.c - stdprinter_getsetlist - -Objects/floatobject.c - float_getset - -Objects/frameobject.c - frame_getsetlist - -Objects/funcobject.c - cm_getsetlist - -Objects/funcobject.c - func_getsetlist - -Objects/funcobject.c - sm_getsetlist - -Objects/genericaliasobject.c - ga_properties - -Objects/genobject.c - async_gen_getsetlist - -Objects/genobject.c - coro_getsetlist - -Objects/genobject.c - gen_getsetlist - -Objects/longobject.c - long_getset - -Objects/memoryobject.c - memory_getsetlist - -Objects/methodobject.c - meth_getsets - -Objects/moduleobject.c - module_getsets - -Objects/odictobject.c - odict_getset - -Objects/typeobject.c - object_getsets - -Objects/typeobject.c - subtype_getsets_dict_only - -Objects/typeobject.c - subtype_getsets_full - -Objects/typeobject.c - subtype_getsets_weakref_only - -Objects/typeobject.c - type_getsets - -Objects/unionobject.c - union_properties - -Python/Python-ast.c - ast_type_getsets - -Python/context.c - PyContextTokenType_getsetlist - -Python/traceback.c - tb_getsetters - - -#----------------------- -# for heap types - -# PyType_Slot -Modules/_abc.c - _abc_data_type_spec_slots - -Modules/_blake2/blake2b_impl.c - blake2b_type_slots - -Modules/_blake2/blake2s_impl.c - blake2s_type_slots - -Modules/_bz2module.c - bz2_compressor_type_slots - -Modules/_bz2module.c - bz2_decompressor_type_slots - -Modules/_csv.c - Dialect_Type_slots - -Modules/_csv.c - Reader_Type_slots - -Modules/_csv.c - Writer_Type_slots - -Modules/_csv.c - error_slots - -Modules/_curses_panel.c - PyCursesPanel_Type_slots - -Modules/_dbmmodule.c - dbmtype_spec_slots - -Modules/_functoolsmodule.c - keyobject_type_slots - -Modules/_functoolsmodule.c - lru_cache_type_slots - -Modules/_functoolsmodule.c - lru_list_elem_type_slots - -Modules/_functoolsmodule.c - partial_type_slots - -Modules/_gdbmmodule.c - gdbmtype_spec_slots - -Modules/_hashopenssl.c - EVPXOFtype_slots - -Modules/_hashopenssl.c - EVPtype_slots - -Modules/_hashopenssl.c - HMACtype_slots - -Modules/_json.c - PyEncoderType_slots - -Modules/_json.c - PyScannerType_slots - -Modules/_lsprof.c - _lsprof_profiler_type_spec_slots - -Modules/_lzmamodule.c - lzma_compressor_type_slots - -Modules/_lzmamodule.c - lzma_decompressor_type_slots - -Modules/_multiprocessing/semaphore.c - _PyMp_SemLockType_slots - -Modules/_operator.c - attrgetter_type_slots - -Modules/_operator.c - itemgetter_type_slots - -Modules/_operator.c - methodcaller_type_slots - -Modules/_queuemodule.c - simplequeue_slots - -Modules/_randommodule.c - Random_Type_slots - -Modules/_sha3/sha3module.c - SHAKE128slots - -Modules/_sha3/sha3module.c - SHAKE256slots - -Modules/_sha3/sha3module.c - sha3_224_slots - -Modules/_sha3/sha3module.c - sha3_256_slots - -Modules/_sha3/sha3module.c - sha3_384_slots - -Modules/_sha3/sha3module.c - sha3_512_slots - -Modules/_sha3/sha3module.c - type_slots_obj - -Modules/_sqlite/blob.c - blob_slots - -Modules/_sqlite/connection.c - connection_slots - -Modules/_sqlite/cursor.c - cursor_slots - -Modules/_sqlite/prepare_protocol.c - type_slots - -Modules/_sqlite/row.c - row_slots - -Modules/_sqlite/statement.c - stmt_slots - -Modules/_sre.c - match_slots - -Modules/_sre.c - pattern_slots - -Modules/_sre.c - scanner_slots - -Modules/_sre/sre.c - match_slots - -Modules/_sre/sre.c - pattern_slots - -Modules/_sre/sre.c - scanner_slots - -Modules/_ssl.c - PySSLContext_slots - -Modules/_ssl.c - PySSLMemoryBIO_slots - -Modules/_ssl.c - PySSLSession_slots - -Modules/_ssl.c - PySSLSocket_slots - -Modules/_ssl.c - sslerror_type_slots - -Modules/_ssl/cert.c - PySSLCertificate_slots - -Modules/_struct.c - PyStructType_slots - -Modules/_struct.c - unpackiter_type_slots - -Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_slots - -Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_slots - -Modules/_testcapi/heaptype.c - HeapCTypeSetattr_slots - -Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_slots - -Modules/_testcapi/heaptype.c - HeapCTypeSubclass_slots - -Modules/_testcapi/heaptype.c - HeapCTypeWithBuffer_slots - -Modules/_testcapi/heaptype.c - HeapCTypeWithDict_slots - -Modules/_testcapi/heaptype.c - HeapCTypeWithNegativeDict_slots - -Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_slots - -Modules/_testcapi/heaptype.c - HeapCType_slots - -Modules/_testcapi/heaptype.c - HeapDocCType_slots - -Modules/_testcapi/heaptype.c - HeapGcCType_slots - -Modules/_testcapi/heaptype.c - NullTpDocType_slots - -Modules/_testcapi/heaptype.c - empty_type_slots - -Modules/_testcapi/heaptype.c - repeated_doc_slots - -Modules/_testcapi/heaptype.c - repeated_members_slots - -Modules/_testcapi/vectorcall.c - VectorCallClass_slots - -Modules/_testcapi/vectorcall_limited.c - LimitedVectorallClass_slots - -Modules/_testcapimodule.c - HeapTypeNameType_slots - -Modules/_testcapimodule.c - NullTpDocType_slots - -Modules/_threadmodule.c - local_dummy_type_slots - -Modules/_threadmodule.c - local_type_slots - -Modules/_threadmodule.c - lock_type_slots - -Modules/_threadmodule.c - rlock_type_slots - -Modules/_tkinter.c - PyTclObject_Type_slots - -Modules/_tkinter.c - Tkapp_Type_slots - -Modules/_tkinter.c - Tktt_Type_slots - -Modules/_winapi.c - winapi_overlapped_type_slots - -Modules/arraymodule.c - array_slots - -Modules/arraymodule.c - arrayiter_slots - -Modules/cjkcodecs/multibytecodec.c - decoder_slots - -Modules/cjkcodecs/multibytecodec.c - encoder_slots - -Modules/cjkcodecs/multibytecodec.c - multibytecodec_slots - -Modules/cjkcodecs/multibytecodec.c - reader_slots - -Modules/cjkcodecs/multibytecodec.c - writer_slots - -Modules/md5module.c - md5_type_slots - -Modules/mmapmodule.c - mmap_object_slots - -Modules/overlapped.c - overlapped_type_slots - -Modules/posixmodule.c - DirEntryType_slots - -Modules/posixmodule.c - ScandirIteratorType_slots - -Modules/pyexpat.c - _xml_parse_type_spec_slots - -Modules/selectmodule.c - devpoll_Type_slots - -Modules/selectmodule.c - kqueue_event_Type_slots - -Modules/selectmodule.c - kqueue_queue_Type_slots - -Modules/selectmodule.c - poll_Type_slots - -Modules/selectmodule.c - pyEpoll_Type_slots - -Modules/sha1module.c - sha1_type_slots - -Modules/sha256module.c - sha256_types_slots - -Modules/sha512module.c - sha512_sha384_type_slots - -Modules/sha512module.c - sha512_sha512_type_slots - -Modules/unicodedata.c - ucd_type_slots - -Modules/xxlimited.c - Null_Type_slots - -Modules/xxlimited.c - Str_Type_slots - -Modules/xxlimited.c - Xxo_Type_slots - -Modules/xxlimited_35.c - Null_Type_slots - -Modules/xxlimited_35.c - Str_Type_slots - -Modules/xxlimited_35.c - Xxo_Type_slots - -Modules/zlibmodule.c - Comptype_slots - -Modules/zlibmodule.c - Decomptype_slots - -Python/Python-ast.c - AST_type_slots - -Python/Python-tokenize.c - tokenizeriter_slots - - -# PyType_Spec -Modules/_abc.c - _abc_data_type_spec - -Modules/_blake2/blake2b_impl.c - blake2b_type_spec - -Modules/_blake2/blake2s_impl.c - blake2s_type_spec - -Modules/_bz2module.c - bz2_compressor_type_spec - -Modules/_bz2module.c - bz2_decompressor_type_spec - -Modules/_csv.c - Dialect_Type_spec - -Modules/_csv.c - Reader_Type_spec - -Modules/_csv.c - Writer_Type_spec - -Modules/_csv.c - error_spec - -Modules/_curses_panel.c - PyCursesPanel_Type_spec - -Modules/_dbmmodule.c - dbmtype_spec - -Modules/_functoolsmodule.c - keyobject_type_spec - -Modules/_functoolsmodule.c - lru_cache_type_spec - -Modules/_functoolsmodule.c - lru_list_elem_type_spec - -Modules/_functoolsmodule.c - partial_type_spec - -Modules/_gdbmmodule.c - gdbmtype_spec - -Modules/_hashopenssl.c - EVPXOFtype_spec - -Modules/_hashopenssl.c - EVPtype_spec - -Modules/_hashopenssl.c - HMACtype_spec - -Modules/_json.c - PyEncoderType_spec - -Modules/_json.c - PyScannerType_spec - -Modules/_lsprof.c - _lsprof_profiler_type_spec - -Modules/_lzmamodule.c - lzma_compressor_type_spec - -Modules/_lzmamodule.c - lzma_decompressor_type_spec - -Modules/_multiprocessing/multiprocessing.h - _PyMp_SemLockType_spec - -Modules/_multiprocessing/semaphore.c - _PyMp_SemLockType_spec - -Modules/_operator.c - attrgetter_type_spec - -Modules/_operator.c - itemgetter_type_spec - -Modules/_operator.c - methodcaller_type_spec - -Modules/_queuemodule.c - simplequeue_spec - -Modules/_randommodule.c - Random_Type_spec - -Modules/_sha3/sha3module.c - SHAKE128_spec - -Modules/_sha3/sha3module.c - SHAKE256_spec - -Modules/_sha3/sha3module.c - sha3_224_spec - -Modules/_sha3/sha3module.c - sha3_256_spec - -Modules/_sha3/sha3module.c - sha3_384_spec - -Modules/_sha3/sha3module.c - sha3_512_spec - -Modules/_sha3/sha3module.c - type_spec_obj - -Modules/_sqlite/blob.c - blob_spec - -Modules/_sqlite/connection.c - connection_spec - -Modules/_sqlite/cursor.c - cursor_spec - -Modules/_sqlite/prepare_protocol.c - type_spec - -Modules/_sqlite/row.c - row_spec - -Modules/_sqlite/statement.c - stmt_spec - -Modules/_sre.c - match_spec - -Modules/_sre.c - pattern_spec - -Modules/_sre.c - scanner_spec - -Modules/_sre/sre.c - match_spec - -Modules/_sre/sre.c - pattern_spec - -Modules/_sre/sre.c - scanner_spec - -Modules/_ssl.c - PySSLContext_spec - -Modules/_ssl.c - PySSLMemoryBIO_spec - -Modules/_ssl.c - PySSLSession_spec - -Modules/_ssl.c - PySSLSocket_spec - -Modules/_ssl.c - sslerror_type_spec - -Modules/_ssl/cert.c - PySSLCertificate_spec - -Modules/_struct.c - PyStructType_spec - -Modules/_struct.c - unpackiter_type_spec - -Modules/_testcapi/heaptype.c - HeapCTypeMetaclassCustomNew_spec - -Modules/_testcapi/heaptype.c - HeapCTypeMetaclass_spec - -Modules/_testcapi/heaptype.c - HeapCTypeSetattr_spec - -Modules/_testcapi/heaptype.c - HeapCTypeSubclassWithFinalizer_spec - -Modules/_testcapi/heaptype.c - HeapCTypeSubclass_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithBuffer_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithDict2_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithDict_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithNegativeDict_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref2_spec - -Modules/_testcapi/heaptype.c - HeapCTypeWithWeakref_spec - -Modules/_testcapi/heaptype.c - HeapCType_spec - -Modules/_testcapi/heaptype.c - HeapDocCType_spec - -Modules/_testcapi/heaptype.c - HeapGcCType_spec - -Modules/_testcapi/heaptype.c - MinimalMetaclass_spec - -Modules/_testcapi/heaptype.c - MinimalType_spec - -Modules/_testcapi/heaptype.c - NullTpDocType_spec - -Modules/_testcapi/heaptype.c - repeated_doc_slots_spec - -Modules/_testcapi/heaptype.c - repeated_members_slots_spec - -Modules/_testcapi/vectorcall_limited.c - LimitedVectorCallClass_spec - -Modules/_testcapimodule.c - HeapTypeNameType_Spec - -Modules/_testcapimodule.c - NullTpDocType_spec - -Modules/_threadmodule.c - local_dummy_type_spec - -Modules/_threadmodule.c - local_type_spec - -Modules/_threadmodule.c - lock_type_spec - -Modules/_threadmodule.c - rlock_type_spec - -Modules/_tkinter.c - PyTclObject_Type_spec - -Modules/_tkinter.c - Tkapp_Type_spec - -Modules/_tkinter.c - Tktt_Type_spec - -Modules/_winapi.c - winapi_overlapped_type_spec - -Modules/_zoneinfo.c - DAYS_BEFORE_MONTH - -Modules/_zoneinfo.c - DAYS_IN_MONTH - -Modules/arraymodule.c - array_spec - -Modules/arraymodule.c - arrayiter_spec - -Modules/cjkcodecs/multibytecodec.c - decoder_spec - -Modules/cjkcodecs/multibytecodec.c - encoder_spec - -Modules/cjkcodecs/multibytecodec.c - multibytecodec_spec - -Modules/cjkcodecs/multibytecodec.c - reader_spec - -Modules/cjkcodecs/multibytecodec.c - writer_spec - -Modules/md5module.c - md5_type_spec - -Modules/mmapmodule.c - mmap_object_spec - -Modules/overlapped.c - overlapped_type_spec - -Modules/posixmodule.c - DirEntryType_spec - -Modules/posixmodule.c - ScandirIteratorType_spec - -Modules/pyexpat.c - _xml_parse_type_spec - -Modules/selectmodule.c - devpoll_Type_spec - -Modules/selectmodule.c - kqueue_event_Type_spec - -Modules/selectmodule.c - kqueue_queue_Type_spec - -Modules/selectmodule.c - poll_Type_spec - -Modules/selectmodule.c - pyEpoll_Type_spec - -Modules/sha1module.c - sha1_type_spec - -Modules/sha256module.c - sha224_type_spec - -Modules/sha256module.c - sha256_type_spec - -Modules/sha512module.c - sha512_sha384_type_spec - -Modules/sha512module.c - sha512_sha512_type_spec - -Modules/unicodedata.c - ucd_type_spec - -Modules/xxlimited.c - Null_Type_spec - -Modules/xxlimited.c - Str_Type_spec - -Modules/xxlimited.c - Xxo_Type_spec - -Modules/xxlimited_35.c - Null_Type_spec - -Modules/xxlimited_35.c - Str_Type_spec - -Modules/xxlimited_35.c - Xxo_Type_spec - -Modules/zlibmodule.c - Comptype_spec - -Modules/zlibmodule.c - Decomptype_spec - -Python/Python-ast.c - AST_type_spec - -Python/Python-tokenize.c - tokenizeriter_spec - - -#----------------------- -# for structseq - -# PyStructSequence_Field[] -Modules/_cursesmodule.c - ncurses_version_fields - -Modules/grpmodule.c - struct_group_type_fields - -Modules/_lsprof.c - profiler_entry_fields - -Modules/_lsprof.c - profiler_subentry_fields - -Modules/posixmodule.c - stat_result_fields - -Modules/posixmodule.c - statvfs_result_fields - -Modules/posixmodule.c - waitid_result_fields - -Modules/posixmodule.c - uname_result_fields - -Modules/posixmodule.c - sched_param_fields - -Modules/posixmodule.c - times_result_fields - -Modules/posixmodule.c - TerminalSize_fields - -Modules/pwdmodule.c - struct_pwd_type_fields - -Modules/resource.c - struct_rusage_fields - -Modules/signalmodule.c - struct_siginfo_fields - -Modules/spwdmodule.c - struct_spwd_type_fields - -Modules/_threadmodule.c - ExceptHookArgs_fields - -Modules/timemodule.c - struct_time_type_fields - -Objects/floatobject.c - floatinfo_fields - -Objects/longobject.c - int_info_fields - -Python/errors.c - UnraisableHookArgs_fields - -Python/sysmodule.c - asyncgen_hooks_fields - -Python/sysmodule.c - hash_info_fields - -Python/sysmodule.c - windows_version_fields - -Python/sysmodule.c - flags_fields - -Python/sysmodule.c - version_info_fields - -Python/thread.c - threadinfo_fields - - -# PyStructSequence_Desc -Modules/_cursesmodule.c - ncurses_version_desc - -Modules/grpmodule.c - struct_group_type_desc - -Modules/_lsprof.c - profiler_entry_desc - -Modules/_lsprof.c - profiler_subentry_desc - -Modules/posixmodule.c - stat_result_desc - -Modules/posixmodule.c - statvfs_result_desc - -Modules/posixmodule.c - waitid_result_desc - -Modules/posixmodule.c - uname_result_desc - -Modules/posixmodule.c - sched_param_desc - -Modules/posixmodule.c - times_result_desc - -Modules/posixmodule.c - TerminalSize_desc - -Modules/pwdmodule.c - struct_pwd_type_desc - -Modules/resource.c - struct_rusage_desc - -Modules/signalmodule.c - struct_siginfo_desc - -Modules/spwdmodule.c - struct_spwd_type_desc - -Modules/_threadmodule.c - ExceptHookArgs_desc - -Modules/timemodule.c - struct_time_type_desc - -Objects/floatobject.c - floatinfo_desc - -Objects/longobject.c - int_info_desc - -Python/errors.c - UnraisableHookArgs_desc - -Python/sysmodule.c - asyncgen_hooks_desc - -Python/sysmodule.c - hash_info_desc - -Python/sysmodule.c - windows_version_desc - -Python/sysmodule.c - flags_desc - -Python/sysmodule.c - version_info_desc - -Python/thread.c - threadinfo_desc - +# All module defs, type defs, etc. are handled in c-analyzr/cpython/_analyzer.py. +# All kwlist arrays are handled in c-analyzr/cpython/_analyzer.py. #----------------------- # other vars that are actually constant @@ -1908,6 +381,8 @@ Modules/_struct.c - lilendian_table - Modules/_tkinter.c - state_key - Modules/_xxsubinterpretersmodule.c - _channelid_end_recv - Modules/_xxsubinterpretersmodule.c - _channelid_end_send - +Modules/_zoneinfo.c - DAYS_BEFORE_MONTH - +Modules/_zoneinfo.c - DAYS_IN_MONTH - Modules/arraymodule.c - descriptors - Modules/arraymodule.c - emptybuf - Modules/cjkcodecs/cjkcodecs.h - __methods - From webhook-mailer at python.org Thu Aug 25 21:43:11 2022 From: webhook-mailer at python.org (corona10) Date: Fri, 26 Aug 2022 01:43:11 -0000 Subject: [Python-checkins] gh-96197: Fix expression when :func:`sys.breakpointhook is missing (gh-96293) Message-ID: <mailman.830.1661478192.3313.python-checkins@python.org> https://github.com/python/cpython/commit/47d406ffc4946b023e38322c5235bec25f068481 commit: 47d406ffc4946b023e38322c5235bec25f068481 branch: main author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-26T10:43:02+09:00 summary: gh-96197: Fix expression when :func:`sys.breakpointhook is missing (gh-96293) files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index fbde9129274..93e2f5b26a7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -164,7 +164,7 @@ are always available. They are listed here in alphabetical order. :func:`sys.breakpointhook` can be set to some other function and :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. - If :func:`sys.breakpointhook` is not available to be called, this function will + If :func:`sys.breakpointhook` is not accessible, this function will raise :exc:`RuntimeError`. .. audit-event:: builtins.breakpoint breakpointhook breakpoint From webhook-mailer at python.org Thu Aug 25 22:03:05 2022 From: webhook-mailer at python.org (corona10) Date: Fri, 26 Aug 2022 02:03:05 -0000 Subject: [Python-checkins] gh-96197: Define the behavior of repr if sys.displayhook is lost (gh-96242) Message-ID: <mailman.831.1661479386.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0319cd6825f3c247a875c91493a38992fb33a5b3 commit: 0319cd6825f3c247a875c91493a38992fb33a5b3 branch: main author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-26T11:02:57+09:00 summary: gh-96197: Define the behavior of repr if sys.displayhook is lost (gh-96242) files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 93e2f5b26a7..e86e1857c7a 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1515,6 +1515,8 @@ are always available. They are listed here in alphabetical order. of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a :meth:`__repr__` method. + If :func:`sys.displayhook` is not accessible, this function will raise + :exc:`RuntimeError`. .. function:: reversed(seq) From webhook-mailer at python.org Thu Aug 25 22:03:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 26 Aug 2022 02:03:21 -0000 Subject: [Python-checkins] gh-96197: Fix expression when :func:`sys.breakpointhook is missing (gh-96293) Message-ID: <mailman.832.1661479401.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5f4588feec1de272c79b29eff8ee960b12c0a115 commit: 5f4588feec1de272c79b29eff8ee960b12c0a115 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-25T19:03:16-07:00 summary: gh-96197: Fix expression when :func:`sys.breakpointhook is missing (gh-96293) (cherry picked from commit 47d406ffc4946b023e38322c5235bec25f068481) Co-authored-by: Dong-hee Na <donghee.na at python.org> files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ba5d2cf8033..95f11e23988 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -164,7 +164,7 @@ are always available. They are listed here in alphabetical order. :func:`sys.breakpointhook` can be set to some other function and :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. - If :func:`sys.breakpointhook` is not available to be called, this function will + If :func:`sys.breakpointhook` is not accessible, this function will raise :exc:`RuntimeError`. .. audit-event:: builtins.breakpoint breakpointhook breakpoint From webhook-mailer at python.org Thu Aug 25 22:12:52 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 26 Aug 2022 02:12:52 -0000 Subject: [Python-checkins] gh-96197: Define the behavior of repr if sys.displayhook is lost (gh-96242) Message-ID: <mailman.833.1661479973.3313.python-checkins@python.org> https://github.com/python/cpython/commit/315807dac99d52b817f5370975335dea911ba673 commit: 315807dac99d52b817f5370975335dea911ba673 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-25T19:12:43-07:00 summary: gh-96197: Define the behavior of repr if sys.displayhook is lost (gh-96242) (cherry picked from commit 0319cd6825f3c247a875c91493a38992fb33a5b3) Co-authored-by: Dong-hee Na <donghee.na at python.org> files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index fbde9129274..068113b3eb5 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1515,6 +1515,8 @@ are always available. They are listed here in alphabetical order. of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a :meth:`__repr__` method. + If :func:`sys.displayhook` is not accessible, this function will raise + :exc:`RuntimeError`. .. function:: reversed(seq) From webhook-mailer at python.org Thu Aug 25 22:13:09 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 26 Aug 2022 02:13:09 -0000 Subject: [Python-checkins] gh-96197: Define the behavior of repr if sys.displayhook is lost (gh-96242) Message-ID: <mailman.834.1661479990.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b69ba3d7233013ea8cb95a3e30e2338f7f76b359 commit: b69ba3d7233013ea8cb95a3e30e2338f7f76b359 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-25T19:13:04-07:00 summary: gh-96197: Define the behavior of repr if sys.displayhook is lost (gh-96242) (cherry picked from commit 0319cd6825f3c247a875c91493a38992fb33a5b3) Co-authored-by: Dong-hee Na <donghee.na at python.org> files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 95f11e23988..86c6b3b4c26 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1509,6 +1509,8 @@ are always available. They are listed here in alphabetical order. of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a :meth:`__repr__` method. + If :func:`sys.displayhook` is not accessible, this function will raise + :exc:`RuntimeError`. .. function:: reversed(seq) From webhook-mailer at python.org Fri Aug 26 06:32:24 2022 From: webhook-mailer at python.org (tiran) Date: Fri, 26 Aug 2022 10:32:24 -0000 Subject: [Python-checkins] gh-96269: Fix build dependency on AIX (GH-96304) Message-ID: <mailman.835.1661509945.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8c1dbad36f44f332dadd9d08c8ffe3da7f6a20a6 commit: 8c1dbad36f44f332dadd9d08c8ffe3da7f6a20a6 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-26T12:31:58+02:00 summary: gh-96269: Fix build dependency on AIX (GH-96304) files: A Misc/NEWS.d/next/Build/2022-08-26-11-50-03.gh-issue-96269.x_J5h0.rst M Makefile.pre.in M Modules/makesetup diff --git a/Makefile.pre.in b/Makefile.pre.in index 3491e91f43ab..af203705d38e 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2522,6 +2522,8 @@ Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h ########################################################################## # Module dependencies and platform-specific files +MODULE_DEPS=$(PYTHON_HEADERS) Modules/config.c $(EXPORTSYMS) + MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h MODULE_PYEXPAT_DEPS=$(LIBEXPAT_HEADERS) @LIBEXPAT_INTERNAL@ diff --git a/Misc/NEWS.d/next/Build/2022-08-26-11-50-03.gh-issue-96269.x_J5h0.rst b/Misc/NEWS.d/next/Build/2022-08-26-11-50-03.gh-issue-96269.x_J5h0.rst new file mode 100644 index 000000000000..adb605fede5d --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-08-26-11-50-03.gh-issue-96269.x_J5h0.rst @@ -0,0 +1,3 @@ +Shared module targets now depend on new ``MODULE_DEPS`` variable, which +includes ``EXPORTSYMS``. This fixes a build order issue on unsupported AIX +platform. diff --git a/Modules/makesetup b/Modules/makesetup index 08303814c8c9..5c275ac9a049 100755 --- a/Modules/makesetup +++ b/Modules/makesetup @@ -267,7 +267,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | cc="$cc $cpps \$(PY_BUILTIN_MODULE_CFLAGS)";; esac # force rebuild when header file or module build flavor (static/shared) is changed - rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(PYTHON_HEADERS) Modules/config.c; $cc -c $src -o $obj" + rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS); $cc -c $src -o $obj" echo "$rule" >>$rulesf done case $doconfig in From webhook-mailer at python.org Fri Aug 26 10:07:46 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 26 Aug 2022 14:07:46 -0000 Subject: [Python-checkins] Port regression test for issue GH-93592 (GH-96208) Message-ID: <mailman.836.1661522867.3313.python-checkins@python.org> https://github.com/python/cpython/commit/771eff21a0984327a95013e2bd1d57b1f1a0e89d commit: 771eff21a0984327a95013e2bd1d57b1f1a0e89d branch: main author: Kristj?n Valur J?nsson <sweskman at gmail.com> committer: markshannon <mark at hotpy.org> date: 2022-08-26T15:07:31+01:00 summary: Port regression test for issue GH-93592 (GH-96208) files: M Lib/test/test_coroutines.py diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index dba5ceffaf1..8fff2d47c10 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -4,6 +4,7 @@ import pickle import sys import types +import traceback import unittest import warnings from test import support @@ -2207,6 +2208,29 @@ async def f(): with self.assertWarns(RuntimeWarning): gen.cr_frame.clear() + def test_stack_in_coroutine_throw(self): + # Regression test for https://github.com/python/cpython/issues/93592 + async def a(): + return await b() + + async def b(): + return await c() + + @types.coroutine + def c(): + try: + # traceback.print_stack() + yield len(traceback.extract_stack()) + except ZeroDivisionError: + # traceback.print_stack() + yield len(traceback.extract_stack()) + + coro = a() + len_send = coro.send(None) + len_throw = coro.throw(ZeroDivisionError) + # before fixing, visible stack from throw would be shorter than from send. + self.assertEqual(len_send, len_throw) + @unittest.skipIf( support.is_emscripten or support.is_wasi, From webhook-mailer at python.org Fri Aug 26 10:21:25 2022 From: webhook-mailer at python.org (iritkatriel) Date: Fri, 26 Aug 2022 14:21:25 -0000 Subject: [Python-checkins] bpo-33587: inspect.getsource: reorder stat on file in linecache (GH-6805) Message-ID: <mailman.837.1661523686.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c1581a928cc153076593c5c433a8dd36ce10fbfb commit: c1581a928cc153076593c5c433a8dd36ce10fbfb branch: main author: Pankaj Pandey <pankaj86 at gmail.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-26T15:20:48+01:00 summary: bpo-33587: inspect.getsource: reorder stat on file in linecache (GH-6805) * inspect.getsource: avoid stat on file in linecache The check for os.path.exists() on source file is postponed in inspect.getsourcefile() until needed avoiding an expensive filesystem stat call and PEP 302 module loader check is moved last for performance since it is an uncommon case. files: M Lib/inspect.py diff --git a/Lib/inspect.py b/Lib/inspect.py index cbc0632484b..498ee7ab9ea 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -946,6 +946,9 @@ def getsourcefile(object): elif any(filename.endswith(s) for s in importlib.machinery.EXTENSION_SUFFIXES): return None + # return a filename found in the linecache even if it doesn't exist on disk + if filename in linecache.cache: + return filename if os.path.exists(filename): return filename # only return a non-existent filename if the module has a PEP 302 loader @@ -954,9 +957,6 @@ def getsourcefile(object): return filename elif getattr(getattr(module, "__spec__", None), "loader", None) is not None: return filename - # or it is in the linecache - elif filename in linecache.cache: - return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. From webhook-mailer at python.org Fri Aug 26 11:02:47 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 26 Aug 2022 15:02:47 -0000 Subject: [Python-checkins] Port regression test for issue GH-93592 (GH-96208) (GH-96313) Message-ID: <mailman.838.1661526167.3313.python-checkins@python.org> https://github.com/python/cpython/commit/acd7841aa4e103d8d9ca33cbfc8100578211a602 commit: acd7841aa4e103d8d9ca33cbfc8100578211a602 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: markshannon <mark at hotpy.org> date: 2022-08-26T16:02:36+01:00 summary: Port regression test for issue GH-93592 (GH-96208) (GH-96313) files: M Lib/test/test_coroutines.py diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index dba5ceffaf1..8fff2d47c10 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -4,6 +4,7 @@ import pickle import sys import types +import traceback import unittest import warnings from test import support @@ -2207,6 +2208,29 @@ async def f(): with self.assertWarns(RuntimeWarning): gen.cr_frame.clear() + def test_stack_in_coroutine_throw(self): + # Regression test for https://github.com/python/cpython/issues/93592 + async def a(): + return await b() + + async def b(): + return await c() + + @types.coroutine + def c(): + try: + # traceback.print_stack() + yield len(traceback.extract_stack()) + except ZeroDivisionError: + # traceback.print_stack() + yield len(traceback.extract_stack()) + + coro = a() + len_send = coro.send(None) + len_throw = coro.throw(ZeroDivisionError) + # before fixing, visible stack from throw would be shorter than from send. + self.assertEqual(len_send, len_throw) + @unittest.skipIf( support.is_emscripten or support.is_wasi, From webhook-mailer at python.org Fri Aug 26 12:30:10 2022 From: webhook-mailer at python.org (isidentical) Date: Fri, 26 Aug 2022 16:30:10 -0000 Subject: [Python-checkins] GH-96172 fix unicodedata.east_asian_width being wrong on unassigned code points (#96207) Message-ID: <mailman.839.1661531412.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9c197bc8bfa153522927aa03ff854bbc4dce437f commit: 9c197bc8bfa153522927aa03ff854bbc4dce437f branch: main author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de> committer: isidentical <isidentical at gmail.com> date: 2022-08-26T19:29:39+03:00 summary: GH-96172 fix unicodedata.east_asian_width being wrong on unassigned code points (#96207) files: A Misc/NEWS.d/next/Library/2022-08-23-13-30-30.gh-issue-96172.7WTHer.rst M Lib/test/test_unicodedata.py M Modules/unicodedata_db.h M Tools/unicode/makeunicodedata.py diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 3514697f548e..42c02eee58b4 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -71,7 +71,7 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): # Update this if the database changes. Make sure to do a full rebuild # (e.g. 'make distclean && make') to get the correct checksum. - expectedchecksum = '98d602e1f69d5c5bb8a5910c40bbbad4e18e8370' + expectedchecksum = '4975f3ec0acd4a62465d18c9bf8519b1964181f6' @requires_resource('cpu') def test_function_checksum(self): @@ -90,6 +90,7 @@ def test_function_checksum(self): self.db.decomposition(char), str(self.db.mirrored(char)), str(self.db.combining(char)), + unicodedata.east_asian_width(char), ] h.update(''.join(data).encode("ascii")) result = h.hexdigest() @@ -220,6 +221,23 @@ def test_east_asian_width(self): self.assertEqual(eaw('\u2010'), 'A') self.assertEqual(eaw('\U00020000'), 'W') + def test_east_asian_width_unassigned(self): + eaw = self.db.east_asian_width + # unassigned + for char in '\u0530\u0ece\u10c6\u20fc\uaaca\U000107bd\U000115f2': + self.assertEqual(eaw(char), 'N') + self.assertIs(self.db.name(char, None), None) + + # unassigned but reserved for CJK + for char in '\uFA6E\uFADA\U0002A6E0\U0002FA20\U0003134B\U0003FFFD': + self.assertEqual(eaw(char), 'W') + self.assertIs(self.db.name(char, None), None) + + # private use areas + for char in '\uE000\uF800\U000F0000\U000FFFEE\U00100000\U0010FFF0': + self.assertEqual(eaw(char), 'A') + self.assertIs(self.db.name(char, None), None) + def test_east_asian_width_9_0_changes(self): self.assertEqual(self.db.ucd_3_2_0.east_asian_width('\u231a'), 'N') self.assertEqual(self.db.east_asian_width('\u231a'), 'W') diff --git a/Misc/NEWS.d/next/Library/2022-08-23-13-30-30.gh-issue-96172.7WTHer.rst b/Misc/NEWS.d/next/Library/2022-08-23-13-30-30.gh-issue-96172.7WTHer.rst new file mode 100644 index 000000000000..1bb57f177887 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-23-13-30-30.gh-issue-96172.7WTHer.rst @@ -0,0 +1,3 @@ +Fix a bug in ``unicodedata``: ``east_asian_width`` used to return the wrong +value for unassigned characters; and for yet unassigned, but reserved +characters. diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index e76631e8e7b0..399610be74d5 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -4,10 +4,10 @@ /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {0, 0, 0, 0, 0, 0}, - {13, 0, 15, 0, 5, 0}, - {13, 0, 17, 0, 5, 0}, - {13, 0, 16, 0, 5, 0}, - {13, 0, 18, 0, 5, 0}, + {13, 0, 15, 0, 0, 0}, + {13, 0, 17, 0, 0, 0}, + {13, 0, 16, 0, 0, 0}, + {13, 0, 18, 0, 0, 0}, {10, 0, 18, 0, 3, 0}, {26, 0, 19, 0, 3, 0}, {26, 0, 11, 0, 3, 0}, @@ -24,44 +24,44 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {29, 0, 19, 0, 3, 0}, {20, 0, 19, 0, 3, 0}, {2, 0, 1, 0, 3, 0}, - {10, 0, 13, 0, 5, 136}, + {10, 0, 13, 0, 0, 136}, {26, 0, 19, 0, 4, 0}, {28, 0, 11, 0, 4, 0}, {30, 0, 19, 0, 3, 0}, {29, 0, 19, 0, 4, 136}, - {30, 0, 19, 0, 5, 0}, + {30, 0, 19, 0, 0, 0}, {19, 0, 1, 0, 4, 136}, - {24, 0, 19, 1, 5, 0}, + {24, 0, 19, 1, 0, 0}, {14, 0, 15, 0, 4, 0}, {30, 0, 19, 0, 4, 0}, {29, 0, 19, 0, 3, 136}, {30, 0, 11, 0, 4, 0}, {27, 0, 11, 0, 4, 0}, {9, 0, 9, 0, 4, 136}, - {2, 0, 1, 0, 5, 136}, - {25, 0, 19, 1, 5, 0}, + {2, 0, 1, 0, 0, 136}, + {25, 0, 19, 1, 0, 0}, {9, 0, 19, 0, 4, 136}, - {1, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 0, 10}, {1, 0, 1, 0, 4, 0}, {27, 0, 19, 0, 4, 0}, {2, 0, 1, 0, 4, 0}, {2, 0, 1, 0, 4, 10}, - {2, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 0}, + {2, 0, 1, 0, 0, 10}, + {1, 0, 1, 0, 0, 0}, {1, 0, 1, 0, 4, 136}, {2, 0, 1, 0, 4, 136}, - {2, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 0}, - {1, 0, 1, 0, 5, 136}, - {3, 0, 1, 0, 5, 136}, - {18, 0, 1, 0, 5, 136}, - {18, 0, 19, 0, 5, 0}, - {18, 0, 1, 0, 5, 0}, - {29, 0, 19, 0, 5, 0}, + {2, 0, 1, 0, 0, 0}, + {19, 0, 1, 0, 0, 0}, + {1, 0, 1, 0, 0, 136}, + {3, 0, 1, 0, 0, 136}, + {18, 0, 1, 0, 0, 136}, + {18, 0, 19, 0, 0, 0}, + {18, 0, 1, 0, 0, 0}, + {29, 0, 19, 0, 0, 0}, {29, 0, 19, 0, 4, 0}, {18, 0, 19, 0, 4, 0}, {18, 0, 1, 0, 4, 0}, - {29, 0, 19, 0, 5, 136}, + {29, 0, 19, 0, 0, 136}, {4, 230, 14, 0, 4, 80}, {4, 230, 14, 0, 4, 0}, {4, 232, 14, 0, 4, 0}, @@ -77,173 +77,173 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {4, 0, 14, 0, 4, 0}, {4, 233, 14, 0, 4, 0}, {4, 234, 14, 0, 4, 0}, - {18, 0, 19, 0, 5, 170}, - {26, 0, 19, 0, 5, 170}, - {29, 0, 19, 0, 5, 138}, - {1, 0, 1, 0, 5, 138}, - {27, 0, 19, 0, 5, 0}, + {18, 0, 19, 0, 0, 170}, + {26, 0, 19, 0, 0, 170}, + {29, 0, 19, 0, 0, 138}, + {1, 0, 1, 0, 0, 138}, + {27, 0, 19, 0, 0, 0}, {1, 0, 1, 0, 4, 10}, - {30, 0, 1, 0, 5, 0}, - {4, 230, 14, 0, 5, 0}, - {6, 0, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 0}, - {21, 0, 19, 0, 5, 0}, - {28, 0, 11, 0, 5, 0}, - {4, 220, 14, 0, 5, 0}, - {4, 222, 14, 0, 5, 0}, - {4, 228, 14, 0, 5, 0}, - {4, 10, 14, 0, 5, 0}, - {4, 11, 14, 0, 5, 0}, - {4, 12, 14, 0, 5, 0}, - {4, 13, 14, 0, 5, 0}, - {4, 14, 14, 0, 5, 0}, - {4, 15, 14, 0, 5, 0}, - {4, 16, 14, 0, 5, 0}, - {4, 17, 14, 0, 5, 0}, - {4, 18, 14, 0, 5, 0}, - {4, 19, 14, 0, 5, 0}, - {4, 20, 14, 0, 5, 0}, - {4, 21, 14, 0, 5, 0}, - {4, 22, 14, 0, 5, 0}, - {21, 0, 4, 0, 5, 0}, - {4, 23, 14, 0, 5, 0}, - {26, 0, 4, 0, 5, 0}, - {4, 24, 14, 0, 5, 0}, - {4, 25, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 0}, - {14, 0, 12, 0, 5, 0}, - {27, 0, 5, 0, 5, 0}, - {26, 0, 11, 0, 5, 0}, - {28, 0, 5, 0, 5, 0}, - {26, 0, 13, 0, 5, 0}, - {26, 0, 5, 0, 5, 0}, - {4, 30, 14, 0, 5, 0}, - {4, 31, 14, 0, 5, 0}, - {4, 32, 14, 0, 5, 0}, - {14, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 10}, - {18, 0, 5, 0, 5, 0}, - {4, 27, 14, 0, 5, 0}, - {4, 28, 14, 0, 5, 0}, - {4, 29, 14, 0, 5, 0}, - {4, 33, 14, 0, 5, 0}, - {4, 34, 14, 0, 5, 0}, - {4, 230, 14, 0, 5, 80}, - {4, 220, 14, 0, 5, 80}, - {7, 0, 12, 0, 5, 0}, - {26, 0, 12, 0, 5, 0}, - {4, 35, 14, 0, 5, 0}, - {19, 0, 5, 0, 5, 136}, - {7, 0, 9, 0, 5, 0}, - {30, 0, 5, 0, 5, 0}, - {4, 36, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 0}, - {7, 0, 4, 0, 5, 0}, - {18, 0, 4, 0, 5, 0}, - {26, 0, 19, 0, 5, 0}, - {28, 0, 4, 0, 5, 0}, - {29, 0, 5, 0, 5, 0}, - {5, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 10}, - {4, 7, 14, 0, 5, 80}, - {4, 9, 14, 0, 5, 0}, - {19, 0, 1, 0, 5, 170}, - {7, 0, 1, 0, 5, 0}, - {4, 7, 14, 0, 5, 0}, - {5, 0, 1, 0, 5, 80}, - {5, 0, 1, 0, 5, 10}, - {9, 0, 1, 0, 5, 0}, - {4, 0, 14, 0, 5, 80}, - {4, 0, 14, 0, 5, 10}, - {4, 84, 14, 0, 5, 0}, - {4, 91, 14, 0, 5, 80}, - {9, 0, 19, 0, 5, 0}, - {4, 0, 1, 0, 5, 0}, - {4, 9, 14, 0, 5, 80}, - {19, 0, 1, 0, 5, 136}, - {4, 103, 14, 0, 5, 0}, - {4, 107, 14, 0, 5, 0}, - {4, 118, 14, 0, 5, 0}, - {4, 122, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 136}, - {4, 216, 14, 0, 5, 0}, - {22, 0, 19, 1, 5, 0}, - {23, 0, 19, 1, 5, 0}, - {4, 129, 14, 0, 5, 0}, - {4, 130, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 170}, - {4, 132, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 136}, + {30, 0, 1, 0, 0, 0}, + {4, 230, 14, 0, 0, 0}, + {6, 0, 14, 0, 0, 0}, + {26, 0, 1, 0, 0, 0}, + {21, 0, 19, 0, 0, 0}, + {28, 0, 11, 0, 0, 0}, + {4, 220, 14, 0, 0, 0}, + {4, 222, 14, 0, 0, 0}, + {4, 228, 14, 0, 0, 0}, + {4, 10, 14, 0, 0, 0}, + {4, 11, 14, 0, 0, 0}, + {4, 12, 14, 0, 0, 0}, + {4, 13, 14, 0, 0, 0}, + {4, 14, 14, 0, 0, 0}, + {4, 15, 14, 0, 0, 0}, + {4, 16, 14, 0, 0, 0}, + {4, 17, 14, 0, 0, 0}, + {4, 18, 14, 0, 0, 0}, + {4, 19, 14, 0, 0, 0}, + {4, 20, 14, 0, 0, 0}, + {4, 21, 14, 0, 0, 0}, + {4, 22, 14, 0, 0, 0}, + {21, 0, 4, 0, 0, 0}, + {4, 23, 14, 0, 0, 0}, + {26, 0, 4, 0, 0, 0}, + {4, 24, 14, 0, 0, 0}, + {4, 25, 14, 0, 0, 0}, + {19, 0, 4, 0, 0, 0}, + {14, 0, 12, 0, 0, 0}, + {27, 0, 5, 0, 0, 0}, + {26, 0, 11, 0, 0, 0}, + {28, 0, 5, 0, 0, 0}, + {26, 0, 13, 0, 0, 0}, + {26, 0, 5, 0, 0, 0}, + {4, 30, 14, 0, 0, 0}, + {4, 31, 14, 0, 0, 0}, + {4, 32, 14, 0, 0, 0}, + {14, 0, 5, 0, 0, 0}, + {19, 0, 5, 0, 0, 0}, + {19, 0, 5, 0, 0, 10}, + {18, 0, 5, 0, 0, 0}, + {4, 27, 14, 0, 0, 0}, + {4, 28, 14, 0, 0, 0}, + {4, 29, 14, 0, 0, 0}, + {4, 33, 14, 0, 0, 0}, + {4, 34, 14, 0, 0, 0}, + {4, 230, 14, 0, 0, 80}, + {4, 220, 14, 0, 0, 80}, + {7, 0, 12, 0, 0, 0}, + {26, 0, 12, 0, 0, 0}, + {4, 35, 14, 0, 0, 0}, + {19, 0, 5, 0, 0, 136}, + {7, 0, 9, 0, 0, 0}, + {30, 0, 5, 0, 0, 0}, + {4, 36, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 0}, + {7, 0, 4, 0, 0, 0}, + {18, 0, 4, 0, 0, 0}, + {26, 0, 19, 0, 0, 0}, + {28, 0, 4, 0, 0, 0}, + {29, 0, 5, 0, 0, 0}, + {5, 0, 1, 0, 0, 0}, + {19, 0, 1, 0, 0, 10}, + {4, 7, 14, 0, 0, 80}, + {4, 9, 14, 0, 0, 0}, + {19, 0, 1, 0, 0, 170}, + {7, 0, 1, 0, 0, 0}, + {4, 7, 14, 0, 0, 0}, + {5, 0, 1, 0, 0, 80}, + {5, 0, 1, 0, 0, 10}, + {9, 0, 1, 0, 0, 0}, + {4, 0, 14, 0, 0, 80}, + {4, 0, 14, 0, 0, 10}, + {4, 84, 14, 0, 0, 0}, + {4, 91, 14, 0, 0, 80}, + {9, 0, 19, 0, 0, 0}, + {4, 0, 1, 0, 0, 0}, + {4, 9, 14, 0, 0, 80}, + {19, 0, 1, 0, 0, 136}, + {4, 103, 14, 0, 0, 0}, + {4, 107, 14, 0, 0, 0}, + {4, 118, 14, 0, 0, 0}, + {4, 122, 14, 0, 0, 0}, + {26, 0, 1, 0, 0, 136}, + {4, 216, 14, 0, 0, 0}, + {22, 0, 19, 1, 0, 0}, + {23, 0, 19, 1, 0, 0}, + {4, 129, 14, 0, 0, 0}, + {4, 130, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 170}, + {4, 132, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 136}, {19, 0, 1, 0, 2, 0}, - {19, 0, 1, 0, 5, 80}, - {10, 0, 18, 0, 5, 0}, - {8, 0, 1, 0, 5, 0}, - {5, 9, 1, 0, 5, 0}, - {14, 0, 15, 0, 5, 0}, - {4, 1, 14, 0, 5, 0}, - {4, 234, 14, 0, 5, 0}, - {4, 214, 14, 0, 5, 0}, - {4, 202, 14, 0, 5, 0}, - {4, 232, 14, 0, 5, 0}, - {4, 218, 14, 0, 5, 0}, - {4, 233, 14, 0, 5, 0}, - {2, 0, 1, 0, 5, 138}, - {2, 0, 1, 0, 5, 170}, - {3, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 170}, - {29, 0, 19, 0, 5, 170}, - {10, 0, 18, 0, 5, 170}, - {10, 0, 18, 0, 5, 136}, - {14, 0, 1, 0, 5, 0}, - {14, 0, 4, 0, 5, 0}, + {19, 0, 1, 0, 0, 80}, + {10, 0, 18, 0, 0, 0}, + {8, 0, 1, 0, 0, 0}, + {5, 9, 1, 0, 0, 0}, + {14, 0, 15, 0, 0, 0}, + {4, 1, 14, 0, 0, 0}, + {4, 234, 14, 0, 0, 0}, + {4, 214, 14, 0, 0, 0}, + {4, 202, 14, 0, 0, 0}, + {4, 232, 14, 0, 0, 0}, + {4, 218, 14, 0, 0, 0}, + {4, 233, 14, 0, 0, 0}, + {2, 0, 1, 0, 0, 138}, + {2, 0, 1, 0, 0, 170}, + {3, 0, 1, 0, 0, 10}, + {1, 0, 1, 0, 0, 170}, + {29, 0, 19, 0, 0, 170}, + {10, 0, 18, 0, 0, 170}, + {10, 0, 18, 0, 0, 136}, + {14, 0, 1, 0, 0, 0}, + {14, 0, 4, 0, 0, 0}, {21, 0, 19, 0, 4, 0}, - {21, 0, 19, 0, 5, 136}, - {26, 0, 19, 0, 5, 136}, + {21, 0, 19, 0, 0, 136}, + {26, 0, 19, 0, 0, 136}, {24, 0, 19, 0, 4, 0}, {25, 0, 19, 0, 4, 0}, - {22, 0, 19, 0, 5, 0}, - {24, 0, 19, 0, 5, 0}, + {22, 0, 19, 0, 0, 0}, + {24, 0, 19, 0, 0, 0}, {26, 0, 19, 0, 4, 136}, - {11, 0, 18, 0, 5, 0}, - {12, 0, 16, 0, 5, 0}, - {14, 0, 2, 0, 5, 0}, - {14, 0, 6, 0, 5, 0}, - {14, 0, 8, 0, 5, 0}, - {14, 0, 3, 0, 5, 0}, - {14, 0, 7, 0, 5, 0}, + {11, 0, 18, 0, 0, 0}, + {12, 0, 16, 0, 0, 0}, + {14, 0, 2, 0, 0, 0}, + {14, 0, 6, 0, 0, 0}, + {14, 0, 8, 0, 0, 0}, + {14, 0, 3, 0, 0, 0}, + {14, 0, 7, 0, 0, 0}, {26, 0, 11, 0, 4, 0}, {26, 0, 11, 0, 4, 136}, - {26, 0, 11, 0, 5, 136}, - {20, 0, 19, 0, 5, 0}, - {27, 0, 13, 0, 5, 0}, - {14, 0, 20, 0, 5, 0}, - {14, 0, 21, 0, 5, 0}, - {14, 0, 22, 0, 5, 0}, - {14, 0, 23, 0, 5, 0}, - {9, 0, 9, 0, 5, 136}, - {27, 0, 10, 0, 5, 136}, - {27, 0, 19, 0, 5, 136}, - {22, 0, 19, 1, 5, 136}, - {23, 0, 19, 1, 5, 136}, + {26, 0, 11, 0, 0, 136}, + {20, 0, 19, 0, 0, 0}, + {27, 0, 13, 0, 0, 0}, + {14, 0, 20, 0, 0, 0}, + {14, 0, 21, 0, 0, 0}, + {14, 0, 22, 0, 0, 0}, + {14, 0, 23, 0, 0, 0}, + {9, 0, 9, 0, 0, 136}, + {27, 0, 10, 0, 0, 136}, + {27, 0, 19, 0, 0, 136}, + {22, 0, 19, 1, 0, 136}, + {23, 0, 19, 1, 0, 136}, {18, 0, 1, 0, 4, 136}, - {28, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 0, 136}, {28, 0, 11, 0, 1, 0}, - {30, 0, 19, 0, 5, 136}, + {30, 0, 19, 0, 0, 136}, {30, 0, 19, 0, 4, 136}, {1, 0, 1, 0, 4, 170}, - {30, 0, 11, 0, 5, 0}, - {27, 0, 19, 1, 5, 136}, - {9, 0, 19, 0, 5, 136}, + {30, 0, 11, 0, 0, 0}, + {27, 0, 19, 1, 0, 136}, + {9, 0, 19, 0, 0, 136}, {8, 0, 1, 0, 4, 136}, - {8, 0, 1, 0, 5, 136}, - {27, 0, 19, 0, 5, 10}, - {30, 0, 19, 0, 5, 10}, - {27, 0, 19, 1, 5, 0}, + {8, 0, 1, 0, 0, 136}, + {27, 0, 19, 0, 0, 10}, + {30, 0, 19, 0, 0, 10}, + {27, 0, 19, 1, 0, 0}, {27, 0, 19, 1, 4, 0}, - {27, 0, 19, 1, 5, 10}, - {27, 0, 10, 0, 5, 0}, - {27, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 0, 10}, + {27, 0, 10, 0, 0, 0}, + {27, 0, 11, 0, 0, 0}, {27, 0, 19, 1, 4, 136}, {27, 0, 19, 1, 4, 10}, {30, 0, 19, 0, 2, 0}, @@ -252,10 +252,10 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {30, 0, 1, 0, 4, 136}, {9, 0, 19, 0, 4, 0}, {27, 0, 19, 0, 2, 0}, - {27, 0, 19, 1, 5, 170}, - {30, 0, 19, 1, 5, 0}, + {27, 0, 19, 1, 0, 170}, + {30, 0, 19, 1, 0, 0}, {30, 0, 19, 0, 2, 136}, - {10, 0, 18, 0, 0, 136}, + {10, 0, 18, 0, 5, 136}, {26, 0, 19, 0, 2, 0}, {18, 0, 1, 0, 2, 0}, {8, 0, 1, 0, 2, 0}, @@ -280,15 +280,16 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {30, 0, 1, 0, 2, 136}, {9, 0, 1, 0, 4, 0}, {9, 0, 19, 0, 2, 136}, - {29, 0, 1, 0, 5, 0}, - {15, 0, 1, 0, 5, 0}, + {29, 0, 1, 0, 0, 0}, + {15, 0, 1, 0, 0, 0}, {16, 0, 1, 0, 4, 0}, {19, 0, 1, 0, 2, 170}, - {19, 0, 4, 0, 5, 170}, - {4, 26, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 136}, - {23, 0, 19, 0, 5, 0}, - {28, 0, 5, 0, 5, 136}, + {0, 0, 0, 0, 2, 0}, + {19, 0, 4, 0, 0, 170}, + {4, 26, 14, 0, 0, 0}, + {19, 0, 4, 0, 0, 136}, + {23, 0, 19, 0, 0, 0}, + {28, 0, 5, 0, 0, 136}, {26, 0, 19, 0, 2, 136}, {22, 0, 19, 0, 2, 136}, {23, 0, 19, 0, 2, 136}, @@ -303,47 +304,47 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {27, 0, 19, 1, 2, 136}, {27, 0, 19, 0, 2, 136}, {28, 0, 11, 0, 2, 136}, - {26, 0, 19, 0, 0, 136}, - {26, 0, 11, 0, 0, 136}, - {28, 0, 11, 0, 0, 136}, - {22, 0, 19, 1, 0, 136}, - {23, 0, 19, 1, 0, 136}, - {27, 0, 10, 0, 0, 136}, - {26, 0, 13, 0, 0, 136}, - {21, 0, 10, 0, 0, 136}, - {7, 0, 9, 0, 0, 136}, - {27, 0, 19, 1, 0, 136}, - {27, 0, 19, 0, 0, 136}, - {1, 0, 1, 0, 0, 136}, - {29, 0, 19, 0, 0, 136}, - {20, 0, 19, 0, 0, 136}, - {2, 0, 1, 0, 0, 136}, + {26, 0, 19, 0, 5, 136}, + {26, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 5, 136}, + {22, 0, 19, 1, 5, 136}, + {23, 0, 19, 1, 5, 136}, + {27, 0, 10, 0, 5, 136}, + {26, 0, 13, 0, 5, 136}, + {21, 0, 10, 0, 5, 136}, + {7, 0, 9, 0, 5, 136}, + {27, 0, 19, 1, 5, 136}, + {27, 0, 19, 0, 5, 136}, + {1, 0, 1, 0, 5, 136}, + {29, 0, 19, 0, 5, 136}, + {20, 0, 19, 0, 5, 136}, + {2, 0, 1, 0, 5, 136}, {26, 0, 19, 0, 1, 136}, {22, 0, 19, 1, 1, 136}, {23, 0, 19, 1, 1, 136}, {19, 0, 1, 0, 1, 136}, {18, 0, 1, 0, 1, 136}, - {30, 0, 19, 0, 0, 136}, + {30, 0, 19, 0, 5, 136}, {30, 0, 19, 0, 1, 136}, {27, 0, 19, 0, 1, 136}, - {14, 0, 19, 0, 5, 0}, - {8, 0, 19, 0, 5, 0}, - {9, 0, 9, 0, 5, 0}, - {9, 0, 4, 0, 5, 0}, - {30, 0, 4, 0, 5, 0}, - {1, 0, 4, 0, 5, 0}, - {2, 0, 4, 0, 5, 0}, - {9, 0, 12, 0, 5, 0}, - {9, 0, 5, 0, 5, 0}, - {4, 9, 1, 0, 5, 0}, + {14, 0, 19, 0, 0, 0}, + {8, 0, 19, 0, 0, 0}, + {9, 0, 9, 0, 0, 0}, + {9, 0, 4, 0, 0, 0}, + {30, 0, 4, 0, 0, 0}, + {1, 0, 4, 0, 0, 0}, + {2, 0, 4, 0, 0, 0}, + {9, 0, 12, 0, 0, 0}, + {9, 0, 5, 0, 0, 0}, + {4, 9, 1, 0, 0, 0}, {4, 0, 14, 0, 2, 0}, {5, 6, 1, 0, 2, 0}, - {30, 0, 1, 0, 5, 170}, - {5, 216, 1, 0, 5, 0}, - {5, 226, 1, 0, 5, 0}, - {27, 0, 1, 0, 5, 136}, - {7, 0, 9, 0, 5, 136}, - {30, 0, 1, 0, 5, 136}, + {30, 0, 1, 0, 0, 170}, + {5, 216, 1, 0, 0, 0}, + {5, 226, 1, 0, 0, 0}, + {27, 0, 1, 0, 0, 136}, + {7, 0, 9, 0, 0, 136}, + {30, 0, 1, 0, 0, 136}, {30, 0, 1, 0, 4, 0}, {29, 0, 19, 0, 2, 0}, }; @@ -674,12 +675,12 @@ const char *_PyUnicode_BidirectionalNames[] = { NULL }; const char *_PyUnicode_EastAsianWidthNames[] = { - "F", + "N", "H", "W", "Na", "A", - "N", + "F", NULL }; static const char *decomp_prefix[] = { @@ -809,38 +810,46 @@ static const unsigned short index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 267, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 121, 121, 121, 121, 268, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 121, 121, 121, 121, 269, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 270, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 269, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 271, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 270, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1206,15 +1215,7 @@ static const unsigned short index1[] = { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 270, 137, 271, 272, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 272, 137, 273, 274, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1287,7 +1288,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 273, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 275, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, @@ -1324,7 +1325,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 273, + 120, 275, }; static const unsigned short index2[] = { @@ -2259,7 +2260,7 @@ static const unsigned short index2[] = { 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 0, 0, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, @@ -2267,22 +2268,23 @@ static const unsigned short index2[] = { 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, - 281, 282, 281, 283, 283, 283, 283, 283, 283, 283, 283, 283, 219, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 281, 281, - 281, 281, 281, 0, 281, 0, 281, 281, 0, 281, 281, 0, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 283, 131, 131, 131, 131, 131, 131, 131, 131, + 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 35, 35, 35, + 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, + 0, 0, 0, 0, 0, 282, 283, 282, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 219, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 0, 282, 282, 282, 282, 282, 0, 282, 0, 282, 282, 0, 282, 282, 0, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 284, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2299,26 +2301,26 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 284, 199, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 285, 199, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 285, 26, 26, 26, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 286, 286, 286, 286, 286, 286, 286, 287, 288, 286, 0, 0, 0, 0, - 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 81, 81, - 286, 289, 289, 290, 290, 287, 288, 287, 288, 287, 288, 287, 288, 287, - 288, 287, 288, 287, 288, 287, 288, 253, 253, 287, 288, 286, 286, 286, - 286, 290, 290, 290, 291, 286, 291, 0, 286, 291, 286, 286, 289, 292, 293, - 292, 293, 292, 293, 294, 286, 286, 295, 296, 297, 297, 298, 0, 286, 299, - 294, 286, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 286, 26, 26, 26, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 287, 287, 287, 287, 287, 287, 287, 288, 289, + 287, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, + 86, 86, 81, 81, 287, 290, 290, 291, 291, 288, 289, 288, 289, 288, 289, + 288, 289, 288, 289, 288, 289, 288, 289, 288, 289, 253, 253, 288, 289, + 287, 287, 287, 287, 291, 291, 291, 292, 287, 292, 0, 287, 292, 287, 287, + 290, 293, 294, 293, 294, 293, 294, 295, 287, 287, 296, 297, 298, 298, + 299, 0, 287, 300, 295, 287, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2328,278 +2330,278 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 0, 0, 177, 0, 300, 300, 301, 302, 301, 300, 300, - 303, 304, 300, 305, 306, 307, 306, 306, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 306, 300, 309, 310, 309, 300, 300, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 303, 300, 304, 312, 313, - 312, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 303, - 310, 304, 310, 303, 304, 315, 316, 317, 315, 315, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 319, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 319, 319, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 0, 0, 0, 318, 318, 318, 318, 318, 318, 0, 0, 318, 318, 318, 318, - 318, 318, 0, 0, 318, 318, 318, 318, 318, 318, 0, 0, 318, 318, 318, 0, 0, - 0, 302, 302, 310, 312, 320, 302, 302, 0, 321, 322, 322, 322, 322, 321, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 323, 323, 26, 30, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 177, 0, 301, 301, 302, 303, + 302, 301, 301, 304, 305, 301, 306, 307, 308, 307, 307, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 307, 301, 310, 311, 310, 301, 301, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 304, 301, + 305, 313, 314, 313, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 304, 311, 305, 311, 304, 305, 316, 317, 318, 316, 316, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, + 320, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 0, 0, 0, 319, 319, 319, 319, 319, 319, 0, 0, 319, + 319, 319, 319, 319, 319, 0, 0, 319, 319, 319, 319, 319, 319, 0, 0, 319, + 319, 319, 0, 0, 0, 303, 303, 311, 313, 321, 303, 303, 0, 322, 323, 323, + 323, 323, 322, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 324, 324, 26, 30, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 150, 150, 150, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, - 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 155, 155, 155, 155, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 155, 155, 26, 80, 80, 0, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 155, 155, 155, 155, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 155, 155, 26, 80, + 80, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 80, 80, 80, 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 150, 150, 150, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 175, 48, 48, 48, 48, 48, 48, 48, 48, 175, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 150, + 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 175, 48, 48, 48, 48, 48, 48, + 48, 48, 175, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 83, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, + 48, 48, 48, 48, 48, 48, 48, 83, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 48, 48, 48, 48, 48, 48, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 44, 44, - 44, 44, 44, 0, 44, 44, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, - 47, 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 0, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 51, 51, 51, 51, - 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 53, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 0, 0, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, 0, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 107, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, + 0, 0, 0, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, + 327, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, 326, 326, 326, 326, - 326, 326, 326, 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, - 327, 326, 326, 326, 326, 326, 326, 326, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 328, 328, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, - 0, 0, 326, 326, 326, 326, 326, 326, 326, 326, 326, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 107, 107, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, 107, 107, 107, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 326, 326, 326, 326, 326, 326, 0, 0, 0, 138, 107, + 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 0, 0, 327, 327, 327, 327, + 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, 327, 327, 327, + 327, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 326, 326, - 107, 107, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 0, 0, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 107, 135, 135, 135, 0, 135, - 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, 107, 0, 107, 107, - 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 0, 0, 81, 178, 86, 0, 0, 0, 0, 144, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, + 0, 0, 0, 327, 327, 107, 107, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 0, 0, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 107, 135, + 135, 135, 0, 135, 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, + 107, 0, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, 104, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 0, 0, 81, 178, 86, 0, 0, 0, 0, 144, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, - 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 327, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, + 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 86, 0, 0, 0, 0, 326, 326, 326, 326, 326, 104, 104, 104, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, + 107, 107, 107, 328, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 81, 86, 0, 0, 0, 0, 327, 327, 327, 327, 327, 104, + 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 326, 326, 326, 326, 326, 326, 326, - 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, - 326, 326, 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, 326, - 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, + 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 327, 327, + 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, + 327, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, + 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, + 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, 0, 326, - 326, 326, 326, 326, 326, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 0, 0, 0, + 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 81, 81, - 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 118, 118, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 107, 0, 0, 0, 0, 0, 0, 0, 0, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 86, 86, 81, 81, 81, 86, 81, 86, - 86, 86, 86, 331, 331, 331, 331, 113, 113, 113, 113, 113, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 86, 81, 86, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 326, 326, 326, 326, 326, 326, 326, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, + 107, 107, 107, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 107, 0, + 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 86, 86, 81, + 81, 81, 86, 81, 86, 86, 86, 86, 332, 332, 332, 332, 113, 113, 113, 113, + 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 135, 141, + 107, 107, 107, 107, 81, 86, 81, 86, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, 327, + 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 141, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 144, 83, - 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 144, 48, 48, 135, 135, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 135, 135, 141, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 142, - 48, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 142, 48, - 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 141, 141, 144, 143, 83, - 83, 192, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, 135, 135, - 135, 135, 141, 135, 152, 152, 135, 135, 135, 144, 144, 0, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, 83, 48, 141, 141, 48, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 144, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 144, 48, + 48, 135, 135, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 135, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 147, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, - 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 142, 48, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 142, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 141, 141, + 144, 143, 83, 83, 192, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, + 135, 135, 135, 135, 141, 135, 152, 152, 135, 135, 135, 144, 144, 0, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, 83, 48, 141, + 141, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 141, 176, 48, 48, 48, 48, 83, 83, - 83, 83, 135, 147, 135, 135, 83, 141, 135, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 48, 83, 48, 83, 83, 83, 0, 150, 150, 150, 150, 150, + 48, 48, 48, 48, 48, 48, 48, 147, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 135, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, + 141, 135, 135, 135, 135, 135, 135, 135, 135, 135, 141, 176, 48, 48, 48, + 48, 83, 83, 83, 83, 135, 147, 135, 135, 83, 141, 135, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 48, 83, 48, 83, 83, 83, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, - 141, 141, 135, 135, 135, 141, 141, 135, 176, 147, 135, 83, 83, 83, 83, - 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 141, 141, 141, 135, 135, 135, 141, 141, 135, 176, 147, 135, 83, + 83, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 135, 141, 141, 141, 135, 135, 135, 135, 135, 135, 147, 144, 0, 0, 0, 0, - 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 135, 135, 141, 141, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, - 48, 48, 48, 0, 147, 147, 48, 148, 141, 135, 141, 141, 141, 141, 0, 0, + 48, 48, 48, 135, 141, 141, 141, 135, 135, 135, 135, 135, 135, 147, 144, + 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, + 0, 0, 0, 135, 135, 141, 141, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, + 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, + 48, 48, 48, 48, 0, 147, 147, 48, 148, 141, 135, 141, 141, 141, 141, 0, 0, 141, 141, 0, 0, 149, 149, 176, 0, 0, 48, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 141, 141, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, @@ -2688,7 +2690,7 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 135, 135, 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, - 141, 332, 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, + 141, 333, 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -2815,7 +2817,7 @@ static const unsigned short index2[] = { 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, - 253, 254, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 334, 334, 0, 0, 0, 0, 0, + 253, 254, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -2899,13 +2901,13 @@ static const unsigned short index2[] = { 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 335, 335, 335, 335, 335, 335, 335, - 336, 336, 178, 178, 178, 80, 80, 80, 337, 336, 336, 336, 336, 336, 177, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 336, 336, 336, 336, 336, 336, 336, + 337, 337, 178, 178, 178, 80, 80, 80, 338, 337, 337, 337, 337, 337, 177, 177, 177, 177, 177, 177, 177, 177, 86, 86, 86, 86, 86, 86, 86, 86, 80, 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 335, 335, 335, 335, 335, 335, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 336, 336, 336, 336, 336, 336, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, @@ -2966,26 +2968,26 @@ static const unsigned short index2[] = { 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, @@ -3044,35 +3046,35 @@ static const unsigned short index2[] = { 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 0, 0, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 329, 329, 329, 329, 329, + 0, 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 81, 81, 81, 81, 81, 81, 147, 137, 0, 0, 0, 0, 136, 136, 136, 136, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 81, 81, 81, 81, 81, 81, 147, 137, 0, 0, 0, 0, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 133, - 331, 331, 331, 111, 331, 331, 331, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 133, + 332, 332, 332, 111, 332, 332, 332, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 133, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 133, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -3106,16 +3108,16 @@ static const unsigned short index2[] = { 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 155, 155, 26, 26, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 340, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 341, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 246, 246, 246, 246, 246, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 226, 226, 226, 26, 26, 26, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 272, 341, - 246, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 246, 246, 246, 246, 246, 246, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 226, 226, 226, 26, 26, 26, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 272, 342, + 246, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 274, 274, @@ -3142,8 +3144,8 @@ static const unsigned short index2[] = { 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 26, 26, 26, 243, 26, 26, 26, 243, 243, 243, 342, 342, - 342, 342, 342, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 26, 26, 26, 243, 26, 26, 26, 243, 243, 243, 343, 343, + 343, 343, 343, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, @@ -3265,27 +3267,28 @@ static const unsigned short index2[] = { 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, 281, 281, 281, + 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -3294,9 +3297,9 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -3308,30 +3311,55 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, + 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, @@ -3344,8 +3372,7 @@ static const unsigned short index2[] = { 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, @@ -3354,7 +3381,7 @@ static const unsigned short index2[] = { 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 0, 0, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 0, 0, }; /* decomposition data */ @@ -5939,7 +5966,7 @@ static const change_record change_records_3_2_0[] = { { 19, 30, 255, 255, 255, 0 }, { 255, 8, 255, 255, 255, 0 }, { 255, 27, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 5, 0 }, + { 255, 255, 255, 255, 0, 0 }, { 255, 22, 255, 255, 255, 0 }, { 255, 23, 255, 255, 255, 0 }, { 9, 255, 255, 255, 255, 0 }, diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index f28266f390c1..c30175929d60 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -77,7 +77,8 @@ "PDF", "EN", "ES", "ET", "AN", "CS", "NSM", "BN", "B", "S", "WS", "ON", "LRI", "RLI", "FSI", "PDI" ] -EASTASIANWIDTH_NAMES = [ "F", "H", "W", "Na", "A", "N" ] +# "N" needs to be the first entry, see the comment in makeunicodedata +EASTASIANWIDTH_NAMES = [ "N", "H", "W", "Na", "A", "F" ] MANDATORY_LINE_BREAKS = [ "BK", "CR", "LF", "NL" ] @@ -135,6 +136,14 @@ def maketables(trace=0): def makeunicodedata(unicode, trace): + # the default value of east_asian_width is "N", for unassigned code points + # not mentioned in EastAsianWidth.txt + # in addition there are some reserved but unassigned code points in CJK + # ranges that are classified as "W". code points in private use areas + # have a width of "A". both of these have entries in + # EastAsianWidth.txt + # see https://unicode.org/reports/tr11/#Unassigned + assert EASTASIANWIDTH_NAMES[0] == "N" dummy = (0, 0, 0, 0, 0, 0) table = [dummy] cache = {0: dummy} @@ -160,12 +169,20 @@ def makeunicodedata(unicode, trace): category, combining, bidirectional, mirrored, eastasianwidth, normalizationquickcheck ) - # add entry to index and item tables - i = cache.get(item) - if i is None: - cache[item] = i = len(table) - table.append(item) - index[char] = i + elif unicode.widths[char] is not None: + # an unassigned but reserved character, with a known + # east_asian_width + eastasianwidth = EASTASIANWIDTH_NAMES.index(unicode.widths[char]) + item = (0, 0, 0, 0, eastasianwidth, 0) + else: + continue + + # add entry to index and item tables + i = cache.get(item) + if i is None: + cache[item] = i = len(table) + table.append(item) + index[char] = i # 2) decomposition data @@ -1085,6 +1102,7 @@ def __init__(self, version, cjk_check=True): for i in range(0, 0x110000): if table[i] is not None: table[i].east_asian_width = widths[i] + self.widths = widths for char, (p,) in UcdFile(DERIVED_CORE_PROPERTIES, version).expanded(): if table[char]: From webhook-mailer at python.org Fri Aug 26 15:05:28 2022 From: webhook-mailer at python.org (ezio-melotti) Date: Fri, 26 Aug 2022 19:05:28 -0000 Subject: [Python-checkins] gh-95994: Clarify escaped newlines. (#96066) Message-ID: <mailman.840.1661540729.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c3d591fd0699605c8253beda2372114052a7bdba commit: c3d591fd0699605c8253beda2372114052a7bdba branch: main author: Ezio Melotti <ezio.melotti at gmail.com> committer: ezio-melotti <ezio.melotti at gmail.com> date: 2022-08-26T21:05:01+02:00 summary: gh-95994: Clarify escaped newlines. (#96066) * gh-95994: clarify escaped newlines. * Rephrase ambiguous sentence. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> * Use `<newline>` in escape sequences table. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> files: M Doc/reference/lexical_analysis.rst diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index b76b4688413e..8fd8d70426a8 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -552,7 +552,7 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\newline`` | Backslash and newline ignored | | +| ``\``\ <newline>| Backslash and newline ignored | \(1) | +-----------------+---------------------------------+-------+ | ``\\`` | Backslash (``\``) | | +-----------------+---------------------------------+-------+ @@ -574,10 +574,10 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | ``\v`` | ASCII Vertical Tab (VT) | | +-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (1,3) | +| ``\ooo`` | Character with octal value | (2,4) | | | *ooo* | | +-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (2,3) | +| ``\xhh`` | Character with hex value *hh* | (3,4) | +-----------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: @@ -585,19 +585,30 @@ Escape sequences only recognized in string literals are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(4) | +| ``\N{name}`` | Character named *name* in the | \(5) | | | Unicode database | | +-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(5) | +| ``\uxxxx`` | Character with 16-bit hex value | \(6) | | | *xxxx* | | +-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(6) | +| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | | | *xxxxxxxx* | | +-----------------+---------------------------------+-------+ Notes: (1) + A backslash can be added at the end of a line to ignore the newline:: + + >>> 'This string will not include \ + ... backslashes or newline characters.' + 'This string will not include backslashes or newline characters.' + + The same result can be achieved using :ref:`triple-quoted strings <strings>`, + or parentheses and :ref:`string literal concatenation <string-concatenation>`. + + +(2) As in Standard C, up to three octal digits are accepted. .. versionchanged:: 3.11 @@ -605,22 +616,22 @@ Notes: In a future Python version they will be a :exc:`SyntaxWarning` and eventually a :exc:`SyntaxError`. -(2) +(3) Unlike in Standard C, exactly two hex digits are required. -(3) +(4) In a bytes literal, hexadecimal and octal escapes denote the byte with the given value. In a string literal, these escapes denote a Unicode character with the given value. -(4) +(5) .. versionchanged:: 3.3 Support for name aliases [#]_ has been added. -(5) +(6) Exactly four hex digits are required. -(6) +(7) Any Unicode character can be encoded this way. Exactly eight hex digits are required. From webhook-mailer at python.org Fri Aug 26 15:12:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 26 Aug 2022 19:12:08 -0000 Subject: [Python-checkins] gh-95994: Clarify escaped newlines. (GH-96066) Message-ID: <mailman.841.1661541129.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f0469c74243f1ad1b5c8d79647660d497ee29ffe commit: f0469c74243f1ad1b5c8d79647660d497ee29ffe branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-26T12:11:59-07:00 summary: gh-95994: Clarify escaped newlines. (GH-96066) * gh-95994: clarify escaped newlines. * Rephrase ambiguous sentence. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> * Use `<newline>` in escape sequences table. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> (cherry picked from commit c3d591fd0699605c8253beda2372114052a7bdba) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> files: M Doc/reference/lexical_analysis.rst diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index e75f460f8497..44726de3e037 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -548,7 +548,7 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\newline`` | Backslash and newline ignored | | +| ``\``\ <newline>| Backslash and newline ignored | \(1) | +-----------------+---------------------------------+-------+ | ``\\`` | Backslash (``\``) | | +-----------------+---------------------------------+-------+ @@ -570,10 +570,10 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | ``\v`` | ASCII Vertical Tab (VT) | | +-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (1,3) | +| ``\ooo`` | Character with octal value | (2,4) | | | *ooo* | | +-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (2,3) | +| ``\xhh`` | Character with hex value *hh* | (3,4) | +-----------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: @@ -581,19 +581,30 @@ Escape sequences only recognized in string literals are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(4) | +| ``\N{name}`` | Character named *name* in the | \(5) | | | Unicode database | | +-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(5) | +| ``\uxxxx`` | Character with 16-bit hex value | \(6) | | | *xxxx* | | +-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(6) | +| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | | | *xxxxxxxx* | | +-----------------+---------------------------------+-------+ Notes: (1) + A backslash can be added at the end of a line to ignore the newline:: + + >>> 'This string will not include \ + ... backslashes or newline characters.' + 'This string will not include backslashes or newline characters.' + + The same result can be achieved using :ref:`triple-quoted strings <strings>`, + or parentheses and :ref:`string literal concatenation <string-concatenation>`. + + +(2) As in Standard C, up to three octal digits are accepted. .. versionchanged:: 3.11 @@ -601,22 +612,22 @@ Notes: In a future Python version they will be a :exc:`SyntaxWarning` and eventually a :exc:`SyntaxError`. -(2) +(3) Unlike in Standard C, exactly two hex digits are required. -(3) +(4) In a bytes literal, hexadecimal and octal escapes denote the byte with the given value. In a string literal, these escapes denote a Unicode character with the given value. -(4) +(5) .. versionchanged:: 3.3 Support for name aliases [#]_ has been added. -(5) +(6) Exactly four hex digits are required. -(6) +(7) Any Unicode character can be encoded this way. Exactly eight hex digits are required. From webhook-mailer at python.org Fri Aug 26 17:21:49 2022 From: webhook-mailer at python.org (brettcannon) Date: Fri, 26 Aug 2022 21:21:49 -0000 Subject: [Python-checkins] Fix documentation typo for pathlib.Path.walk (GH-96301) Message-ID: <mailman.842.1661548910.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b462f143ff9592179d82680d0156eedb74705ed4 commit: b462f143ff9592179d82680d0156eedb74705ed4 branch: main author: Ansab Gillani <56605828+ansabgillani at users.noreply.github.com> committer: brettcannon <brett at python.org> date: 2022-08-26T14:21:40-07:00 summary: Fix documentation typo for pathlib.Path.walk (GH-96301) files: M Doc/library/pathlib.rst diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index f7d7745eef5..1375ce1aef9 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1038,7 +1038,7 @@ call fails (for example because the path doesn't exist). # Delete everything reachable from the directory "top". # CAUTION: This is dangerous! For example, if top == Path('/'), # it could delete all of your files. - for root, dirs, files in top.walk(topdown=False): + for root, dirs, files in top.walk(top_down=False): for name in files: (root / name).unlink() for name in dirs: From webhook-mailer at python.org Fri Aug 26 17:44:48 2022 From: webhook-mailer at python.org (iritkatriel) Date: Fri, 26 Aug 2022 21:44:48 -0000 Subject: [Python-checkins] gh-96280: suppress deprecation warning in test_importlib (GH-96281) Message-ID: <mailman.843.1661550289.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ccf94a6289c722f56000ffed5dd416371127c759 commit: ccf94a6289c722f56000ffed5dd416371127c759 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-08-26T22:44:33+01:00 summary: gh-96280: suppress deprecation warning in test_importlib (GH-96281) files: M Lib/test/test_importlib/test_abc.py diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index 88bf100efaa..430dd77f876 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -322,7 +322,9 @@ def contents(self, *args, **kwargs): class ResourceReaderDefaultsTests(ABCTestHarness): - SPLIT = make_abc_subclasses(ResourceReader) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + SPLIT = make_abc_subclasses(ResourceReader) def test_open_resource(self): with self.assertRaises(FileNotFoundError): From webhook-mailer at python.org Fri Aug 26 19:24:55 2022 From: webhook-mailer at python.org (vsajip) Date: Fri, 26 Aug 2022 23:24:55 -0000 Subject: [Python-checkins] gh-77116: Add SMTP buffering example to logging cookbook. (GH-96324) Message-ID: <mailman.844.1661556297.3313.python-checkins@python.org> https://github.com/python/cpython/commit/43a6deadbb40bc93e0eaebb3c56c34f8a3502132 commit: 43a6deadbb40bc93e0eaebb3c56c34f8a3502132 branch: main author: Vinay Sajip <vinay_sajip at yahoo.co.uk> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T00:24:36+01:00 summary: gh-77116: Add SMTP buffering example to logging cookbook. (GH-96324) files: M Doc/howto/logging-cookbook.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 321c4bc510ad..16df3b730ac8 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2678,6 +2678,88 @@ You can of course use the conventional means of decoration:: ... +.. _buffered-smtp: + +Sending logging messages to email, with buffering +------------------------------------------------- + +To illustrate how you can send log messages via email, so that a set number of +messages are sent per email, you can subclass +:class:`~logging.handlers.BufferingHandler`. In the following example, which you can +adapt to suit your specific needs, a simple test harness is provided which allows you +to run the script with command line arguments specifying what you typically need to +send things via SMTP. (Run the downloaded script with the ``-h`` argument to see the +required and optional arguments.) + +.. code-block:: python + + import logging + import logging.handlers + import smtplib + + class BufferingSMTPHandler(logging.handlers.BufferingHandler): + def __init__(self, mailhost, port, username, password, fromaddr, toaddrs, + subject, capacity): + logging.handlers.BufferingHandler.__init__(self, capacity) + self.mailhost = mailhost + self.mailport = port + self.username = username + self.password = password + self.fromaddr = fromaddr + if isinstance(toaddrs, str): + toaddrs = [toaddrs] + self.toaddrs = toaddrs + self.subject = subject + self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s")) + + def flush(self): + if len(self.buffer) > 0: + try: + smtp = smtplib.SMTP(self.mailhost, self.mailport) + smtp.starttls() + smtp.login(self.username, self.password) + msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject) + for record in self.buffer: + s = self.format(record) + msg = msg + s + "\r\n" + smtp.sendmail(self.fromaddr, self.toaddrs, msg) + smtp.quit() + except Exception: + if logging.raiseExceptions: + raise + self.buffer = [] + + if __name__ == '__main__': + import argparse + + ap = argparse.ArgumentParser() + aa = ap.add_argument + aa('host', metavar='HOST', help='SMTP server') + aa('--port', '-p', type=int, default=587, help='SMTP port') + aa('user', metavar='USER', help='SMTP username') + aa('password', metavar='PASSWORD', help='SMTP password') + aa('to', metavar='TO', help='Addressee for emails') + aa('sender', metavar='SENDER', help='Sender email address') + aa('--subject', '-s', + default='Test Logging email from Python logging module (buffering)', + help='Subject of email') + options = ap.parse_args() + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + h = BufferingSMTPHandler(options.host, options.port, options.user, + options.password, options.sender, + options.to, options.subject, 10) + logger.addHandler(h) + for i in range(102): + logger.info("Info index = %d", i) + h.flush() + h.close() + +If you run this script and your SMTP server is correctly set up, you should find that +it sends eleven emails to the addressee you specify. The first ten emails will each +have ten log messages, and the eleventh will have two messages. That makes up 102 +messages as specified in the script. + .. _utc-formatting: Formatting times using UTC (GMT) via configuration From webhook-mailer at python.org Fri Aug 26 20:49:59 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 27 Aug 2022 00:49:59 -0000 Subject: [Python-checkins] gh-95973: Add a new --with-dsymutil option to link debug information in macOS (GH-95974) Message-ID: <mailman.845.1661561399.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5b070c0d40b0c7dd83b8c4eaa44812e9d2af14f9 commit: 5b070c0d40b0c7dd83b8c4eaa44812e9d2af14f9 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-26T17:49:41-07:00 summary: gh-95973: Add a new --with-dsymutil option to link debug information in macOS (GH-95974) Automerge-Triggered-By: GH:pablogsal files: A Misc/NEWS.d/next/Build/2022-08-15-10-56-07.gh-issue-95973.Bsswsc.rst M .gitignore M Makefile.pre.in M configure M configure.ac diff --git a/.gitignore b/.gitignore index 0ddfd717d737..924c136ba9aa 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,12 @@ *.cover *.iml *.o +*.lto *.a *.so *.so.* *.dylib +*.dSYM *.dll *.wasm *.orig diff --git a/Makefile.pre.in b/Makefile.pre.in index af203705d38e..94ddfa4b1bed 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -54,6 +54,8 @@ DTRACE= @DTRACE@ DFLAGS= @DFLAGS@ DTRACE_HEADERS= @DTRACE_HEADERS@ DTRACE_OBJS= @DTRACE_OBJS@ +DSYMUTIL= @DSYMUTIL@ +DSYMUTIL_PATH= @DSYMUTIL_PATH@ GNULD= @GNULD@ @@ -576,7 +578,7 @@ LIBEXPAT_HEADERS= \ # Default target all: @DEF_MAKE_ALL_RULE@ build_all: check-clean-src $(BUILDPYTHON) platform sharedmods \ - gdbhooks Programs/_testembed scripts checksharedmods + gdbhooks Programs/_testembed scripts checksharedmods rundsymutil build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \ python-config checksharedmods @@ -905,6 +907,22 @@ sharedmods: $(SHAREDMODS) pybuilddir.txt checksharedmods: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) @$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/scripts/check_extension_modules.py +rundsymutil: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @if [ ! -z $(DSYMUTIL) ] ; then \ + echo $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + if test -f $(LDLIBRARY); then \ + echo $(DSYMUTIL_PATH) $(LDLIBRARY); \ + $(DSYMUTIL_PATH) $(LDLIBRARY); \ + fi; \ + for mod in X $(SHAREDMODS); do \ + if test $$mod != X; then \ + echo $(DSYMUTIL_PATH) $$mod; \ + $(DSYMUTIL_PATH) $$mod; \ + fi; \ + done \ + fi + Modules/Setup.local: @# Create empty Setup.local when file was deleted by user echo "# Edit this file for local setup changes" > $@ @@ -1755,9 +1773,14 @@ sharedinstall: $(DESTSHARED) all if test $$i != X; then \ echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \ $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + if test -d "$$i.dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + fi; \ fi; \ done + $(DESTSHARED): @for i in $(DESTDIRS); \ do \ @@ -1818,6 +1841,23 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ -output $(DESTDIR)$(BINDIR)/python$(VERSION)-intel64$(EXE) \ $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ fi + # Install macOS debug information (if available) + if test -d "$(BUILDPYTHON).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + fi + if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + fi \ + else \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + fi \ + fi + bininstall: altbininstall if test ! -d $(DESTDIR)$(LIBPC); then \ @@ -2392,6 +2432,7 @@ clean-retain-profile: pycremoval find . -name '*.[oa]' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';' + find . -name '*.lto' -exec rm -f {} ';' find . -name '*.wasm' -exec rm -f {} ';' find . -name '*.lst' -exec rm -f {} ';' find build -name 'fficonfig.h' -exec rm -f {} ';' || true @@ -2508,7 +2549,7 @@ Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h # Declare targets that aren't real files .PHONY: all build_all build_wasm check-clean-src -.PHONY: sharedmods checksharedmods test quicktest +.PHONY: sharedmods checksharedmods test quicktest rundsymutil .PHONY: install altinstall sharedinstall bininstall altbininstall .PHONY: maninstall libinstall inclinstall libainstall .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure diff --git a/Misc/NEWS.d/next/Build/2022-08-15-10-56-07.gh-issue-95973.Bsswsc.rst b/Misc/NEWS.d/next/Build/2022-08-15-10-56-07.gh-issue-95973.Bsswsc.rst new file mode 100644 index 000000000000..d03bc5205ead --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-08-15-10-56-07.gh-issue-95973.Bsswsc.rst @@ -0,0 +1,2 @@ +Add a new ``--with-dsymutil`` configure option to to link debug information +in macOS. Patch by Pablo Galindo. diff --git a/configure b/configure index 1801f806ae13..ee2eabb13c07 100755 --- a/configure +++ b/configure @@ -869,6 +869,8 @@ BLDSHARED LDCXXSHARED LDSHARED SHLIB_SUFFIX +DSYMUTIL_PATH +DSYMUTIL LIBTOOL_CRUFT OTHER_LIBTOOL_OPT UNIVERSAL_ARCH_FLAGS @@ -1053,6 +1055,7 @@ with_assertions enable_optimizations with_lto enable_bolt +with_dsymutil with_address_sanitizer with_memory_sanitizer with_undefined_behavior_sanitizer @@ -1824,6 +1827,8 @@ Optional Packages: --with-lto=[full|thin|no|yes] enable Link-Time-Optimization in any build (default is no) + --with-dsymutil link debug information into final executable with + dsymutil in macOS (default is no) --with-address-sanitizer enable AddressSanitizer memory error detector, 'asan' (default is no) @@ -7831,10 +7836,10 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} # Any changes made here should be reflected in the GCC+Darwin case below if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" else - LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic" + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto=${Py_LTO_POLICY}" fi ;; @@ -7863,7 +7868,7 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} LDFLAGS_NOLTO="-fno-lto" case $ac_sys_system in Darwin*) - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" ;; *) @@ -10974,6 +10979,81 @@ else $as_echo "no" >&6; } fi +# Check for --with-dsymutil + + +DSYMUTIL= +DSYMUTIL_PATH= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dsymutil" >&5 +$as_echo_n "checking for --with-dsymutil... " >&6; } + +# Check whether --with-dsymutil was given. +if test "${with_dsymutil+set}" = set; then : + withval=$with_dsymutil; +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + as_fn_error $? "dsymutil debug linking is only available in macOS." "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + DSYMUTIL='true' +else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; DSYMUTIL= +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "$DSYMUTIL"; then + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DSYMUTIL_PATH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DSYMUTIL_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_DSYMUTIL_PATH="$DSYMUTIL_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DSYMUTIL_PATH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_DSYMUTIL_PATH" && ac_cv_path_DSYMUTIL_PATH="not found" + ;; +esac +fi +DSYMUTIL_PATH=$ac_cv_path_DSYMUTIL_PATH +if test -n "$DSYMUTIL_PATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL_PATH" >&5 +$as_echo "$DSYMUTIL_PATH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$DSYMUTIL_PATH" = "not found"; then + as_fn_error $? "dsymutil command not found on \$PATH" "$LINENO" 5 + fi +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dyld" >&5 $as_echo_n "checking for dyld... " >&6; } case $ac_sys_system/$ac_sys_release in diff --git a/configure.ac b/configure.ac index bb9fec07242f..02e5d6745712 100644 --- a/configure.ac +++ b/configure.ac @@ -1863,10 +1863,10 @@ if test "$Py_LTO" = 'true' ; then # Any changes made here should be reflected in the GCC+Darwin case below if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" else - LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic" + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto=${Py_LTO_POLICY}" fi ;; @@ -1896,7 +1896,7 @@ if test "$Py_LTO" = 'true' ; then LDFLAGS_NOLTO="-fno-lto" case $ac_sys_system in Darwin*) - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" ;; *) @@ -3053,6 +3053,33 @@ else AC_MSG_RESULT(no) fi +# Check for --with-dsymutil +AC_SUBST(DSYMUTIL) +AC_SUBST(DSYMUTIL_PATH) +DSYMUTIL= +DSYMUTIL_PATH= +AC_MSG_CHECKING(for --with-dsymutil) +AC_ARG_WITH(dsymutil, + AS_HELP_STRING([--with-dsymutil], [link debug information into final executable with dsymutil in macOS (default is no)]), +[ +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + AC_MSG_ERROR([dsymutil debug linking is only available in macOS.]) + fi + AC_MSG_RESULT(yes); + DSYMUTIL='true' +else AC_MSG_RESULT(no); DSYMUTIL= +fi], +[AC_MSG_RESULT(no)]) + +if test "$DSYMUTIL"; then + AC_PATH_PROG(DSYMUTIL_PATH, [dsymutil], [not found]) + if test "$DSYMUTIL_PATH" = "not found"; then + AC_MSG_ERROR([dsymutil command not found on \$PATH]) + fi +fi + AC_MSG_CHECKING(for dyld) case $ac_sys_system/$ac_sys_release in Darwin/*) From webhook-mailer at python.org Fri Aug 26 23:50:57 2022 From: webhook-mailer at python.org (gvanrossum) Date: Sat, 27 Aug 2022 03:50:57 -0000 Subject: [Python-checkins] Docs: Fix count of bullets in asyncio-task.rst (#96307) Message-ID: <mailman.846.1661572258.3313.python-checkins@python.org> https://github.com/python/cpython/commit/35e4da25d4c86c891a99cae4ddbb9edb7d911e9f commit: 35e4da25d4c86c891a99cae4ddbb9edb7d911e9f branch: main author: zhanpon <pon.zhan at gmail.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-26T20:50:48-07:00 summary: Docs: Fix count of bullets in asyncio-task.rst (#96307) files: M Doc/library/asyncio-task.rst diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index a6b638c11240..ffbf421bae5e 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -40,7 +40,7 @@ be executed:: >>> main() <coroutine object main at 0x1053bb7c8> -To actually run a coroutine, asyncio provides three main mechanisms: +To actually run a coroutine, asyncio provides the following mechanisms: * The :func:`asyncio.run` function to run the top-level entry point "main()" function (see the above example.) From webhook-mailer at python.org Sat Aug 27 01:06:35 2022 From: webhook-mailer at python.org (benjaminp) Date: Sat, 27 Aug 2022 05:06:35 -0000 Subject: [Python-checkins] fix threading.Event.isSet() docstring (#96297) Message-ID: <mailman.847.1661576796.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e53444051018af3351cc26c4bf1ed2d380292016 commit: e53444051018af3351cc26c4bf1ed2d380292016 branch: main author: Daniel Giger <danielg3432 at gmail.com> committer: benjaminp <benjamin at locrian.net> date: 2022-08-26T22:06:26-07:00 summary: fix threading.Event.isSet() docstring (#96297) fixes gh-96296 files: M Lib/threading.py diff --git a/Lib/threading.py b/Lib/threading.py index f28597c99305..7237a149ecca 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -589,7 +589,7 @@ def is_set(self): def isSet(self): """Return true if and only if the internal flag is true. - This method is deprecated, use notify_all() instead. + This method is deprecated, use is_set() instead. """ import warnings From webhook-mailer at python.org Sat Aug 27 01:30:46 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 27 Aug 2022 05:30:46 -0000 Subject: [Python-checkins] fix threading.Event.isSet() docstring (GH-96297) Message-ID: <mailman.848.1661578246.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c216af8e8e202c72ab5ad0ac65475f0e1ca37764 commit: c216af8e8e202c72ab5ad0ac65475f0e1ca37764 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-26T22:30:41-07:00 summary: fix threading.Event.isSet() docstring (GH-96297) fixes gh-96296 (cherry picked from commit e53444051018af3351cc26c4bf1ed2d380292016) Co-authored-by: Daniel Giger <danielg3432 at gmail.com> files: M Lib/threading.py diff --git a/Lib/threading.py b/Lib/threading.py index 668126523d50..62f49c05cdc1 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -557,7 +557,7 @@ def is_set(self): def isSet(self): """Return true if and only if the internal flag is true. - This method is deprecated, use notify_all() instead. + This method is deprecated, use is_set() instead. """ import warnings From webhook-mailer at python.org Sat Aug 27 01:32:07 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 27 Aug 2022 05:32:07 -0000 Subject: [Python-checkins] fix threading.Event.isSet() docstring (GH-96297) Message-ID: <mailman.849.1661578328.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0bc0b732eed658ee259061f126f451e31e402b5c commit: 0bc0b732eed658ee259061f126f451e31e402b5c branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-26T22:32:03-07:00 summary: fix threading.Event.isSet() docstring (GH-96297) fixes gh-96296 (cherry picked from commit e53444051018af3351cc26c4bf1ed2d380292016) Co-authored-by: Daniel Giger <danielg3432 at gmail.com> files: M Lib/threading.py diff --git a/Lib/threading.py b/Lib/threading.py index 8e7cdf6f620d..4f72938551d4 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -572,7 +572,7 @@ def is_set(self): def isSet(self): """Return true if and only if the internal flag is true. - This method is deprecated, use notify_all() instead. + This method is deprecated, use is_set() instead. """ import warnings From webhook-mailer at python.org Sat Aug 27 01:33:37 2022 From: webhook-mailer at python.org (benjaminp) Date: Sat, 27 Aug 2022 05:33:37 -0000 Subject: [Python-checkins] fixes gh-96292: Fix Trivial Typo in cpython/Modules/atexitmodule.c (#96327) Message-ID: <mailman.850.1661578418.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0ace820bec8892d621a4aadc1feb6c56e25560bf commit: 0ace820bec8892d621a4aadc1feb6c56e25560bf branch: main author: Ansab Gillani <56605828+ansabgillani at users.noreply.github.com> committer: benjaminp <benjamin at locrian.net> date: 2022-08-26T22:33:29-07:00 summary: fixes gh-96292: Fix Trivial Typo in cpython/Modules/atexitmodule.c (#96327) files: M Modules/atexitmodule.c diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index e806730aa9cf..a1c511e09d70 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -185,7 +185,7 @@ PyDoc_STRVAR(atexit_run_exitfuncs__doc__, \n\ Run all registered exit functions.\n\ \n\ -If a callaback raises an exception, it is logged with sys.unraisablehook."); +If a callback raises an exception, it is logged with sys.unraisablehook."); static PyObject * atexit_run_exitfuncs(PyObject *module, PyObject *unused) From webhook-mailer at python.org Sat Aug 27 01:53:56 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 27 Aug 2022 05:53:56 -0000 Subject: [Python-checkins] fixes gh-96292: Fix Trivial Typo in cpython/Modules/atexitmodule.c (GH-96327) Message-ID: <mailman.851.1661579638.3313.python-checkins@python.org> https://github.com/python/cpython/commit/5d82cefdc4f04e87fc5ed9b5de2415de79e89d89 commit: 5d82cefdc4f04e87fc5ed9b5de2415de79e89d89 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-26T22:53:47-07:00 summary: fixes gh-96292: Fix Trivial Typo in cpython/Modules/atexitmodule.c (GH-96327) (cherry picked from commit 0ace820bec8892d621a4aadc1feb6c56e25560bf) Co-authored-by: Ansab Gillani <56605828+ansabgillani at users.noreply.github.com> files: M Modules/atexitmodule.c diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index 95c653cf4782..7df2db5288c7 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -185,7 +185,7 @@ PyDoc_STRVAR(atexit_run_exitfuncs__doc__, \n\ Run all registered exit functions.\n\ \n\ -If a callaback raises an exception, it is logged with sys.unraisablehook."); +If a callback raises an exception, it is logged with sys.unraisablehook."); static PyObject * atexit_run_exitfuncs(PyObject *module, PyObject *unused) From webhook-mailer at python.org Sat Aug 27 01:59:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 27 Aug 2022 05:59:31 -0000 Subject: [Python-checkins] fixes gh-96292: Fix Trivial Typo in cpython/Modules/atexitmodule.c (GH-96327) Message-ID: <mailman.852.1661579972.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6bd95f968cfbe0fd7fbcec27e047876f404259ed commit: 6bd95f968cfbe0fd7fbcec27e047876f404259ed branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-26T22:59:21-07:00 summary: fixes gh-96292: Fix Trivial Typo in cpython/Modules/atexitmodule.c (GH-96327) (cherry picked from commit 0ace820bec8892d621a4aadc1feb6c56e25560bf) Co-authored-by: Ansab Gillani <56605828+ansabgillani at users.noreply.github.com> files: M Modules/atexitmodule.c diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index e806730aa9cf..a1c511e09d70 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -185,7 +185,7 @@ PyDoc_STRVAR(atexit_run_exitfuncs__doc__, \n\ Run all registered exit functions.\n\ \n\ -If a callaback raises an exception, it is logged with sys.unraisablehook."); +If a callback raises an exception, it is logged with sys.unraisablehook."); static PyObject * atexit_run_exitfuncs(PyObject *module, PyObject *unused) From webhook-mailer at python.org Sat Aug 27 07:13:59 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 11:13:59 -0000 Subject: [Python-checkins] =?utf-8?q?gh-92007=3A_Handle_elevation_errors_?= =?utf-8?q?in_NTEventLogHandler_more_grace=E2=80=A6_=28GH-96322=29?= Message-ID: <mailman.853.1661598840.3313.python-checkins@python.org> https://github.com/python/cpython/commit/013e659e495796df77aae4d33b67995f9793f454 commit: 013e659e495796df77aae4d33b67995f9793f454 branch: main author: Vinay Sajip <vinay_sajip at yahoo.co.uk> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T12:13:19+01:00 summary: gh-92007: Handle elevation errors in NTEventLogHandler more grace? (GH-96322) files: M Lib/logging/handlers.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 3f97862cc37a..b4c5c1304b97 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1111,7 +1111,16 @@ def __init__(self, appname, dllname=None, logtype="Application"): dllname = os.path.join(dllname[0], r'win32service.pyd') self.dllname = dllname self.logtype = logtype - self._welu.AddSourceToRegistry(appname, dllname, logtype) + # Administrative privileges are required to add a source to the registry. + # This may not be available for a user that just wants to add to an + # existing source - handle this specific case. + try: + self._welu.AddSourceToRegistry(appname, dllname, logtype) + except Exception as e: + # This will probably be a pywintypes.error. Only raise if it's not + # an "access denied" error, else let it pass + if getattr(e, 'winerror', None) != 5: # not access denied + raise self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE self.typemap = { logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, From webhook-mailer at python.org Sat Aug 27 07:15:28 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 11:15:28 -0000 Subject: [Python-checkins] [3.10] gh-77116: Add SMTP buffering example to logging cookbook. (GH-96324) (GH-96325) Message-ID: <mailman.854.1661598929.3313.python-checkins@python.org> https://github.com/python/cpython/commit/91b6ca4e76f4d753780469054877e9eea7cf5e81 commit: 91b6ca4e76f4d753780469054877e9eea7cf5e81 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T12:15:23+01:00 summary: [3.10] gh-77116: Add SMTP buffering example to logging cookbook. (GH-96324) (GH-96325) files: M Doc/howto/logging-cookbook.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 321c4bc510ad..16df3b730ac8 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2678,6 +2678,88 @@ You can of course use the conventional means of decoration:: ... +.. _buffered-smtp: + +Sending logging messages to email, with buffering +------------------------------------------------- + +To illustrate how you can send log messages via email, so that a set number of +messages are sent per email, you can subclass +:class:`~logging.handlers.BufferingHandler`. In the following example, which you can +adapt to suit your specific needs, a simple test harness is provided which allows you +to run the script with command line arguments specifying what you typically need to +send things via SMTP. (Run the downloaded script with the ``-h`` argument to see the +required and optional arguments.) + +.. code-block:: python + + import logging + import logging.handlers + import smtplib + + class BufferingSMTPHandler(logging.handlers.BufferingHandler): + def __init__(self, mailhost, port, username, password, fromaddr, toaddrs, + subject, capacity): + logging.handlers.BufferingHandler.__init__(self, capacity) + self.mailhost = mailhost + self.mailport = port + self.username = username + self.password = password + self.fromaddr = fromaddr + if isinstance(toaddrs, str): + toaddrs = [toaddrs] + self.toaddrs = toaddrs + self.subject = subject + self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s")) + + def flush(self): + if len(self.buffer) > 0: + try: + smtp = smtplib.SMTP(self.mailhost, self.mailport) + smtp.starttls() + smtp.login(self.username, self.password) + msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject) + for record in self.buffer: + s = self.format(record) + msg = msg + s + "\r\n" + smtp.sendmail(self.fromaddr, self.toaddrs, msg) + smtp.quit() + except Exception: + if logging.raiseExceptions: + raise + self.buffer = [] + + if __name__ == '__main__': + import argparse + + ap = argparse.ArgumentParser() + aa = ap.add_argument + aa('host', metavar='HOST', help='SMTP server') + aa('--port', '-p', type=int, default=587, help='SMTP port') + aa('user', metavar='USER', help='SMTP username') + aa('password', metavar='PASSWORD', help='SMTP password') + aa('to', metavar='TO', help='Addressee for emails') + aa('sender', metavar='SENDER', help='Sender email address') + aa('--subject', '-s', + default='Test Logging email from Python logging module (buffering)', + help='Subject of email') + options = ap.parse_args() + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + h = BufferingSMTPHandler(options.host, options.port, options.user, + options.password, options.sender, + options.to, options.subject, 10) + logger.addHandler(h) + for i in range(102): + logger.info("Info index = %d", i) + h.flush() + h.close() + +If you run this script and your SMTP server is correctly set up, you should find that +it sends eleven emails to the addressee you specify. The first ten emails will each +have ten log messages, and the eleventh will have two messages. That makes up 102 +messages as specified in the script. + .. _utc-formatting: Formatting times using UTC (GMT) via configuration From webhook-mailer at python.org Sat Aug 27 07:15:58 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 11:15:58 -0000 Subject: [Python-checkins] [3.11] gh-77116: Add SMTP buffering example to logging cookbook. (GH-96324) (GH-96326) Message-ID: <mailman.855.1661598959.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b76c43a55a7afaf8ba4ab929cf087133916e57d3 commit: b76c43a55a7afaf8ba4ab929cf087133916e57d3 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T12:15:53+01:00 summary: [3.11] gh-77116: Add SMTP buffering example to logging cookbook. (GH-96324) (GH-96326) files: M Doc/howto/logging-cookbook.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 321c4bc510ad..16df3b730ac8 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2678,6 +2678,88 @@ You can of course use the conventional means of decoration:: ... +.. _buffered-smtp: + +Sending logging messages to email, with buffering +------------------------------------------------- + +To illustrate how you can send log messages via email, so that a set number of +messages are sent per email, you can subclass +:class:`~logging.handlers.BufferingHandler`. In the following example, which you can +adapt to suit your specific needs, a simple test harness is provided which allows you +to run the script with command line arguments specifying what you typically need to +send things via SMTP. (Run the downloaded script with the ``-h`` argument to see the +required and optional arguments.) + +.. code-block:: python + + import logging + import logging.handlers + import smtplib + + class BufferingSMTPHandler(logging.handlers.BufferingHandler): + def __init__(self, mailhost, port, username, password, fromaddr, toaddrs, + subject, capacity): + logging.handlers.BufferingHandler.__init__(self, capacity) + self.mailhost = mailhost + self.mailport = port + self.username = username + self.password = password + self.fromaddr = fromaddr + if isinstance(toaddrs, str): + toaddrs = [toaddrs] + self.toaddrs = toaddrs + self.subject = subject + self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s")) + + def flush(self): + if len(self.buffer) > 0: + try: + smtp = smtplib.SMTP(self.mailhost, self.mailport) + smtp.starttls() + smtp.login(self.username, self.password) + msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject) + for record in self.buffer: + s = self.format(record) + msg = msg + s + "\r\n" + smtp.sendmail(self.fromaddr, self.toaddrs, msg) + smtp.quit() + except Exception: + if logging.raiseExceptions: + raise + self.buffer = [] + + if __name__ == '__main__': + import argparse + + ap = argparse.ArgumentParser() + aa = ap.add_argument + aa('host', metavar='HOST', help='SMTP server') + aa('--port', '-p', type=int, default=587, help='SMTP port') + aa('user', metavar='USER', help='SMTP username') + aa('password', metavar='PASSWORD', help='SMTP password') + aa('to', metavar='TO', help='Addressee for emails') + aa('sender', metavar='SENDER', help='Sender email address') + aa('--subject', '-s', + default='Test Logging email from Python logging module (buffering)', + help='Subject of email') + options = ap.parse_args() + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + h = BufferingSMTPHandler(options.host, options.port, options.user, + options.password, options.sender, + options.to, options.subject, 10) + logger.addHandler(h) + for i in range(102): + logger.info("Info index = %d", i) + h.flush() + h.close() + +If you run this script and your SMTP server is correctly set up, you should find that +it sends eleven emails to the addressee you specify. The first ten emails will each +have ten log messages, and the eleventh will have two messages. That makes up 102 +messages as specified in the script. + .. _utc-formatting: Formatting times using UTC (GMT) via configuration From webhook-mailer at python.org Sat Aug 27 07:38:03 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 11:38:03 -0000 Subject: [Python-checkins] =?utf-8?q?=5B3=2E10=5D_gh-92007=3A_Handle_elev?= =?utf-8?q?ation_errors_in_NTEventLogHandler_more_grace=E2=80=A6_=28GH-963?= =?utf-8?q?22=29_=28GH-96338=29?= Message-ID: <mailman.856.1661600284.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a2cf98449c8e176e8534eb961043f6eac918ce2b commit: a2cf98449c8e176e8534eb961043f6eac918ce2b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T12:37:55+01:00 summary: [3.10] gh-92007: Handle elevation errors in NTEventLogHandler more grace? (GH-96322) (GH-96338) files: M Lib/logging/handlers.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 32c04202c5aa..f0fdedae5ebb 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1098,7 +1098,16 @@ def __init__(self, appname, dllname=None, logtype="Application"): dllname = os.path.join(dllname[0], r'win32service.pyd') self.dllname = dllname self.logtype = logtype - self._welu.AddSourceToRegistry(appname, dllname, logtype) + # Administrative privileges are required to add a source to the registry. + # This may not be available for a user that just wants to add to an + # existing source - handle this specific case. + try: + self._welu.AddSourceToRegistry(appname, dllname, logtype) + except Exception as e: + # This will probably be a pywintypes.error. Only raise if it's not + # an "access denied" error, else let it pass + if getattr(e, 'winerror', None) != 5: # not access denied + raise self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE self.typemap = { logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, From webhook-mailer at python.org Sat Aug 27 08:08:24 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 12:08:24 -0000 Subject: [Python-checkins] =?utf-8?q?=5B3=2E11=5D_gh-92007=3A_Handle_elev?= =?utf-8?q?ation_errors_in_NTEventLogHandler_more_grace=E2=80=A6_=28GH-963?= =?utf-8?q?22=29_=28GH-96337=29?= Message-ID: <mailman.857.1661602105.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b7ea2b8358b2f50e1aad502bab29783bb40ed4d9 commit: b7ea2b8358b2f50e1aad502bab29783bb40ed4d9 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T13:08:14+01:00 summary: [3.11] gh-92007: Handle elevation errors in NTEventLogHandler more grace? (GH-96322) (GH-96337) files: M Lib/logging/handlers.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 2bcab657ba4e..c6853e0513e0 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1111,7 +1111,16 @@ def __init__(self, appname, dllname=None, logtype="Application"): dllname = os.path.join(dllname[0], r'win32service.pyd') self.dllname = dllname self.logtype = logtype - self._welu.AddSourceToRegistry(appname, dllname, logtype) + # Administrative privileges are required to add a source to the registry. + # This may not be available for a user that just wants to add to an + # existing source - handle this specific case. + try: + self._welu.AddSourceToRegistry(appname, dllname, logtype) + except Exception as e: + # This will probably be a pywintypes.error. Only raise if it's not + # an "access denied" error, else let it pass + if getattr(e, 'winerror', None) != 5: # not access denied + raise self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE self.typemap = { logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, From webhook-mailer at python.org Sat Aug 27 08:33:33 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 12:33:33 -0000 Subject: [Python-checkins] gh-89047: Fix msecs computation so you never end up with 1000 msecs. (GH-96340) Message-ID: <mailman.858.1661603614.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6fbd889d6e937ad255f98b5495b78a06d05640d5 commit: 6fbd889d6e937ad255f98b5495b78a06d05640d5 branch: main author: Vinay Sajip <vinay_sajip at yahoo.co.uk> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T13:33:24+01:00 summary: gh-89047: Fix msecs computation so you never end up with 1000 msecs. (GH-96340) files: M Lib/logging/__init__.py M Lib/test/test_logging.py diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index afb5234a0772..c3208a21f499 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -340,7 +340,7 @@ def __init__(self, name, level, pathname, lineno, self.lineno = lineno self.funcName = func self.created = ct - self.msecs = (ct - int(ct)) * 1000 + self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 99ea2f687551..a67ed07f12c8 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4261,6 +4261,14 @@ class NoMsecFormatter(logging.Formatter): f.converter = time.gmtime self.assertEqual(f.formatTime(r), '21/04/1993 08:03:00') + def test_issue_89047(self): + f = logging.Formatter(fmt='{asctime}.{msecs:03.0f} {message}', style='{', datefmt="%Y-%m-%d %H:%M:%S") + for i in range(2500): + time.sleep(0.0004) + r = logging.makeLogRecord({'msg': 'Message %d' % (i + 1)}) + s = f.format(r) + self.assertNotIn('.1000', s) + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records): From webhook-mailer at python.org Sat Aug 27 09:26:53 2022 From: webhook-mailer at python.org (pablogsal) Date: Sat, 27 Aug 2022 13:26:53 -0000 Subject: [Python-checkins] Docs: Fix count of bullets in asyncio-task.rst (GH-96307) (#96330) Message-ID: <mailman.859.1661606814.3313.python-checkins@python.org> https://github.com/python/cpython/commit/698df306a955fe33670d770107580418e41dd771 commit: 698df306a955fe33670d770107580418e41dd771 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-27T14:26:42+01:00 summary: Docs: Fix count of bullets in asyncio-task.rst (GH-96307) (#96330) (cherry picked from commit 35e4da25d4c86c891a99cae4ddbb9edb7d911e9f) Co-authored-by: zhanpon <pon.zhan at gmail.com> Co-authored-by: zhanpon <pon.zhan at gmail.com> files: M Doc/library/asyncio-task.rst diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index a6b638c11240..ffbf421bae5e 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -40,7 +40,7 @@ be executed:: >>> main() <coroutine object main at 0x1053bb7c8> -To actually run a coroutine, asyncio provides three main mechanisms: +To actually run a coroutine, asyncio provides the following mechanisms: * The :func:`asyncio.run` function to run the top-level entry point "main()" function (see the above example.) From webhook-mailer at python.org Sat Aug 27 10:10:10 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 14:10:10 -0000 Subject: [Python-checkins] [3.11] gh-89047: Fix msecs computation so you never end up with 1000 msecs. (GH-96340) (GH-96341) Message-ID: <mailman.860.1661609411.3313.python-checkins@python.org> https://github.com/python/cpython/commit/103f26f28238b80693a391746bd4509a7a0a227f commit: 103f26f28238b80693a391746bd4509a7a0a227f branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T15:09:54+01:00 summary: [3.11] gh-89047: Fix msecs computation so you never end up with 1000 msecs. (GH-96340) (GH-96341) files: M Lib/logging/__init__.py M Lib/test/test_logging.py diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 79e4b7d09bfa..458c5fb7d0dc 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -334,7 +334,7 @@ def __init__(self, name, level, pathname, lineno, self.lineno = lineno self.funcName = func self.created = ct - self.msecs = (ct - int(ct)) * 1000 + self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 71926a5432e2..5349874c63c5 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4088,6 +4088,14 @@ class NoMsecFormatter(logging.Formatter): f.converter = time.gmtime self.assertEqual(f.formatTime(r), '21/04/1993 08:03:00') + def test_issue_89047(self): + f = logging.Formatter(fmt='{asctime}.{msecs:03.0f} {message}', style='{', datefmt="%Y-%m-%d %H:%M:%S") + for i in range(2500): + time.sleep(0.0004) + r = logging.makeLogRecord({'msg': 'Message %d' % (i + 1)}) + s = f.format(r) + self.assertNotIn('.1000', s) + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records): From webhook-mailer at python.org Sat Aug 27 10:10:22 2022 From: webhook-mailer at python.org (vsajip) Date: Sat, 27 Aug 2022 14:10:22 -0000 Subject: [Python-checkins] [3.10] gh-89047: Fix msecs computation so you never end up with 1000 msecs. (GH-96340) (GH-96342) Message-ID: <mailman.861.1661609423.3313.python-checkins@python.org> https://github.com/python/cpython/commit/c0a9859afb522d555a9b9851be48be56327d252d commit: c0a9859afb522d555a9b9851be48be56327d252d branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-27T15:10:17+01:00 summary: [3.10] gh-89047: Fix msecs computation so you never end up with 1000 msecs. (GH-96340) (GH-96342) files: M Lib/logging/__init__.py M Lib/test/test_logging.py diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 19bd2bc20b25..09810bdf0d0b 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -325,7 +325,7 @@ def __init__(self, name, level, pathname, lineno, self.lineno = lineno self.funcName = func self.created = ct - self.msecs = (ct - int(ct)) * 1000 + self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index af68f2582040..920bbeb66006 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4020,6 +4020,14 @@ class NoMsecFormatter(logging.Formatter): f.converter = time.gmtime self.assertEqual(f.formatTime(r), '21/04/1993 08:03:00') + def test_issue_89047(self): + f = logging.Formatter(fmt='{asctime}.{msecs:03.0f} {message}', style='{', datefmt="%Y-%m-%d %H:%M:%S") + for i in range(2500): + time.sleep(0.0004) + r = logging.makeLogRecord({'msg': 'Message %d' % (i + 1)}) + s = f.format(r) + self.assertNotIn('.1000', s) + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records): From webhook-mailer at python.org Sat Aug 27 15:32:21 2022 From: webhook-mailer at python.org (gvanrossum) Date: Sat, 27 Aug 2022 19:32:21 -0000 Subject: [Python-checkins] gh-90467: StreamReaderProtocol - add strong reference to created task (#96323) Message-ID: <mailman.862.1661628742.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e860e521ec0d84e175269aeb15cf24bd6053ad17 commit: e860e521ec0d84e175269aeb15cf24bd6053ad17 branch: main author: Kirill <iam at python273.pw> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-27T12:32:01-07:00 summary: gh-90467: StreamReaderProtocol - add strong reference to created task (#96323) files: A Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst M Lib/asyncio/streams.py M Misc/ACKS diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 9a169035de88..614b2cda6068 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -205,6 +205,7 @@ def __init__(self, stream_reader, client_connected_cb=None, loop=None): self._strong_reader = stream_reader self._reject_connection = False self._stream_writer = None + self._task = None self._transport = None self._client_connected_cb = client_connected_cb self._over_ssl = False @@ -247,7 +248,7 @@ def connection_made(self, transport): res = self._client_connected_cb(reader, self._stream_writer) if coroutines.iscoroutine(res): - self._loop.create_task(res) + self._task = self._loop.create_task(res) self._strong_reader = None def connection_lost(self, exc): @@ -265,6 +266,7 @@ def connection_lost(self, exc): super().connection_lost(exc) self._stream_reader_wr = None self._stream_writer = None + self._task = None self._transport = None def data_received(self, data): diff --git a/Misc/ACKS b/Misc/ACKS index daa01c1a0f1d..0edea9219d05 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1442,6 +1442,7 @@ Ram Rachum Jeffrey Rackauckas J?r?me Radix Burton Radons +Kirill (python273) R. Abhilash Raj Shorya Raj Ajith Ramachandran @@ -1987,6 +1988,7 @@ Gordon Worley Darren Worrall Thomas Wouters Daniel Wozniak +Simon Wrede Marcin Niemira Wei Wu Heiko Wundram diff --git a/Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst b/Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst new file mode 100644 index 000000000000..282c0e76a8c8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst @@ -0,0 +1,2 @@ +Fix :class:`asyncio.streams.StreamReaderProtocol` to keep a strong reference +to the created task, so that it's not garbage collected From webhook-mailer at python.org Sun Aug 28 01:35:50 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sun, 28 Aug 2022 05:35:50 -0000 Subject: [Python-checkins] gh-96021: Explicitly tear down the IsolatedAsyncioTestCase loop in tests (GH-96135) (GH-96235) Message-ID: <mailman.863.1661664951.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9b070d361da2d1458ba005e2451b26d698c1fbf7 commit: 9b070d361da2d1458ba005e2451b26d698c1fbf7 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-28T08:35:39+03:00 summary: gh-96021: Explicitly tear down the IsolatedAsyncioTestCase loop in tests (GH-96135) (GH-96235) Tests for IsolatedAsyncioTestCase.debug() rely on the runner be closed in __del__. It makes tests depending on the GC an unreliable on other implementations. It is better to tear down the loop explicitly even if currently there is no a public API for this. (cherry picked from commit 4de06e3cc0a58d73934f9a2759ad9cd2f6b031b0) Co-authored-by: Serhiy Storchaka <storchaka at gmail.com> files: M Lib/unittest/test/test_async_case.py diff --git a/Lib/unittest/test/test_async_case.py b/Lib/unittest/test/test_async_case.py index e46b99fd0026..b97ad939a0ea 100644 --- a/Lib/unittest/test/test_async_case.py +++ b/Lib/unittest/test/test_async_case.py @@ -14,10 +14,10 @@ def tearDownModule(): class TestAsyncCase(unittest.TestCase): maxDiff = None - def tearDown(self): + def setUp(self): # Ensure that IsolatedAsyncioTestCase instances are destroyed before # starting a new event loop - support.gc_collect() + self.addCleanup(support.gc_collect) def test_full_cycle(self): class Test(unittest.IsolatedAsyncioTestCase): @@ -108,6 +108,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioLoop) try: test.debug() except MyException: @@ -143,6 +144,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioLoop) try: test.debug() except MyException: @@ -178,6 +180,7 @@ async def on_cleanup(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioLoop) try: test.debug() except MyException: @@ -219,6 +222,7 @@ async def on_cleanup2(self): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioLoop) try: test.debug() except MyException: @@ -331,6 +335,7 @@ async def cleanup(self, fut): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioLoop) try: test.debug() except MyException: From webhook-mailer at python.org Sun Aug 28 09:17:06 2022 From: webhook-mailer at python.org (ezio-melotti) Date: Sun, 28 Aug 2022 13:17:06 -0000 Subject: [Python-checkins] [3.10] gh-95994: Clarify escaped newlines. (GH-96066) (#96360) Message-ID: <mailman.864.1661692627.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f51c232ec812d5413dc3dde5580ad298abb7e551 commit: f51c232ec812d5413dc3dde5580ad298abb7e551 branch: 3.10 author: Ezio Melotti <ezio.melotti at gmail.com> committer: ezio-melotti <ezio.melotti at gmail.com> date: 2022-08-28T15:17:01+02:00 summary: [3.10] gh-95994: Clarify escaped newlines. (GH-96066) (#96360) * gh-95994: clarify escaped newlines. * Rephrase ambiguous sentence. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> * Use `<newline>` in escape sequences table. Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach at Gerlach.CAM>. (cherry picked from commit c3d591fd0699605c8253beda2372114052a7bdba) Co-authored-by: Ezio Melotti <ezio.melotti at gmail.com> files: M Doc/reference/lexical_analysis.rst diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 1a2cb411427a..e50a0368fa3e 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -552,7 +552,7 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\newline`` | Backslash and newline ignored | | +| ``\``\ <newline>| Backslash and newline ignored | \(1) | +-----------------+---------------------------------+-------+ | ``\\`` | Backslash (``\``) | | +-----------------+---------------------------------+-------+ @@ -574,10 +574,10 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | ``\v`` | ASCII Vertical Tab (VT) | | +-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (1,3) | +| ``\ooo`` | Character with octal value | (2,4) | | | *ooo* | | +-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (2,3) | +| ``\xhh`` | Character with hex value *hh* | (3,4) | +-----------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: @@ -585,37 +585,47 @@ Escape sequences only recognized in string literals are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(4) | +| ``\N{name}`` | Character named *name* in the | \(5) | | | Unicode database | | +-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(5) | +| ``\uxxxx`` | Character with 16-bit hex value | \(6) | | | *xxxx* | | +-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(6) | +| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | | | *xxxxxxxx* | | +-----------------+---------------------------------+-------+ Notes: (1) - As in Standard C, up to three octal digits are accepted. + A backslash can be added at the end of a line to ignore the newline:: + + >>> 'This string will not include \ + ... backslashes or newline characters.' + 'This string will not include backslashes or newline characters.' + + The same result can be achieved using :ref:`triple-quoted strings <strings>`, + or parentheses and :ref:`string literal concatenation <string-concatenation>`. (2) - Unlike in Standard C, exactly two hex digits are required. + As in Standard C, up to three octal digits are accepted. (3) + Unlike in Standard C, exactly two hex digits are required. + +(4) In a bytes literal, hexadecimal and octal escapes denote the byte with the given value. In a string literal, these escapes denote a Unicode character with the given value. -(4) +(5) .. versionchanged:: 3.3 Support for name aliases [#]_ has been added. -(5) +(6) Exactly four hex digits are required. -(6) +(7) Any Unicode character can be encoded this way. Exactly eight hex digits are required. From webhook-mailer at python.org Sun Aug 28 17:27:56 2022 From: webhook-mailer at python.org (gvanrossum) Date: Sun, 28 Aug 2022 21:27:56 -0000 Subject: [Python-checkins] gh-69142: add %:z strftime format code (gh-95983) Message-ID: <mailman.865.1661722077.3313.python-checkins@python.org> https://github.com/python/cpython/commit/023c51d9d8e2fd91069eea2bf12e373f1c71e9d2 commit: 023c51d9d8e2fd91069eea2bf12e373f1c71e9d2 branch: main author: TW <tw at waldmann-edv.de> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-28T14:27:42-07:00 summary: gh-69142: add %:z strftime format code (gh-95983) datetime.isoformat generates the tzoffset with colons, but there was no format code to make strftime output the same format. for simplicity and consistency the %:z formatting behaves mostly as %z, with the exception of adding colons. this includes the dynamic behaviour of adding seconds and microseconds only when needed (when not 0). this fixes the still open "generate" part of this issue: https://github.com/python/cpython/issues/69142 Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-08-14-18-59-54.gh-issue-69142.6is5Pq.rst M Doc/library/datetime.rst M Lib/datetime.py M Lib/test/datetimetester.py M Modules/_datetimemodule.c diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 0f042374b64..c3a66a4674b 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2443,6 +2443,11 @@ convenience. These parameters all correspond to ISO 8601 date values. | | Week 01 is the week containing | | | | | Jan 4. | | | +-----------+--------------------------------+------------------------+-------+ +| ``%:z`` | UTC offset in the form | (empty), +00:00, | \(6) | +| | ``?HH:MM[:SS[.ffffff]]`` | -04:00, +10:30, | | +| | (empty string if the object is | +06:34:15, | | +| | naive). | -03:07:12.345216 | | ++-----------+--------------------------------+------------------------+-------+ These may not be available on all platforms when used with the :meth:`strftime` method. The ISO 8601 year and ISO 8601 week directives are not interchangeable @@ -2458,6 +2463,9 @@ differences between platforms in handling of unsupported format specifiers. .. versionadded:: 3.6 ``%G``, ``%u`` and ``%V`` were added. +.. versionadded:: 3.12 + ``%:z`` was added. + Technical Detail ^^^^^^^^^^^^^^^^ @@ -2530,8 +2538,8 @@ Notes: available). (6) - For a naive object, the ``%z`` and ``%Z`` format codes are replaced by empty - strings. + For a naive object, the ``%z``, ``%:z`` and ``%Z`` format codes are replaced + by empty strings. For an aware object: @@ -2557,6 +2565,10 @@ Notes: For example, ``'+01:00:00'`` will be parsed as an offset of one hour. In addition, providing ``'Z'`` is identical to ``'+00:00'``. + ``%:z`` + Behaves exactly as ``%z``, but has a colon separator added between + hours, minutes and seconds. + ``%Z`` In :meth:`strftime`, ``%Z`` is replaced by an empty string if :meth:`tzname` returns ``None``; otherwise ``%Z`` is replaced by the diff --git a/Lib/datetime.py b/Lib/datetime.py index 00ded32cc3e..007114ae622 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -179,7 +179,7 @@ def _format_time(hh, mm, ss, us, timespec='auto'): else: return fmt.format(hh, mm, ss, us) -def _format_offset(off): +def _format_offset(off, sep=':'): s = '' if off is not None: if off.days < 0: @@ -189,9 +189,9 @@ def _format_offset(off): sign = "+" hh, mm = divmod(off, timedelta(hours=1)) mm, ss = divmod(mm, timedelta(minutes=1)) - s += "%s%02d:%02d" % (sign, hh, mm) + s += "%s%02d%s%02d" % (sign, hh, sep, mm) if ss or ss.microseconds: - s += ":%02d" % ss.seconds + s += "%s%02d" % (sep, ss.seconds) if ss.microseconds: s += '.%06d' % ss.microseconds @@ -202,9 +202,10 @@ def _wrap_strftime(object, format, timetuple): # Don't call utcoffset() or tzname() unless actually needed. freplace = None # the string to use for %f zreplace = None # the string to use for %z + colonzreplace = None # the string to use for %:z Zreplace = None # the string to use for %Z - # Scan format for %z and %Z escapes, replacing as needed. + # Scan format for %z, %:z and %Z escapes, replacing as needed. newformat = [] push = newformat.append i, n = 0, len(format) @@ -222,26 +223,28 @@ def _wrap_strftime(object, format, timetuple): newformat.append(freplace) elif ch == 'z': if zreplace is None: - zreplace = "" if hasattr(object, "utcoffset"): - offset = object.utcoffset() - if offset is not None: - sign = '+' - if offset.days < 0: - offset = -offset - sign = '-' - h, rest = divmod(offset, timedelta(hours=1)) - m, rest = divmod(rest, timedelta(minutes=1)) - s = rest.seconds - u = offset.microseconds - if u: - zreplace = '%c%02d%02d%02d.%06d' % (sign, h, m, s, u) - elif s: - zreplace = '%c%02d%02d%02d' % (sign, h, m, s) - else: - zreplace = '%c%02d%02d' % (sign, h, m) + zreplace = _format_offset(object.utcoffset(), sep="") + else: + zreplace = "" assert '%' not in zreplace newformat.append(zreplace) + elif ch == ':': + if i < n: + ch2 = format[i] + i += 1 + if ch2 == 'z': + if colonzreplace is None: + if hasattr(object, "utcoffset"): + colonzreplace = _format_offset(object.utcoffset(), sep=":") + else: + colonzreplace = "" + assert '%' not in colonzreplace + newformat.append(colonzreplace) + else: + push('%') + push(ch) + push(ch2) elif ch == 'Z': if Zreplace is None: Zreplace = "" diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 7e7f4f33d6e..bba96698e9e 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1463,8 +1463,8 @@ def test_strftime(self): # test that unicode input is allowed (issue 2782) self.assertEqual(t.strftime("%m"), "03") - # A naive object replaces %z and %Z w/ empty strings. - self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + # A naive object replaces %z, %:z and %Z w/ empty strings. + self.assertEqual(t.strftime("'%z' '%:z' '%Z'"), "'' '' ''") #make sure that invalid format specifiers are handled correctly #self.assertRaises(ValueError, t.strftime, "%e") @@ -1528,7 +1528,7 @@ def strftime(self, format_spec): for fmt in ["m:%m d:%d y:%y", "m:%m d:%d y:%y H:%H M:%M S:%S", - "%z %Z", + "%z %:z %Z", ]: self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) @@ -2134,7 +2134,7 @@ def strftime(self, format_spec): for fmt in ["m:%m d:%d y:%y", "m:%m d:%d y:%y H:%H M:%M S:%S", - "%z %Z", + "%z %:z %Z", ]: self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) @@ -2777,6 +2777,7 @@ def test_more_strftime(self): tz = timezone(-timedelta(hours=2, seconds=s, microseconds=us)) t = t.replace(tzinfo=tz) self.assertEqual(t.strftime("%z"), "-0200" + z) + self.assertEqual(t.strftime("%:z"), "-02:00:" + z) # bpo-34482: Check that surrogates don't cause a crash. try: @@ -3515,8 +3516,8 @@ def test_1653736(self): def test_strftime(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004") - # A naive object replaces %z and %Z with empty strings. - self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + # A naive object replaces %z, %:z and %Z with empty strings. + self.assertEqual(t.strftime("'%z' '%:z' '%Z'"), "'' '' ''") # bpo-34482: Check that surrogates don't cause a crash. try: @@ -3934,10 +3935,10 @@ def test_zones(self): self.assertEqual(repr(t4), d + "(0, 0, 0, 40)") self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)") - self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"), - "07:47:00 %Z=EST %z=-0500") - self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000") - self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100") + self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z %%:z=%:z"), + "07:47:00 %Z=EST %z=-0500 %:z=-05:00") + self.assertEqual(t2.strftime("%H:%M:%S %Z %z %:z"), "12:47:00 UTC +0000 +00:00") + self.assertEqual(t3.strftime("%H:%M:%S %Z %z %:z"), "13:47:00 MET +0100 +01:00") yuck = FixedOffset(-1439, "%z %Z %%z%%Z") t1 = time(23, 59, tzinfo=yuck) diff --git a/Misc/NEWS.d/next/Library/2022-08-14-18-59-54.gh-issue-69142.6is5Pq.rst b/Misc/NEWS.d/next/Library/2022-08-14-18-59-54.gh-issue-69142.6is5Pq.rst new file mode 100644 index 00000000000..0db8b3730cf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-14-18-59-54.gh-issue-69142.6is5Pq.rst @@ -0,0 +1 @@ +Add ``%:z`` strftime format code (generates tzoffset with colons as separator), see :ref:`strftime-strptime-behavior`. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index eca7c6b29d7..d86418af0dc 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1506,6 +1506,27 @@ format_utcoffset(char *buf, size_t buflen, const char *sep, return 0; } +static PyObject * +make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg) +{ + char buf[100]; + PyObject *tzinfo = get_tzinfo_member(object); + + if (tzinfo == Py_None || tzinfo == NULL) { + return PyBytes_FromStringAndSize(NULL, 0); + } + + assert(tzinfoarg != NULL); + if (format_utcoffset(buf, + sizeof(buf), + sep, + tzinfo, + tzinfoarg) < 0) + return NULL; + + return PyBytes_FromStringAndSize(buf, strlen(buf)); +} + static PyObject * make_Zreplacement(PyObject *object, PyObject *tzinfoarg) { @@ -1566,7 +1587,7 @@ make_freplacement(PyObject *object) /* I sure don't want to reproduce the strftime code from the time module, * so this imports the module and calls it. All the hair is due to - * giving special meanings to the %z, %Z and %f format codes via a + * giving special meanings to the %z, %:z, %Z and %f format codes via a * preprocessing step on the format string. * tzinfoarg is the argument to pass to the object's tzinfo method, if * needed. @@ -1578,6 +1599,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, PyObject *result = NULL; /* guilty until proved innocent */ PyObject *zreplacement = NULL; /* py string, replacement for %z */ + PyObject *colonzreplacement = NULL; /* py string, replacement for %:z */ PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ PyObject *freplacement = NULL; /* py string, replacement for %f */ @@ -1632,32 +1654,29 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, } /* A % has been seen and ch is the character after it. */ else if (ch == 'z') { + /* %z -> +HHMM */ if (zreplacement == NULL) { - /* format utcoffset */ - char buf[100]; - PyObject *tzinfo = get_tzinfo_member(object); - zreplacement = PyBytes_FromStringAndSize("", 0); - if (zreplacement == NULL) goto Done; - if (tzinfo != Py_None && tzinfo != NULL) { - assert(tzinfoarg != NULL); - if (format_utcoffset(buf, - sizeof(buf), - "", - tzinfo, - tzinfoarg) < 0) - goto Done; - Py_DECREF(zreplacement); - zreplacement = - PyBytes_FromStringAndSize(buf, - strlen(buf)); - if (zreplacement == NULL) - goto Done; - } + zreplacement = make_somezreplacement(object, "", tzinfoarg); + if (zreplacement == NULL) + goto Done; } assert(zreplacement != NULL); + assert(PyBytes_Check(zreplacement)); ptoappend = PyBytes_AS_STRING(zreplacement); ntoappend = PyBytes_GET_SIZE(zreplacement); } + else if (ch == ':' && *pin == 'z' && pin++) { + /* %:z -> +HH:MM */ + if (colonzreplacement == NULL) { + colonzreplacement = make_somezreplacement(object, ":", tzinfoarg); + if (colonzreplacement == NULL) + goto Done; + } + assert(colonzreplacement != NULL); + assert(PyBytes_Check(colonzreplacement)); + ptoappend = PyBytes_AS_STRING(colonzreplacement); + ntoappend = PyBytes_GET_SIZE(colonzreplacement); + } else if (ch == 'Z') { /* format tzname */ if (Zreplacement == NULL) { @@ -1686,7 +1705,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, ntoappend = PyBytes_GET_SIZE(freplacement); } else { - /* percent followed by neither z nor Z */ + /* percent followed by something else */ ptoappend = pin - 2; ntoappend = 2; } @@ -1733,6 +1752,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, Done: Py_XDECREF(freplacement); Py_XDECREF(zreplacement); + Py_XDECREF(colonzreplacement); Py_XDECREF(Zreplacement); Py_XDECREF(newfmt); return result; From webhook-mailer at python.org Sun Aug 28 18:48:59 2022 From: webhook-mailer at python.org (brandtbucher) Date: Sun, 28 Aug 2022 22:48:59 -0000 Subject: [Python-checkins] GH-96359: Fix docs that claim int(0|1) doesn't match False (GH-96361) Message-ID: <mailman.866.1661726941.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3d3a86ed40626471b2c9e7f1336b228eb0dd0879 commit: 3d3a86ed40626471b2c9e7f1336b228eb0dd0879 branch: main author: Jonathan Oberl?nder <github at l3vi.de> committer: brandtbucher <brandtbucher at gmail.com> date: 2022-08-28T15:48:51-07:00 summary: GH-96359: Fix docs that claim int(0|1) doesn't match False (GH-96361) files: M Doc/reference/compound_stmts.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 93c1720220f0..751c7c2dbcf2 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -1122,7 +1122,7 @@ subject value: These classes accept a single positional argument, and the pattern there is matched against the whole object rather than an attribute. For example ``int(0|1)`` matches - the value ``0``, but not the values ``0.0`` or ``False``. + the value ``0``, but not the value ``0.0``. In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens: From webhook-mailer at python.org Sun Aug 28 20:43:40 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Mon, 29 Aug 2022 00:43:40 -0000 Subject: [Python-checkins] gh-95950: Add a test for both `csv.Dialect` and `kwargs` (#95951) Message-ID: <mailman.867.1661733821.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1c01bd28a0ec7e46e570a07d970c590b1809f8f1 commit: 1c01bd28a0ec7e46e570a07d970c590b1809f8f1 branch: main author: Nikita Sobolev <mail at sobolevn.me> committer: JelleZijlstra <jelle.zijlstra at gmail.com> date: 2022-08-28T17:43:32-07:00 summary: gh-95950: Add a test for both `csv.Dialect` and `kwargs` (#95951) files: M Lib/test/test_csv.py diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 51ca1f2ab29..a2b00430c7d 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -448,6 +448,34 @@ def test_register_kwargs(self): self.assertEqual(csv.get_dialect(name).delimiter, ';') self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name))) + def test_register_kwargs_override(self): + class mydialect(csv.Dialect): + delimiter = "\t" + quotechar = '"' + doublequote = True + skipinitialspace = False + lineterminator = '\r\n' + quoting = csv.QUOTE_MINIMAL + + name = 'test_dialect' + csv.register_dialect(name, mydialect, + delimiter=';', + quotechar="'", + doublequote=False, + skipinitialspace=True, + lineterminator='\n', + quoting=csv.QUOTE_ALL) + self.addCleanup(csv.unregister_dialect, name) + + # Ensure that kwargs do override attributes of a dialect class: + dialect = csv.get_dialect(name) + self.assertEqual(dialect.delimiter, ';') + self.assertEqual(dialect.quotechar, "'") + self.assertEqual(dialect.doublequote, False) + self.assertEqual(dialect.skipinitialspace, True) + self.assertEqual(dialect.lineterminator, '\n') + self.assertEqual(dialect.quoting, csv.QUOTE_ALL) + def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): delimiter = "\t" From webhook-mailer at python.org Sun Aug 28 20:45:32 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Mon, 29 Aug 2022 00:45:32 -0000 Subject: [Python-checkins] gh-96357: Improve `typing.get_overloads` coverage (#96358) Message-ID: <mailman.868.1661733933.3313.python-checkins@python.org> https://github.com/python/cpython/commit/675e3470ccf3804a36a9cd451b813e9bd655aeb3 commit: 675e3470ccf3804a36a9cd451b813e9bd655aeb3 branch: main author: Nikita Sobolev <mail at sobolevn.me> committer: JelleZijlstra <jelle.zijlstra at gmail.com> date: 2022-08-28T17:45:24-07:00 summary: gh-96357: Improve `typing.get_overloads` coverage (#96358) files: M Lib/test/test_typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 3f4101485c6..ca7bd8e083c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4416,6 +4416,9 @@ def some_other_func(): pass other_overload = some_other_func def some_other_func(): pass self.assertEqual(list(get_overloads(some_other_func)), [other_overload]) + # Unrelated function still has no overloads: + def not_overloaded(): pass + self.assertEqual(list(get_overloads(not_overloaded)), []) # Make sure that after we clear all overloads, the registry is # completely empty. From webhook-mailer at python.org Sun Aug 28 21:11:15 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 29 Aug 2022 01:11:15 -0000 Subject: [Python-checkins] gh-95950: Add a test for both `csv.Dialect` and `kwargs` (GH-95951) Message-ID: <mailman.869.1661735477.3313.python-checkins@python.org> https://github.com/python/cpython/commit/60f704f1258d8c225ad0a9ba3f342b553064206a commit: 60f704f1258d8c225ad0a9ba3f342b553064206a branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-28T18:11:02-07:00 summary: gh-95950: Add a test for both `csv.Dialect` and `kwargs` (GH-95951) (cherry picked from commit 1c01bd28a0ec7e46e570a07d970c590b1809f8f1) Co-authored-by: Nikita Sobolev <mail at sobolevn.me> files: M Lib/test/test_csv.py diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 6e5dfc63d43..d94a6f24597 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -421,6 +421,34 @@ def test_register_kwargs(self): self.assertEqual(csv.get_dialect(name).delimiter, ';') self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name))) + def test_register_kwargs_override(self): + class mydialect(csv.Dialect): + delimiter = "\t" + quotechar = '"' + doublequote = True + skipinitialspace = False + lineterminator = '\r\n' + quoting = csv.QUOTE_MINIMAL + + name = 'test_dialect' + csv.register_dialect(name, mydialect, + delimiter=';', + quotechar="'", + doublequote=False, + skipinitialspace=True, + lineterminator='\n', + quoting=csv.QUOTE_ALL) + self.addCleanup(csv.unregister_dialect, name) + + # Ensure that kwargs do override attributes of a dialect class: + dialect = csv.get_dialect(name) + self.assertEqual(dialect.delimiter, ';') + self.assertEqual(dialect.quotechar, "'") + self.assertEqual(dialect.doublequote, False) + self.assertEqual(dialect.skipinitialspace, True) + self.assertEqual(dialect.lineterminator, '\n') + self.assertEqual(dialect.quoting, csv.QUOTE_ALL) + def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): delimiter = "\t" From webhook-mailer at python.org Mon Aug 29 00:42:06 2022 From: webhook-mailer at python.org (rhettinger) Date: Mon, 29 Aug 2022 04:42:06 -0000 Subject: [Python-checkins] Prepare private _rank() function to be made public. (#96372) Message-ID: <mailman.870.1661748127.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d8d55d13fc502ed79081e2c73d5d8cb034a8b577 commit: d8d55d13fc502ed79081e2c73d5d8cb034a8b577 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-28T23:41:58-05:00 summary: Prepare private _rank() function to be made public. (#96372) files: M Lib/statistics.py diff --git a/Lib/statistics.py b/Lib/statistics.py index a3f915c1302..b4676fed5e2 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -355,7 +355,8 @@ def _fail_neg(values, errmsg='negative value'): raise StatisticsError(errmsg) yield x -def _rank(data, /, *, key=None, reverse=False, ties='average') -> list[float]: + +def _rank(data, /, *, key=None, reverse=False, ties='average', start=1) -> list[float]: """Rank order a dataset. The lowest value has rank 1. Ties are averaged so that equal values receive the same rank: @@ -369,14 +370,22 @@ def _rank(data, /, *, key=None, reverse=False, ties='average') -> list[float]: >>> _rank([3.5, 5.0, 3.5, 2.0, 6.0, 1.0]) [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] - It is possible to rank the data in reverse order so that - the highest value has rank 1. Also, a key-function can - extract the field to be ranked: + It is possible to rank the data in reverse order so that the + highest value has rank 1. Also, a key-function can extract + the field to be ranked: >>> goals = [('eagles', 45), ('bears', 48), ('lions', 44)] >>> _rank(goals, key=itemgetter(1), reverse=True) [2.0, 1.0, 3.0] + Ranks are conventionally numbered starting from one; however, + setting *start* to zero allow the ranks to be used as array indices: + + >>> prize = ['Gold', 'Silver', 'Bronze', 'Certificate'] + >>> scores = [8.1, 7.3, 9.4, 8.3] + >>> [prize[int(i)] for i in _rank(scores, start=0, reverse=True)] + ['Bronze', 'Certificate', 'Gold', 'Silver'] + """ # If this function becomes public at some point, more thought # needs to be given to the signature. A list of ints is @@ -389,7 +398,7 @@ def _rank(data, /, *, key=None, reverse=False, ties='average') -> list[float]: if key is not None: data = map(key, data) val_pos = sorted(zip(data, count()), reverse=reverse) - i = 0 # To rank starting at 0 instead of 1, set i = -1. + i = start - 1 result = [0] * len(val_pos) for _, g in groupby(val_pos, key=itemgetter(0)): group = list(g) @@ -400,6 +409,7 @@ def _rank(data, /, *, key=None, reverse=False, ties='average') -> list[float]: i += size return result + def _integer_sqrt_of_frac_rto(n: int, m: int) -> int: """Square root of n/m, rounded to the nearest integer using round-to-odd.""" # Reference: https://www.lri.fr/~melquion/doc/05-imacs17_1-expose.pdf From webhook-mailer at python.org Mon Aug 29 01:01:49 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 29 Aug 2022 05:01:49 -0000 Subject: [Python-checkins] gh-96191: Update the configure file to use GitHub issue (gh-96211) Message-ID: <mailman.871.1661749310.3313.python-checkins@python.org> https://github.com/python/cpython/commit/af368a7db46594ca6bd7ed5d4d68bb39900dae0e commit: af368a7db46594ca6bd7ed5d4d68bb39900dae0e branch: main author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-29T14:01:37+09:00 summary: gh-96191: Update the configure file to use GitHub issue (gh-96211) files: M configure M configure.ac diff --git a/configure b/configure index ee2eabb13c0..fc7f7fadedb 100755 --- a/configure +++ b/configure @@ -2,7 +2,7 @@ # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for python 3.12. # -# Report bugs to <https://bugs.python.org/>. +# Report bugs to <https://github.com/python/cpython/issues/>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -267,10 +267,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf at gnu.org and -$0: https://bugs.python.org/ about your system, including -$0: any error possibly output before this message. Then -$0: install a modern shell, or manually run the script -$0: under such a shell if you do have one." +$0: https://github.com/python/cpython/issues/ about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -582,7 +582,7 @@ PACKAGE_NAME='python' PACKAGE_TARNAME='python' PACKAGE_VERSION='3.12' PACKAGE_STRING='python 3.12' -PACKAGE_BUGREPORT='https://bugs.python.org/' +PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/' PACKAGE_URL='' ac_unique_file="Include/object.h" @@ -1971,7 +1971,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to <https://bugs.python.org/>. +Report bugs to <https://github.com/python/cpython/issues/>. _ACEOF ac_status=$? fi @@ -2193,9 +2193,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## --------------------------------------- ## -## Report this to https://bugs.python.org/ ## -## --------------------------------------- ##" +( $as_echo "## -------------------------------------------------------- ## +## Report this to https://github.com/python/cpython/issues/ ## +## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac @@ -20845,7 +20845,7 @@ fi # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 $as_echo_n "checking for x87-style double rounding... " >&6; } if ${ac_cv_x87_double_rounding+:} false; then : @@ -28913,7 +28913,7 @@ $config_files Configuration headers: $config_headers -Report bugs to <https://bugs.python.org/>." +Report bugs to <https://github.com/python/cpython/issues/>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 diff --git a/configure.ac b/configure.ac index 02e5d674571..2b927cd961f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl *************************************************** dnl * Please run autoreconf -if to test your changes! * dnl *************************************************** dnl -dnl Python's configure script requires autoconf 2.69 and autoconf-archive. +dnl Python's configure.ac file requires autoconf 2.69 and autoconf-archive. dnl # Set VERSION so we only need to edit in one place (i.e., here) @@ -10,7 +10,7 @@ m4_define(PYTHON_VERSION, 3.12) AC_PREREQ([2.69]) -AC_INIT([python],[PYTHON_VERSION],[https://bugs.python.org/]) +AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/]) m4_ifdef( [AX_C_FLOAT_WORDS_BIGENDIAN], @@ -5582,7 +5582,7 @@ AS_VAR_IF([ac_cv_gcc_asm_for_mc68881], [yes], [ # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. AC_CACHE_CHECK([for x87-style double rounding], [ac_cv_x87_double_rounding], [ # $BASECFLAGS may affect the result ac_save_cc="$CC" @@ -6309,7 +6309,7 @@ dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap AC_MSG_CHECKING([curses module flags]) AS_VAR_IF([have_curses], [no], [ - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) ], [ AC_MSG_RESULT([$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)]) ]) @@ -6357,7 +6357,7 @@ PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') AC_MSG_CHECKING([panel flags]) AS_VAR_IF([have_panel], [no], [ - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) ], [ AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)]) ]) From webhook-mailer at python.org Mon Aug 29 02:50:32 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 29 Aug 2022 06:50:32 -0000 Subject: [Python-checkins] [3.11] gh-96191: Update the configure file to use GitHub issue (gh-96211) (gh-96375) Message-ID: <mailman.872.1661755833.3313.python-checkins@python.org> https://github.com/python/cpython/commit/915d12834f5c6f9e10ee50195b98c2a80830119c commit: 915d12834f5c6f9e10ee50195b98c2a80830119c branch: 3.11 author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-29T15:50:22+09:00 summary: [3.11] gh-96191: Update the configure file to use GitHub issue (gh-96211) (gh-96375) files: M configure M configure.ac diff --git a/configure b/configure index 91227f00bef..784f8d30609 100755 --- a/configure +++ b/configure @@ -2,7 +2,7 @@ # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for python 3.11. # -# Report bugs to <https://bugs.python.org/>. +# Report bugs to <https://github.com/python/cpython/issues/>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -267,10 +267,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf at gnu.org and -$0: https://bugs.python.org/ about your system, including -$0: any error possibly output before this message. Then -$0: install a modern shell, or manually run the script -$0: under such a shell if you do have one." +$0: https://github.com/python/cpython/issues/ about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -582,7 +582,7 @@ PACKAGE_NAME='python' PACKAGE_TARNAME='python' PACKAGE_VERSION='3.11' PACKAGE_STRING='python 3.11' -PACKAGE_BUGREPORT='https://bugs.python.org/' +PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/' PACKAGE_URL='' ac_unique_file="Include/object.h" @@ -1918,7 +1918,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to <https://bugs.python.org/>. +Report bugs to <https://github.com/python/cpython/issues/>. _ACEOF ac_status=$? fi @@ -2140,9 +2140,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## --------------------------------------- ## -## Report this to https://bugs.python.org/ ## -## --------------------------------------- ##" +( $as_echo "## -------------------------------------------------------- ## +## Report this to https://github.com/python/cpython/issues/ ## +## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac @@ -19835,7 +19835,7 @@ fi # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 $as_echo_n "checking for x87-style double rounding... " >&6; } if ${ac_cv_x87_double_rounding+:} false; then : @@ -26451,7 +26451,7 @@ $config_files Configuration headers: $config_headers -Report bugs to <https://bugs.python.org/>." +Report bugs to <https://github.com/python/cpython/issues/>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 diff --git a/configure.ac b/configure.ac index 77fb609b74d..ab5e1de6fab 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl *************************************************** dnl * Please run autoreconf -if to test your changes! * dnl *************************************************** dnl -dnl Python's configure script requires autoconf 2.69 and autoconf-archive. +dnl Python's configure.ac file requires autoconf 2.69 and autoconf-archive. dnl # Set VERSION so we only need to edit in one place (i.e., here) @@ -10,7 +10,7 @@ m4_define(PYTHON_VERSION, 3.11) AC_PREREQ([2.69]) -AC_INIT([python],[PYTHON_VERSION],[https://bugs.python.org/]) +AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/]) m4_ifdef( [AX_C_FLOAT_WORDS_BIGENDIAN], @@ -2066,7 +2066,7 @@ AS_CASE([$ac_sys_system], dnl build with WASM debug info if either Py_DEBUG is set or the target is dnl node-debug or browser-debug. AS_VAR_IF([Py_DEBUG], [yes], [wasm_debug=yes], [wasm_debug=no]) - + dnl Start with 20 MB and allow to grow AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH -sTOTAL_MEMORY=20971520"]) @@ -5415,7 +5415,7 @@ AS_VAR_IF([ac_cv_gcc_asm_for_mc68881], [yes], [ # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. AC_CACHE_CHECK([for x87-style double rounding], [ac_cv_x87_double_rounding], [ # $BASECFLAGS may affect the result ac_save_cc="$CC" From webhook-mailer at python.org Mon Aug 29 02:50:41 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 29 Aug 2022 06:50:41 -0000 Subject: [Python-checkins] [3.10] gh-96191: Update the configure file to use GitHub issue (gh-96211) (gh-96376) Message-ID: <mailman.873.1661755843.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f6f8acb6d14b3adbeef2730e874264d7209bfffc commit: f6f8acb6d14b3adbeef2730e874264d7209bfffc branch: 3.10 author: Dong-hee Na <donghee.na at python.org> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-29T15:50:36+09:00 summary: [3.10] gh-96191: Update the configure file to use GitHub issue (gh-96211) (gh-96376) files: M configure M configure.ac diff --git a/configure b/configure index 19f1bd59ba8..bad619963ad 100755 --- a/configure +++ b/configure @@ -2,7 +2,7 @@ # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for python 3.10. # -# Report bugs to <https://bugs.python.org/>. +# Report bugs to <https://github.com/python/cpython/issues/>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -267,10 +267,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf at gnu.org and -$0: https://bugs.python.org/ about your system, including -$0: any error possibly output before this message. Then -$0: install a modern shell, or manually run the script -$0: under such a shell if you do have one." +$0: https://github.com/python/cpython/issues/ about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -582,7 +582,7 @@ PACKAGE_NAME='python' PACKAGE_TARNAME='python' PACKAGE_VERSION='3.10' PACKAGE_STRING='python 3.10' -PACKAGE_BUGREPORT='https://bugs.python.org/' +PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/' PACKAGE_URL='' ac_unique_file="Include/object.h" @@ -1651,7 +1651,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to <https://bugs.python.org/>. +Report bugs to <https://github.com/python/cpython/issues/>. _ACEOF ac_status=$? fi @@ -1919,9 +1919,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## --------------------------------------- ## -## Report this to https://bugs.python.org/ ## -## --------------------------------------- ##" +( $as_echo "## -------------------------------------------------------- ## +## Report this to https://github.com/python/cpython/issues/ ## +## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac @@ -14866,7 +14866,7 @@ fi # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 $as_echo_n "checking for x87-style double rounding... " >&6; } # $BASECFLAGS may affect the result @@ -18627,7 +18627,7 @@ $config_files Configuration headers: $config_headers -Report bugs to <https://bugs.python.org/>." +Report bugs to <https://github.com/python/cpython/issues/>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 diff --git a/configure.ac b/configure.ac index 763fc697be7..cc69015b102 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl *************************************************** dnl * Please run autoreconf -if to test your changes! * dnl *************************************************** dnl -dnl Python's configure script requires autoconf 2.69 and autoconf-archive. +dnl Python's configure.ac file requires autoconf 2.69 and autoconf-archive. dnl # Set VERSION so we only need to edit in one place (i.e., here) @@ -10,7 +10,7 @@ m4_define(PYTHON_VERSION, 3.10) AC_PREREQ([2.69]) -AC_INIT([python],[PYTHON_VERSION],[https://bugs.python.org/]) +AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/]) m4_ifdef( [AX_C_FLOAT_WORDS_BIGENDIAN], @@ -4585,7 +4585,7 @@ fi # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. AC_MSG_CHECKING(for x87-style double rounding) # $BASECFLAGS may affect the result ac_save_cc="$CC" From webhook-mailer at python.org Mon Aug 29 03:13:51 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 29 Aug 2022 07:13:51 -0000 Subject: [Python-checkins] GH-96359: Fix docs that claim int(0|1) doesn't match False (GH-96361) Message-ID: <mailman.874.1661757232.3313.python-checkins@python.org> https://github.com/python/cpython/commit/ca7e78dc3a1a61b6e0045f529c7333334bf10999 commit: ca7e78dc3a1a61b6e0045f529c7333334bf10999 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-29T00:13:28-07:00 summary: GH-96359: Fix docs that claim int(0|1) doesn't match False (GH-96361) (cherry picked from commit 3d3a86ed40626471b2c9e7f1336b228eb0dd0879) Co-authored-by: Jonathan Oberl?nder <github at l3vi.de> files: M Doc/reference/compound_stmts.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 93c1720220f..751c7c2dbcf 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -1122,7 +1122,7 @@ subject value: These classes accept a single positional argument, and the pattern there is matched against the whole object rather than an attribute. For example ``int(0|1)`` matches - the value ``0``, but not the values ``0.0`` or ``False``. + the value ``0``, but not the value ``0.0``. In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens: From webhook-mailer at python.org Mon Aug 29 03:14:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 29 Aug 2022 07:14:38 -0000 Subject: [Python-checkins] GH-96359: Fix docs that claim int(0|1) doesn't match False (GH-96361) Message-ID: <mailman.875.1661757279.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b6fb779489d1daf0c32684eb614c92446d8eacb1 commit: b6fb779489d1daf0c32684eb614c92446d8eacb1 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-29T00:14:33-07:00 summary: GH-96359: Fix docs that claim int(0|1) doesn't match False (GH-96361) (cherry picked from commit 3d3a86ed40626471b2c9e7f1336b228eb0dd0879) Co-authored-by: Jonathan Oberl?nder <github at l3vi.de> files: M Doc/reference/compound_stmts.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 2b429681e1a..911c38f7235 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -1074,7 +1074,7 @@ subject value: These classes accept a single positional argument, and the pattern there is matched against the whole object rather than an attribute. For example ``int(0|1)`` matches - the value ``0``, but not the values ``0.0`` or ``False``. + the value ``0``, but not the value ``0.0``. In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens: From webhook-mailer at python.org Mon Aug 29 04:53:27 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 29 Aug 2022 08:53:27 -0000 Subject: [Python-checkins] gh-95432: Add doctests for the sqlite3 docs (#96225) Message-ID: <mailman.876.1661763208.3313.python-checkins@python.org> https://github.com/python/cpython/commit/bf9259776dff5348bc854983409ea68618c1f174 commit: bf9259776dff5348bc854983409ea68618c1f174 branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-29T10:52:39+02:00 summary: gh-95432: Add doctests for the sqlite3 docs (#96225) As a consequence of the added test, this commit also includes fixes for broken examples. - Add separate namespace for trace tests bco. module level callback - Move more backup and cursor examples under separate namespaces files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 1e54463c11f..f6a86e69f1e 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -343,7 +343,9 @@ Module functions other than checking that there are no unclosed string literals and the statement is terminated by a semicolon. - For example:: + For example: + + .. doctest:: >>> sqlite3.complete_statement("SELECT foo FROM bar;") True @@ -367,22 +369,27 @@ Module functions to disable the feature again. Register an :func:`unraisable hook handler <sys.unraisablehook>` for an - improved debug experience:: + improved debug experience: + + .. testsetup:: sqlite3.trace + + import sqlite3 + + .. doctest:: sqlite3.trace - >>> import sqlite3 >>> sqlite3.enable_callback_tracebacks(True) - >>> cx = sqlite3.connect(":memory:") - >>> cx.set_trace_callback(lambda stmt: 5/0) - >>> cx.execute("select 1") - Exception ignored in: <function <lambda> at 0x10b4e3ee0> - Traceback (most recent call last): - File "<stdin>", line 1, in <lambda> - ZeroDivisionError: division by zero + >>> con = sqlite3.connect(":memory:") + >>> def evil_trace(stmt): + ... 5/0 + >>> con.set_trace_callback(evil_trace) + >>> def debug(unraisable): + ... print(f"{unraisable.exc_value!r} in callback {unraisable.object.__name__}") + ... print(f"Error message: {unraisable.err_msg}") >>> import sys - >>> sys.unraisablehook = lambda unraisable: print(unraisable) - >>> cx.execute("select 1") - UnraisableHookArgs(exc_type=<class 'ZeroDivisionError'>, exc_value=ZeroDivisionError('division by zero'), exc_traceback=<traceback object at 0x10b559900>, err_msg=None, object=<function <lambda> at 0x10b4e3ee0>) - <sqlite3.Cursor object at 0x10b1fe840> + >>> sys.unraisablehook = debug + >>> cur = con.execute("select 1") + ZeroDivisionError('division by zero') in callback evil_trace + Error message: None .. function:: register_adapter(type, adapter, /) @@ -939,12 +946,12 @@ Connection objects Useful when saving an in-memory database for later restoration. Similar to the ``.dump`` command in the :program:`sqlite3` shell. - Example:: + Example: - # Convert file existing_db.db to SQL dump file dump.sql - import sqlite3 + .. testcode:: - con = sqlite3.connect('existing_db.db') + # Convert file example.db to SQL dump file dump.sql + con = sqlite3.connect('example.db') with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) @@ -987,27 +994,32 @@ Connection objects The number of seconds to sleep between successive attempts to back up remaining pages. - Example 1, copy an existing database into another:: + Example 1, copy an existing database into another: - import sqlite3 + .. testcode:: def progress(status, remaining, total): print(f'Copied {total-remaining} of {total} pages...') - con = sqlite3.connect('existing_db.db') - bck = sqlite3.connect('backup.db') - with bck: - con.backup(bck, pages=1, progress=progress) - bck.close() - con.close() + src = sqlite3.connect('example.db') + dst = sqlite3.connect('backup.db') + with dst: + src.backup(dst, pages=1, progress=progress) + dst.close() + src.close() - Example 2, copy an existing database into a transient copy:: + .. testoutput:: + :hide: - import sqlite3 + Copied 0 of 0 pages... - source = sqlite3.connect('existing_db.db') - dest = sqlite3.connect(':memory:') - source.backup(dest) + Example 2, copy an existing database into a transient copy: + + .. testcode:: + + src = sqlite3.connect('example.db') + dst = sqlite3.connect(':memory:') + src.backup(dst) .. versionadded:: 3.7 @@ -1023,12 +1035,20 @@ Connection objects :raises ProgrammingError: If *category* is not recognised by the underlying SQLite library. - Example, query the maximum length of an SQL statement:: + Example, query the maximum length of an SQL statement + for :class:`Connection` ``con`` (the default is 1000000000): + + .. testsetup:: sqlite3.limits import sqlite3 con = sqlite3.connect(":memory:") - lim = con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) - print(f"SQLITE_LIMIT_SQL_LENGTH={lim}") + con.setlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH, 1_000_000_000) + con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 10) + + .. doctest:: sqlite3.limits + + >>> con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) + 1000000000 .. versionadded:: 3.11 @@ -1052,11 +1072,15 @@ Connection objects :raises ProgrammingError: If *category* is not recognised by the underlying SQLite library. - Example, limit the number of attached databases to 1:: + Example, limit the number of attached databases to 1 + for :class:`Connection` ``con`` (the default limit is 10): - import sqlite3 - con = sqlite3.connect(":memory:") - con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) + .. doctest:: sqlite3.limits + + >>> con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) + 10 + >>> con.getlimit(sqlite3.SQLITE_LIMIT_ATTACHED) + 1 .. versionadded:: 3.11 @@ -1132,11 +1156,25 @@ Cursor objects Cursor objects are :term:`iterators <iterator>`, meaning that if you :meth:`~Cursor.execute` a ``SELECT`` query, - you can simply iterate over the cursor to fetch the resulting rows:: + you can simply iterate over the cursor to fetch the resulting rows: + + .. testsetup:: sqlite3.cursor + + import sqlite3 + con = sqlite3.connect(":memory:", isolation_level=None) + cur = con.execute("CREATE TABLE data(t)") + cur.execute("INSERT INTO data VALUES(1)") - for row in cur.execute("select * from data"): + .. testcode:: sqlite3.cursor + + for row in cur.execute("SELECT t FROM data"): print(row) + .. testoutput:: sqlite3.cursor + :hide: + + (1,) + .. _database cursor: https://en.wikipedia.org/wiki/Cursor_(databases) .. class:: Cursor @@ -1172,14 +1210,16 @@ Cursor objects :term:`iterator` yielding parameters instead of a sequence. Uses the same implicit transaction handling as :meth:`~Cursor.execute`. - Example:: + Example: + + .. testcode:: sqlite3.cursor - data = [ - ("row1",), - ("row2",), - ] - # cur is an sqlite3.Cursor object - cur.executemany("insert into t values(?)", data) + rows = [ + ("row1",), + ("row2",), + ] + # cur is an sqlite3.Cursor object + cur.executemany("insert into data values(?)", rows) .. method:: executescript(sql_script, /) @@ -1191,7 +1231,9 @@ Cursor objects *sql_script* must be a :class:`string <str>`. - Example:: + Example: + + .. testcode:: sqlite3.cursor # cur is an sqlite3.Cursor object cur.executescript(""" @@ -1288,7 +1330,9 @@ Cursor objects Read-only attribute that provides the SQLite database :class:`Connection` belonging to the cursor. A :class:`Cursor` object created by calling :meth:`con.cursor() <Connection.cursor>` will have a - :attr:`connection` attribute that refers to *con*:: + :attr:`connection` attribute that refers to *con*: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> cur = con.cursor() @@ -1323,7 +1367,9 @@ Row objects .. versionchanged:: 3.5 Added support of slicing. - Example:: + Example: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> con.row_factory = sqlite3.Row @@ -1700,7 +1746,7 @@ and constructs a :class:`!Point` object from it. Converter functions are **always** passed a :class:`bytes` object, no matter the underlying SQLite data type. -:: +.. testcode:: def convert_point(s): x, y = map(float, s.split(b";")) @@ -1728,7 +1774,7 @@ Adapter and converter recipes This section shows recipes for common adapters and converters. -.. code-block:: +.. testcode:: import datetime import sqlite3 @@ -1741,7 +1787,7 @@ This section shows recipes for common adapters and converters. """Adapt datetime.datetime to timezone-naive ISO 8601 date.""" return val.isoformat() - def adapt_datetime_epoch(val) + def adapt_datetime_epoch(val): """Adapt datetime.datetime to Unix timestamp.""" return int(val.timestamp()) @@ -1815,23 +1861,38 @@ How to work with SQLite URIs Some useful URI tricks include: -* Open a database in read-only mode:: +* Open a database in read-only mode: - con = sqlite3.connect("file:template.db?mode=ro", uri=True) +.. doctest:: + + >>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True) + >>> con.execute("CREATE TABLE readonly(data)") + Traceback (most recent call last): + OperationalError: attempt to write a readonly database * Do not implicitly create a new database file if it does not already exist; - will raise :exc:`~sqlite3.OperationalError` if unable to create a new file:: + will raise :exc:`~sqlite3.OperationalError` if unable to create a new file: + +.. doctest:: + + >>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) + Traceback (most recent call last): + OperationalError: unable to open database file + - con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) +* Create a shared named in-memory database: + +.. testcode:: -* Create a shared named in-memory database:: + db = "file:mem1?mode=memory&cache=shared" + con1 = sqlite3.connect(db, uri=True) + con2 = sqlite3.connect(db, uri=True) + with con1: + con1.execute("CREATE TABLE shared(data)") + con1.execute("INSERT INTO shared VALUES(28)") + res = con2.execute("SELECT data FROM shared") + assert res.fetchone() == (28,) - con1 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True) - con2 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True) - con1.execute("create table t(t)") - con1.execute("insert into t values(28)") - con1.commit() - rows = con2.execute("select * from t").fetchall() More information about this feature, including a list of parameters, can be found in the `SQLite URI documentation`_. From webhook-mailer at python.org Mon Aug 29 05:01:43 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 29 Aug 2022 09:01:43 -0000 Subject: [Python-checkins] gh-95432: Add doctests for the sqlite3 docs (GH-96225) Message-ID: <mailman.877.1661763704.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2ba877258af0b9101d0a6a5ca97e477409c563cb commit: 2ba877258af0b9101d0a6a5ca97e477409c563cb branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-29T02:01:37-07:00 summary: gh-95432: Add doctests for the sqlite3 docs (GH-96225) As a consequence of the added test, this commit also includes fixes for broken examples. - Add separate namespace for trace tests bco. module level callback - Move more backup and cursor examples under separate namespaces (cherry picked from commit bf9259776dff5348bc854983409ea68618c1f174) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 4cc8b77f381..50499b001e2 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -343,7 +343,9 @@ Module functions other than checking that there are no unclosed string literals and the statement is terminated by a semicolon. - For example:: + For example: + + .. doctest:: >>> sqlite3.complete_statement("SELECT foo FROM bar;") True @@ -364,22 +366,27 @@ Module functions to disable the feature again. Register an :func:`unraisable hook handler <sys.unraisablehook>` for an - improved debug experience:: + improved debug experience: + + .. testsetup:: sqlite3.trace + + import sqlite3 + + .. doctest:: sqlite3.trace - >>> import sqlite3 >>> sqlite3.enable_callback_tracebacks(True) - >>> cx = sqlite3.connect(":memory:") - >>> cx.set_trace_callback(lambda stmt: 5/0) - >>> cx.execute("select 1") - Exception ignored in: <function <lambda> at 0x10b4e3ee0> - Traceback (most recent call last): - File "<stdin>", line 1, in <lambda> - ZeroDivisionError: division by zero + >>> con = sqlite3.connect(":memory:") + >>> def evil_trace(stmt): + ... 5/0 + >>> con.set_trace_callback(evil_trace) + >>> def debug(unraisable): + ... print(f"{unraisable.exc_value!r} in callback {unraisable.object.__name__}") + ... print(f"Error message: {unraisable.err_msg}") >>> import sys - >>> sys.unraisablehook = lambda unraisable: print(unraisable) - >>> cx.execute("select 1") - UnraisableHookArgs(exc_type=<class 'ZeroDivisionError'>, exc_value=ZeroDivisionError('division by zero'), exc_traceback=<traceback object at 0x10b559900>, err_msg=None, object=<function <lambda> at 0x10b4e3ee0>) - <sqlite3.Cursor object at 0x10b1fe840> + >>> sys.unraisablehook = debug + >>> cur = con.execute("select 1") + ZeroDivisionError('division by zero') in callback evil_trace + Error message: None .. function:: register_adapter(type, adapter, /) @@ -926,12 +933,12 @@ Connection objects Useful when saving an in-memory database for later restoration. Similar to the ``.dump`` command in the :program:`sqlite3` shell. - Example:: + Example: - # Convert file existing_db.db to SQL dump file dump.sql - import sqlite3 + .. testcode:: - con = sqlite3.connect('existing_db.db') + # Convert file example.db to SQL dump file dump.sql + con = sqlite3.connect('example.db') with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) @@ -974,27 +981,32 @@ Connection objects The number of seconds to sleep between successive attempts to back up remaining pages. - Example 1, copy an existing database into another:: + Example 1, copy an existing database into another: - import sqlite3 + .. testcode:: def progress(status, remaining, total): print(f'Copied {total-remaining} of {total} pages...') - con = sqlite3.connect('existing_db.db') - bck = sqlite3.connect('backup.db') - with bck: - con.backup(bck, pages=1, progress=progress) - bck.close() - con.close() + src = sqlite3.connect('example.db') + dst = sqlite3.connect('backup.db') + with dst: + src.backup(dst, pages=1, progress=progress) + dst.close() + src.close() - Example 2, copy an existing database into a transient copy:: + .. testoutput:: + :hide: - import sqlite3 + Copied 0 of 0 pages... - source = sqlite3.connect('existing_db.db') - dest = sqlite3.connect(':memory:') - source.backup(dest) + Example 2, copy an existing database into a transient copy: + + .. testcode:: + + src = sqlite3.connect('example.db') + dst = sqlite3.connect(':memory:') + src.backup(dst) .. versionadded:: 3.7 @@ -1010,12 +1022,20 @@ Connection objects :raises ProgrammingError: If *category* is not recognised by the underlying SQLite library. - Example, query the maximum length of an SQL statement:: + Example, query the maximum length of an SQL statement + for :class:`Connection` ``con`` (the default is 1000000000): + + .. testsetup:: sqlite3.limits import sqlite3 con = sqlite3.connect(":memory:") - lim = con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) - print(f"SQLITE_LIMIT_SQL_LENGTH={lim}") + con.setlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH, 1_000_000_000) + con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 10) + + .. doctest:: sqlite3.limits + + >>> con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) + 1000000000 .. versionadded:: 3.11 @@ -1039,11 +1059,15 @@ Connection objects :raises ProgrammingError: If *category* is not recognised by the underlying SQLite library. - Example, limit the number of attached databases to 1:: + Example, limit the number of attached databases to 1 + for :class:`Connection` ``con`` (the default limit is 10): - import sqlite3 - con = sqlite3.connect(":memory:") - con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) + .. doctest:: sqlite3.limits + + >>> con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) + 10 + >>> con.getlimit(sqlite3.SQLITE_LIMIT_ATTACHED) + 1 .. versionadded:: 3.11 @@ -1119,11 +1143,25 @@ Cursor objects Cursor objects are :term:`iterators <iterator>`, meaning that if you :meth:`~Cursor.execute` a ``SELECT`` query, - you can simply iterate over the cursor to fetch the resulting rows:: + you can simply iterate over the cursor to fetch the resulting rows: + + .. testsetup:: sqlite3.cursor + + import sqlite3 + con = sqlite3.connect(":memory:", isolation_level=None) + cur = con.execute("CREATE TABLE data(t)") + cur.execute("INSERT INTO data VALUES(1)") - for row in cur.execute("select * from data"): + .. testcode:: sqlite3.cursor + + for row in cur.execute("SELECT t FROM data"): print(row) + .. testoutput:: sqlite3.cursor + :hide: + + (1,) + .. _database cursor: https://en.wikipedia.org/wiki/Cursor_(databases) .. class:: Cursor @@ -1159,14 +1197,16 @@ Cursor objects :term:`iterator` yielding parameters instead of a sequence. Uses the same implicit transaction handling as :meth:`~Cursor.execute`. - Example:: + Example: + + .. testcode:: sqlite3.cursor - data = [ - ("row1",), - ("row2",), - ] - # cur is an sqlite3.Cursor object - cur.executemany("insert into t values(?)", data) + rows = [ + ("row1",), + ("row2",), + ] + # cur is an sqlite3.Cursor object + cur.executemany("insert into data values(?)", rows) .. method:: executescript(sql_script, /) @@ -1178,7 +1218,9 @@ Cursor objects *sql_script* must be a :class:`string <str>`. - Example:: + Example: + + .. testcode:: sqlite3.cursor # cur is an sqlite3.Cursor object cur.executescript(""" @@ -1275,7 +1317,9 @@ Cursor objects Read-only attribute that provides the SQLite database :class:`Connection` belonging to the cursor. A :class:`Cursor` object created by calling :meth:`con.cursor() <Connection.cursor>` will have a - :attr:`connection` attribute that refers to *con*:: + :attr:`connection` attribute that refers to *con*: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> cur = con.cursor() @@ -1310,7 +1354,9 @@ Row objects .. versionchanged:: 3.5 Added support of slicing. - Example:: + Example: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> con.row_factory = sqlite3.Row @@ -1662,7 +1708,7 @@ and constructs a :class:`!Point` object from it. Converter functions are **always** passed a :class:`bytes` object, no matter the underlying SQLite data type. -:: +.. testcode:: def convert_point(s): x, y = map(float, s.split(b";")) @@ -1690,7 +1736,7 @@ Adapter and converter recipes This section shows recipes for common adapters and converters. -.. code-block:: +.. testcode:: import datetime import sqlite3 @@ -1703,7 +1749,7 @@ This section shows recipes for common adapters and converters. """Adapt datetime.datetime to timezone-naive ISO 8601 date.""" return val.isoformat() - def adapt_datetime_epoch(val) + def adapt_datetime_epoch(val): """Adapt datetime.datetime to Unix timestamp.""" return int(val.timestamp()) @@ -1777,23 +1823,38 @@ How to work with SQLite URIs Some useful URI tricks include: -* Open a database in read-only mode:: +* Open a database in read-only mode: - con = sqlite3.connect("file:template.db?mode=ro", uri=True) +.. doctest:: + + >>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True) + >>> con.execute("CREATE TABLE readonly(data)") + Traceback (most recent call last): + OperationalError: attempt to write a readonly database * Do not implicitly create a new database file if it does not already exist; - will raise :exc:`~sqlite3.OperationalError` if unable to create a new file:: + will raise :exc:`~sqlite3.OperationalError` if unable to create a new file: + +.. doctest:: + + >>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) + Traceback (most recent call last): + OperationalError: unable to open database file + - con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) +* Create a shared named in-memory database: + +.. testcode:: -* Create a shared named in-memory database:: + db = "file:mem1?mode=memory&cache=shared" + con1 = sqlite3.connect(db, uri=True) + con2 = sqlite3.connect(db, uri=True) + with con1: + con1.execute("CREATE TABLE shared(data)") + con1.execute("INSERT INTO shared VALUES(28)") + res = con2.execute("SELECT data FROM shared") + assert res.fetchone() == (28,) - con1 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True) - con2 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True) - con1.execute("create table t(t)") - con1.execute("insert into t values(28)") - con1.commit() - rows = con2.execute("select * from t").fetchall() More information about this feature, including a list of parameters, can be found in the `SQLite URI documentation`_. From webhook-mailer at python.org Mon Aug 29 06:29:55 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 29 Aug 2022 10:29:55 -0000 Subject: [Python-checkins] [3.10] gh-95432: Add doctests for the sqlite3 docs (GH-96225) (#96379) Message-ID: <mailman.878.1661768997.3313.python-checkins@python.org> https://github.com/python/cpython/commit/928a692320ed236fe370e321f85afdcd2bda2d61 commit: 928a692320ed236fe370e321f85afdcd2bda2d61 branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-29T12:29:46+02:00 summary: [3.10] gh-95432: Add doctests for the sqlite3 docs (GH-96225) (#96379) As a consequence of the added test, this commit also includes fixes for broken examples. - Add separate namespace for trace tests bco. module level callback - Move more backup and cursor examples under separate namespaces. (cherry picked from commit bf9259776dff5348bc854983409ea68618c1f174) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 94d1e1b0e7a..6d9f929fb59 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -343,7 +343,9 @@ Module functions other than checking that there are no unclosed string literals and the statement is terminated by a semicolon. - For example:: + For example: + + .. doctest:: >>> sqlite3.complete_statement("SELECT foo FROM bar;") True @@ -807,12 +809,12 @@ Connection objects Useful when saving an in-memory database for later restoration. Similar to the ``.dump`` command in the :program:`sqlite3` shell. - Example:: + Example: - # Convert file existing_db.db to SQL dump file dump.sql - import sqlite3 + .. testcode:: - con = sqlite3.connect('existing_db.db') + # Convert file example.db to SQL dump file dump.sql + con = sqlite3.connect('example.db') with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) @@ -855,27 +857,32 @@ Connection objects The number of seconds to sleep between successive attempts to back up remaining pages. - Example 1, copy an existing database into another:: + Example 1, copy an existing database into another: - import sqlite3 + .. testcode:: def progress(status, remaining, total): print(f'Copied {total-remaining} of {total} pages...') - con = sqlite3.connect('existing_db.db') - bck = sqlite3.connect('backup.db') - with bck: - con.backup(bck, pages=1, progress=progress) - bck.close() - con.close() + src = sqlite3.connect('example.db') + dst = sqlite3.connect('backup.db') + with dst: + src.backup(dst, pages=1, progress=progress) + dst.close() + src.close() - Example 2, copy an existing database into a transient copy:: + .. testoutput:: + :hide: - import sqlite3 + Copied 0 of 0 pages... - source = sqlite3.connect('existing_db.db') - dest = sqlite3.connect(':memory:') - source.backup(dest) + Example 2, copy an existing database into a transient copy: + + .. testcode:: + + src = sqlite3.connect('example.db') + dst = sqlite3.connect(':memory:') + src.backup(dst) .. versionadded:: 3.7 @@ -894,11 +901,25 @@ Cursor objects Cursor objects are :term:`iterators <iterator>`, meaning that if you :meth:`~Cursor.execute` a ``SELECT`` query, - you can simply iterate over the cursor to fetch the resulting rows:: + you can simply iterate over the cursor to fetch the resulting rows: + + .. testsetup:: sqlite3.cursor - for row in cur.execute("select * from data"): + import sqlite3 + con = sqlite3.connect(":memory:", isolation_level=None) + cur = con.execute("CREATE TABLE data(t)") + cur.execute("INSERT INTO data VALUES(1)") + + .. testcode:: sqlite3.cursor + + for row in cur.execute("SELECT t FROM data"): print(row) + .. testoutput:: sqlite3.cursor + :hide: + + (1,) + .. _database cursor: https://en.wikipedia.org/wiki/Cursor_(databases) .. class:: Cursor @@ -934,14 +955,16 @@ Cursor objects :term:`iterator` yielding parameters instead of a sequence. Uses the same implicit transaction handling as :meth:`~Cursor.execute`. - Example:: + Example: + + .. testcode:: sqlite3.cursor - data = [ - ("row1",), - ("row2",), - ] - # cur is an sqlite3.Cursor object - cur.executemany("insert into t values(?)", data) + rows = [ + ("row1",), + ("row2",), + ] + # cur is an sqlite3.Cursor object + cur.executemany("insert into data values(?)", rows) .. method:: executescript(sql_script, /) @@ -953,7 +976,9 @@ Cursor objects *sql_script* must be a :class:`string <str>`. - Example:: + Example: + + .. testcode:: sqlite3.cursor # cur is an sqlite3.Cursor object cur.executescript(""" @@ -1050,7 +1075,9 @@ Cursor objects Read-only attribute that provides the SQLite database :class:`Connection` belonging to the cursor. A :class:`Cursor` object created by calling :meth:`con.cursor() <Connection.cursor>` will have a - :attr:`connection` attribute that refers to *con*:: + :attr:`connection` attribute that refers to *con*: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> cur = con.cursor() @@ -1085,7 +1112,9 @@ Row objects .. versionchanged:: 3.5 Added support of slicing. - Example:: + Example: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> con.row_factory = sqlite3.Row @@ -1365,7 +1394,7 @@ and constructs a :class:`!Point` object from it. Converter functions are **always** passed a :class:`bytes` object, no matter the underlying SQLite data type. -:: +.. testcode:: def convert_point(s): x, y = map(float, s.split(b";")) @@ -1393,7 +1422,7 @@ Adapter and converter recipes This section shows recipes for common adapters and converters. -.. code-block:: +.. testcode:: import datetime import sqlite3 @@ -1406,7 +1435,7 @@ This section shows recipes for common adapters and converters. """Adapt datetime.datetime to timezone-naive ISO 8601 date.""" return val.isoformat() - def adapt_datetime_epoch(val) + def adapt_datetime_epoch(val): """Adapt datetime.datetime to Unix timestamp.""" return int(val.timestamp()) @@ -1480,23 +1509,38 @@ How to work with SQLite URIs Some useful URI tricks include: -* Open a database in read-only mode:: +* Open a database in read-only mode: + +.. doctest:: - con = sqlite3.connect("file:template.db?mode=ro", uri=True) + >>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True) + >>> con.execute("CREATE TABLE readonly(data)") + Traceback (most recent call last): + OperationalError: attempt to write a readonly database * Do not implicitly create a new database file if it does not already exist; - will raise :exc:`~sqlite3.OperationalError` if unable to create a new file:: + will raise :exc:`~sqlite3.OperationalError` if unable to create a new file: + +.. doctest:: + + >>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) + Traceback (most recent call last): + OperationalError: unable to open database file - con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) -* Create a shared named in-memory database:: +* Create a shared named in-memory database: + +.. testcode:: + + db = "file:mem1?mode=memory&cache=shared" + con1 = sqlite3.connect(db, uri=True) + con2 = sqlite3.connect(db, uri=True) + with con1: + con1.execute("CREATE TABLE shared(data)") + con1.execute("INSERT INTO shared VALUES(28)") + res = con2.execute("SELECT data FROM shared") + assert res.fetchone() == (28,) - con1 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True) - con2 = sqlite3.connect("file:mem1?mode=memory&cache=shared", uri=True) - con1.execute("create table t(t)") - con1.execute("insert into t values(28)") - con1.commit() - rows = con2.execute("select * from t").fetchall() More information about this feature, including a list of parameters, can be found in the `SQLite URI documentation`_. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 7167f059333..a3380344db3 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -214,10 +214,9 @@ library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) library/sqlite3,,:year,"cur.execute(""select * from lang where first_appeared=:year"", {""year"": 1972})" library/sqlite3,,:memory, -library/sqlite3,,:template,"con = sqlite3.connect(""file:template.db?mode=ro"", uri=True)" -library/sqlite3,,:nosuchdb,"con = sqlite3.connect(""file:nosuchdb.db?mode=rw"", uri=True)" -library/sqlite3,,:mem1,"con1 = sqlite3.connect(""file:mem1?mode=memory&cache=shared"", uri=True)" -library/sqlite3,,:mem1,"con2 = sqlite3.connect(""file:mem1?mode=memory&cache=shared"", uri=True)" +library/sqlite3,,:mem1,"db = ""file:mem1?mode=memory&cache=shared""" +library/sqlite3,,:nosuchdb,">>> con = sqlite3.connect(""file:nosuchdb.db?mode=rw"", uri=True)" +library/sqlite3,,:tutorial,">>> con = sqlite3.connect(""file:tutorial.db?mode=ro"", uri=True)" library/ssl,,:My,"Organizational Unit Name (eg, section) []:My Group" library/ssl,,:My,"Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc." library/ssl,,:myserver,"Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com" From webhook-mailer at python.org Mon Aug 29 07:11:21 2022 From: webhook-mailer at python.org (encukou) Date: Mon, 29 Aug 2022 11:11:21 -0000 Subject: [Python-checkins] gh-90814: Correct NEWS wording re. optional C11 features (GH-96309) Message-ID: <mailman.879.1661771482.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b2714f05c5cc8765178f296f0f8043410e3a5584 commit: b2714f05c5cc8765178f296f0f8043410e3a5584 branch: main author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-29T13:10:52+02:00 summary: gh-90814: Correct NEWS wording re. optional C11 features (GH-96309) The previous wording of this entry suggests that CPython won't work if optional compiler features are enabled. That's not the case. The change is that we require C11 rather than C89. Note that PEP 7 does say "Python 3.11 and newer versions use C11 without optional features." It is correct there: that's not a guide for users who compile Python, but for CPython devs who must avoid the features. files: M Doc/whatsnew/3.11.rst M Misc/NEWS.d/3.11.0a6.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 2159a3175b9..7c72ef4d207 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1619,7 +1619,8 @@ Changes in the Python API Build Changes ============= -* Building Python now requires a C11 compiler without optional C11 features. +* Building Python now requires a C11 compiler. Optional C11 features are not + required. (Contributed by Victor Stinner in :issue:`46656`.) * Building Python now requires support of IEEE 754 floating point numbers. diff --git a/Misc/NEWS.d/3.11.0a6.rst b/Misc/NEWS.d/3.11.0a6.rst index 24fc5f05666..68b80e46690 100644 --- a/Misc/NEWS.d/3.11.0a6.rst +++ b/Misc/NEWS.d/3.11.0a6.rst @@ -1043,7 +1043,8 @@ Respect `--with-suffix` when building on case-insensitive file systems. .. nonce: MD783M .. section: Build -Building Python now requires a C11 compiler without optional C11 features. +Building Python now requires a C11 compiler. Optional C11 features are not +required. Patch by Victor Stinner. .. From webhook-mailer at python.org Mon Aug 29 07:27:52 2022 From: webhook-mailer at python.org (encukou) Date: Mon, 29 Aug 2022 11:27:52 -0000 Subject: [Python-checkins] gh-90814: Correct NEWS wording re. optional C11 features (GH-96309) (GH-96384) Message-ID: <mailman.880.1661772472.3313.python-checkins@python.org> https://github.com/python/cpython/commit/626e45564dd35dad5d6fc65cf16948dab4b7cc01 commit: 626e45564dd35dad5d6fc65cf16948dab4b7cc01 branch: 3.11 author: Petr Viktorin <encukou at gmail.com> committer: encukou <encukou at gmail.com> date: 2022-08-29T13:27:37+02:00 summary: gh-90814: Correct NEWS wording re. optional C11 features (GH-96309) (GH-96384) The previous wording of this entry suggests that CPython won't work if optional compiler features are enabled. That's not the case. The change is that we require C11 rather than C89. Note that PEP 7 does say "Python 3.11 and newer versions use C11 without optional features." It is correct there: that's not a guide for users who compile Python, but for CPython devs who must avoid the features. files: M Doc/whatsnew/3.11.rst M Misc/NEWS.d/3.11.0a6.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 51ce7da47ae..bdeaf6ebc7f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1607,7 +1607,8 @@ Changes in the Python API Build Changes ============= -* Building Python now requires a C11 compiler without optional C11 features. +* Building Python now requires a C11 compiler. Optional C11 features are not + required. (Contributed by Victor Stinner in :issue:`46656`.) * Building Python now requires support of IEEE 754 floating point numbers. diff --git a/Misc/NEWS.d/3.11.0a6.rst b/Misc/NEWS.d/3.11.0a6.rst index 24fc5f05666..68b80e46690 100644 --- a/Misc/NEWS.d/3.11.0a6.rst +++ b/Misc/NEWS.d/3.11.0a6.rst @@ -1043,7 +1043,8 @@ Respect `--with-suffix` when building on case-insensitive file systems. .. nonce: MD783M .. section: Build -Building Python now requires a C11 compiler without optional C11 features. +Building Python now requires a C11 compiler. Optional C11 features are not +required. Patch by Victor Stinner. .. From webhook-mailer at python.org Mon Aug 29 08:56:08 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 29 Aug 2022 12:56:08 -0000 Subject: [Python-checkins] Fix Py_INCREF() statistics in limited C API 3.10 (#96120) Message-ID: <mailman.881.1661777769.3313.python-checkins@python.org> https://github.com/python/cpython/commit/026ab6f4e50658b798be8d1ccf4f3005966e33ea commit: 026ab6f4e50658b798be8d1ccf4f3005966e33ea branch: main author: Victor Stinner <vstinner at python.org> committer: vstinner <vstinner at python.org> date: 2022-08-29T14:55:46+02:00 summary: Fix Py_INCREF() statistics in limited C API 3.10 (#96120) In the limited C API with a debug build, Py_INCREF() is implemented by calling _Py_IncRef() which calls Py_INCREF(). Only call _Py_INCREF_STAT_INC() once. files: M Include/object.h diff --git a/Include/object.h b/Include/object.h index 21d3a75834eb..75624fe8c77a 100644 --- a/Include/object.h +++ b/Include/object.h @@ -511,11 +511,11 @@ PyAPI_FUNC(void) _Py_DecRef(PyObject *); static inline void Py_INCREF(PyObject *op) { - _Py_INCREF_STAT_INC(); #if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 // Stable ABI for Python 3.10 built in debug mode. _Py_IncRef(op); #else + _Py_INCREF_STAT_INC(); // Non-limited C API and limited C API for Python 3.9 and older access // directly PyObject.ob_refcnt. #ifdef Py_REF_DEBUG From webhook-mailer at python.org Mon Aug 29 10:05:33 2022 From: webhook-mailer at python.org (isidentical) Date: Mon, 29 Aug 2022 14:05:33 -0000 Subject: [Python-checkins] ast.parse: check `feature_version` common case first (GH-94640) Message-ID: <mailman.882.1661781935.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9c2b9348e21a4ba3e995345501898c383972752d commit: 9c2b9348e21a4ba3e995345501898c383972752d branch: main author: Anthony Sottile <asottile at umich.edu> committer: isidentical <isidentical at gmail.com> date: 2022-08-29T17:05:24+03:00 summary: ast.parse: check `feature_version` common case first (GH-94640) files: M Lib/ast.py diff --git a/Lib/ast.py b/Lib/ast.py index ebf4529f79b0..8af6d1ed14db 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -40,13 +40,13 @@ def parse(source, filename='<unknown>', mode='exec', *, flags = PyCF_ONLY_AST if type_comments: flags |= PyCF_TYPE_COMMENTS - if isinstance(feature_version, tuple): + if feature_version is None: + feature_version = -1 + elif isinstance(feature_version, tuple): major, minor = feature_version # Should be a 2-tuple. if major != 3: raise ValueError(f"Unsupported major version: {major}") feature_version = minor - elif feature_version is None: - feature_version = -1 # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, _feature_version=feature_version) From webhook-mailer at python.org Mon Aug 29 12:19:29 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 29 Aug 2022 16:19:29 -0000 Subject: [Python-checkins] gh-94682: Build and test with OpenSSL 1.1.1q (gh-94683) Message-ID: <mailman.883.1661789970.3313.python-checkins@python.org> https://github.com/python/cpython/commit/873554ef84011773618911ffa698cea181cec9fd commit: 873554ef84011773618911ffa698cea181cec9fd branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-29T18:19:15+02:00 summary: gh-94682: Build and test with OpenSSL 1.1.1q (gh-94683) files: A Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 9e9ce2108ed8..bf164d19ef22 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index c3ecc6705728..3cbd19fda982 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d800442ad07e..1db5c5051493 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -175,7 +175,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1n + OPENSSL_VER: 1.1.1q PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout at v3 @@ -234,7 +234,7 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.1.1n, 3.0.2] + openssl_ver: [1.1.1q, 3.0.5] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl @@ -281,7 +281,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1n + OPENSSL_VER: 1.1.1q PYTHONSTRICTEXTENSIONBUILD: 1 ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 steps: diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index a1d31c423814..65fc013999dc 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1n", - url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", - checksum='2aad5635f9bb338bc2c6b7d19cbc9676', + name="OpenSSL 1.1.1q", + url="https://www.openssl.org/source/openssl-1.1.1q.tar.gz", + checksum='d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca', buildrecipe=build_universal_openssl, configure=None, install=None, @@ -797,10 +797,16 @@ def verifyThirdPartyFile(url, checksum, fname): print("Downloading %s"%(name,)) downloadURL(url, fname) print("Archive for %s stored as %s"%(name, fname)) + if len(checksum) == 32: + algo = 'md5' + elif len(checksum) == 64: + algo = 'sha256' + else: + raise ValueError(checksum) if os.system( - 'MD5=$(openssl md5 %s) ; test "${MD5##*= }" = "%s"' - % (shellQuote(fname), checksum) ): - fatal('MD5 checksum mismatch for file %s' % fname) + 'CHECKSUM=$(openssl %s %s) ; test "${CHECKSUM##*= }" = "%s"' + % (algo, shellQuote(fname), checksum) ): + fatal('%s checksum mismatch for file %s' % (algo, fname)) def build_universal_openssl(basedir, archList): """ diff --git a/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst b/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst new file mode 100644 index 000000000000..60717a15bcc2 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst @@ -0,0 +1 @@ +Build and test with OpenSSL 1.1.1q diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index d29344517988..cd211f13e355 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.2 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1q set libraries=%libraries% sqlite-3.38.4.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.1 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.1 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.2 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1q if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.1 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index 7f10e7c45ef7..efcb480976b6 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -67,8 +67,8 @@ <libffiDir>$(ExternalsDir)libffi-3.4.2\</libffiDir> <libffiOutDir>$(ExternalsDir)libffi-3.4.2\$(ArchName)\</libffiOutDir> <libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir> - <opensslDir>$(ExternalsDir)openssl-1.1.1n\</opensslDir> - <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\</opensslOutDir> + <opensslDir>$(ExternalsDir)openssl-1.1.1q\</opensslDir> + <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1q\$(ArchName)\</opensslOutDir> <opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir> <nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir> <zlibDir>$(ExternalsDir)\zlib-1.2.12\</zlibDir> diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index e4cad75189c9..c536fac94cc6 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -168,7 +168,7 @@ _lzma Homepage: https://tukaani.org/xz/ _ssl - Python wrapper for version 1.1.1k of the OpenSSL secure sockets + Python wrapper for version 1.1.1q of the OpenSSL secure sockets library, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 24ddd2a20913..d64b4f66f519 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -46,8 +46,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1n", - "3.0.2" + "1.1.1q", + "3.0.5" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Mon Aug 29 12:47:29 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 29 Aug 2022 16:47:29 -0000 Subject: [Python-checkins] gh-94682: Build and test with OpenSSL 1.1.1q (gh-94683) Message-ID: <mailman.884.1661791651.3313.python-checkins@python.org> https://github.com/python/cpython/commit/882c7cf4c7125a1fa93f016a1822fdf4f16329f3 commit: 882c7cf4c7125a1fa93f016a1822fdf4f16329f3 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-29T09:47:20-07:00 summary: gh-94682: Build and test with OpenSSL 1.1.1q (gh-94683) (cherry picked from commit 873554ef84011773618911ffa698cea181cec9fd) Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 9e9ce2108ed8..bf164d19ef22 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index c3ecc6705728..3cbd19fda982 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70cafd8e07cd..bb08b2ff62d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -203,7 +203,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1n + OPENSSL_VER: 1.1.1q PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout at v3 @@ -262,7 +262,7 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.1.1n, 3.0.2] + openssl_ver: [1.1.1q, 3.0.5] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl @@ -309,7 +309,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1n + OPENSSL_VER: 1.1.1q PYTHONSTRICTEXTENSIONBUILD: 1 ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 steps: diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 91e2dd6191e5..fa614b10efae 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1n", - url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", - checksum='2aad5635f9bb338bc2c6b7d19cbc9676', + name="OpenSSL 1.1.1q", + url="https://www.openssl.org/source/openssl-1.1.1q.tar.gz", + checksum='d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca', buildrecipe=build_universal_openssl, configure=None, install=None, @@ -796,10 +796,16 @@ def verifyThirdPartyFile(url, checksum, fname): print("Downloading %s"%(name,)) downloadURL(url, fname) print("Archive for %s stored as %s"%(name, fname)) + if len(checksum) == 32: + algo = 'md5' + elif len(checksum) == 64: + algo = 'sha256' + else: + raise ValueError(checksum) if os.system( - 'MD5=$(openssl md5 %s) ; test "${MD5##*= }" = "%s"' - % (shellQuote(fname), checksum) ): - fatal('MD5 checksum mismatch for file %s' % fname) + 'CHECKSUM=$(openssl %s %s) ; test "${CHECKSUM##*= }" = "%s"' + % (algo, shellQuote(fname), checksum) ): + fatal('%s checksum mismatch for file %s' % (algo, fname)) def build_universal_openssl(basedir, archList): """ diff --git a/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst b/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst new file mode 100644 index 000000000000..60717a15bcc2 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst @@ -0,0 +1 @@ +Build and test with OpenSSL 1.1.1q diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index d29344517988..cd211f13e355 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.2 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1q set libraries=%libraries% sqlite-3.38.4.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.1 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.1 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.2 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1q if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.1 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index 7f10e7c45ef7..efcb480976b6 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -67,8 +67,8 @@ <libffiDir>$(ExternalsDir)libffi-3.4.2\</libffiDir> <libffiOutDir>$(ExternalsDir)libffi-3.4.2\$(ArchName)\</libffiOutDir> <libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir> - <opensslDir>$(ExternalsDir)openssl-1.1.1n\</opensslDir> - <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\</opensslOutDir> + <opensslDir>$(ExternalsDir)openssl-1.1.1q\</opensslDir> + <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1q\$(ArchName)\</opensslOutDir> <opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir> <nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir> <zlibDir>$(ExternalsDir)\zlib-1.2.12\</zlibDir> diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index e4cad75189c9..c536fac94cc6 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -168,7 +168,7 @@ _lzma Homepage: https://tukaani.org/xz/ _ssl - Python wrapper for version 1.1.1k of the OpenSSL secure sockets + Python wrapper for version 1.1.1q of the OpenSSL secure sockets library, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 82076808bfd3..91d6f558bc51 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -47,8 +47,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1n", - "3.0.2" + "1.1.1q", + "3.0.5" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Mon Aug 29 13:20:14 2022 From: webhook-mailer at python.org (rhettinger) Date: Mon, 29 Aug 2022 17:20:14 -0000 Subject: [Python-checkins] Improve accuracy for Spearman's rank correlation coefficient. (#96392) Message-ID: <mailman.885.1661793615.3313.python-checkins@python.org> https://github.com/python/cpython/commit/3d180e3ab21c5d41d1c46e3ef349b30ba409f300 commit: 3d180e3ab21c5d41d1c46e3ef349b30ba409f300 branch: main author: Raymond Hettinger <rhettinger at users.noreply.github.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-29T12:19:48-05:00 summary: Improve accuracy for Spearman's rank correlation coefficient. (#96392) files: M Lib/statistics.py diff --git a/Lib/statistics.py b/Lib/statistics.py index b4676fed5e2..b4adabd3f05 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -379,7 +379,7 @@ def _rank(data, /, *, key=None, reverse=False, ties='average', start=1) -> list[ [2.0, 1.0, 3.0] Ranks are conventionally numbered starting from one; however, - setting *start* to zero allow the ranks to be used as array indices: + setting *start* to zero allows the ranks to be used as array indices: >>> prize = ['Gold', 'Silver', 'Bronze', 'Certificate'] >>> scores = [8.1, 7.3, 9.4, 8.3] @@ -1073,8 +1073,9 @@ def correlation(x, y, /, *, method='linear'): if method not in {'linear', 'ranked'}: raise ValueError(f'Unknown method: {method!r}') if method == 'ranked': - x = _rank(x) - y = _rank(y) + start = (n - 1) / -2 # Center rankings around zero + x = _rank(x, start=start) + y = _rank(y, start=start) xbar = fsum(x) / n ybar = fsum(y) / n sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) From webhook-mailer at python.org Mon Aug 29 14:02:05 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 29 Aug 2022 18:02:05 -0000 Subject: [Python-checkins] [3.10] gh-94682: Build and test with OpenSSL 1.1.1q (gh-94683) (gh-96391) Message-ID: <mailman.886.1661796126.3313.python-checkins@python.org> https://github.com/python/cpython/commit/32a45011e72f9c5c0a61438ec295d2793af51ba9 commit: 32a45011e72f9c5c0a61438ec295d2793af51ba9 branch: 3.10 author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-29T20:02:00+02:00 summary: [3.10] gh-94682: Build and test with OpenSSL 1.1.1q (gh-94683) (gh-96391) Co-authored-by: Christian Heimes <christian at python.org> files: A Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index d0efa77f9305..8dd79eeccdb0 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index a4f32460c7ea..e1b282be129d 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1n + openssl_version: 1.1.1q steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b98514aaf945..1545ae87dca0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -190,7 +190,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1n + OPENSSL_VER: 1.1.1q PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout at v3 @@ -234,7 +234,7 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.1.1n, 3.0.2] + openssl_ver: [1.1.1q, 3.0.5] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 4308a2003ce7..668667c00729 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1n", - url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", - checksum='2aad5635f9bb338bc2c6b7d19cbc9676', + name="OpenSSL 1.1.1q", + url="https://www.openssl.org/source/openssl-1.1.1q.tar.gz", + checksum='d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca', buildrecipe=build_universal_openssl, configure=None, install=None, @@ -793,10 +793,16 @@ def verifyThirdPartyFile(url, checksum, fname): print("Downloading %s"%(name,)) downloadURL(url, fname) print("Archive for %s stored as %s"%(name, fname)) + if len(checksum) == 32: + algo = 'md5' + elif len(checksum) == 64: + algo = 'sha256' + else: + raise ValueError(checksum) if os.system( - 'MD5=$(openssl md5 %s) ; test "${MD5##*= }" = "%s"' - % (shellQuote(fname), checksum) ): - fatal('MD5 checksum mismatch for file %s' % fname) + 'CHECKSUM=$(openssl %s %s) ; test "${CHECKSUM##*= }" = "%s"' + % (algo, shellQuote(fname), checksum) ): + fatal('%s checksum mismatch for file %s' % (algo, fname)) def build_universal_openssl(basedir, archList): """ diff --git a/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst b/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst new file mode 100644 index 000000000000..60717a15bcc2 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-07-08-10-28-23.gh-issue-94682.ZtGt_0.rst @@ -0,0 +1 @@ +Build and test with OpenSSL 1.1.1q diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index ee79addd44d0..208b573562dc 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1q set libraries=%libraries% sqlite-3.37.2.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.3.0 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1q if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index 859f9db2a8fc..b3604b19a10d 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -63,8 +63,8 @@ <libffiDir>$(ExternalsDir)libffi-3.3.0\</libffiDir> <libffiOutDir>$(ExternalsDir)libffi-3.3.0\$(ArchName)\</libffiOutDir> <libffiIncludeDir>$(libffiOutDir)include</libffiIncludeDir> - <opensslDir>$(ExternalsDir)openssl-1.1.1n\</opensslDir> - <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\</opensslOutDir> + <opensslDir>$(ExternalsDir)openssl-1.1.1q\</opensslDir> + <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1q\$(ArchName)\</opensslOutDir> <opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir> <nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir> <zlibDir>$(ExternalsDir)\zlib-1.2.12\</zlibDir> diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 76f421a9aaee..3af4c5c7da18 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -167,7 +167,7 @@ _lzma Homepage: https://tukaani.org/xz/ _ssl - Python wrapper for version 1.1.1k of the OpenSSL secure sockets + Python wrapper for version 1.1.1q of the OpenSSL secure sockets library, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 82076808bfd3..91d6f558bc51 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -47,8 +47,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1n", - "3.0.2" + "1.1.1q", + "3.0.5" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Mon Aug 29 14:31:25 2022 From: webhook-mailer at python.org (gvanrossum) Date: Mon, 29 Aug 2022 18:31:25 -0000 Subject: [Python-checkins] GH-74116: Allow multiple drain waiters for asyncio.StreamWriter (GH-94705) Message-ID: <mailman.887.1661797886.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e5b2453e61ba5376831093236d598ef5f9f1de61 commit: e5b2453e61ba5376831093236d598ef5f9f1de61 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-29T11:31:11-07:00 summary: GH-74116: Allow multiple drain waiters for asyncio.StreamWriter (GH-94705) files: A Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst M Lib/asyncio/streams.py M Lib/test/test_asyncio/test_streams.py diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 614b2cda6068..c4d837a11708 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -2,6 +2,7 @@ 'StreamReader', 'StreamWriter', 'StreamReaderProtocol', 'open_connection', 'start_server') +import collections import socket import sys import weakref @@ -128,7 +129,7 @@ def __init__(self, loop=None): else: self._loop = loop self._paused = False - self._drain_waiter = None + self._drain_waiters = collections.deque() self._connection_lost = False def pause_writing(self): @@ -143,38 +144,34 @@ def resume_writing(self): if self._loop.get_debug(): logger.debug("%r resumes writing", self) - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None + for waiter in self._drain_waiters: if not waiter.done(): waiter.set_result(None) def connection_lost(self, exc): self._connection_lost = True - # Wake up the writer if currently paused. + # Wake up the writer(s) if currently paused. if not self._paused: return - waiter = self._drain_waiter - if waiter is None: - return - self._drain_waiter = None - if waiter.done(): - return - if exc is None: - waiter.set_result(None) - else: - waiter.set_exception(exc) + + for waiter in self._drain_waiters: + if not waiter.done(): + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) async def _drain_helper(self): if self._connection_lost: raise ConnectionResetError('Connection lost') if not self._paused: return - waiter = self._drain_waiter - assert waiter is None or waiter.cancelled() waiter = self._loop.create_future() - self._drain_waiter = waiter - await waiter + self._drain_waiters.append(waiter) + try: + await waiter + finally: + self._drain_waiters.remove(waiter) def _get_close_waiter(self, stream): raise NotImplementedError diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 098a0da344d0..0c49099bc499 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -864,6 +864,25 @@ def test_streamreaderprotocol_constructor_use_global_loop(self): self.assertEqual(cm.filename, __file__) self.assertIs(protocol._loop, self.loop) + def test_multiple_drain(self): + # See https://github.com/python/cpython/issues/74116 + drained = 0 + + async def drainer(stream): + nonlocal drained + await stream._drain_helper() + drained += 1 + + async def main(): + loop = asyncio.get_running_loop() + stream = asyncio.streams.FlowControlMixin(loop) + stream.pause_writing() + loop.call_later(0.1, stream.resume_writing) + await asyncio.gather(*[drainer(stream) for _ in range(10)]) + self.assertEqual(drained, 10) + + self.loop.run_until_complete(main()) + def test_drain_raises(self): # See http://bugs.python.org/issue25441 diff --git a/Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst b/Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst new file mode 100644 index 000000000000..33782598745b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst @@ -0,0 +1 @@ +Allow :meth:`asyncio.StreamWriter.drain` to be awaited concurrently by multiple tasks. Patch by Kumar Aditya. From webhook-mailer at python.org Mon Aug 29 17:29:32 2022 From: webhook-mailer at python.org (vsajip) Date: Mon, 29 Aug 2022 21:29:32 -0000 Subject: [Python-checkins] gh-91305: Add a note about DatagramHandler and DNS latency. (GH-96380) Message-ID: <mailman.888.1661808572.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6324b135acb92042017c2364540c37426b0ea65f commit: 6324b135acb92042017c2364540c37426b0ea65f branch: main author: Vinay Sajip <vinay_sajip at yahoo.co.uk> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-29T22:29:22+01:00 summary: gh-91305: Add a note about DatagramHandler and DNS latency. (GH-96380) files: M Doc/library/logging.handlers.rst diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index f125dfe64a03..a0129279f4db 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -572,6 +572,13 @@ over UDP sockets. Returns a new instance of the :class:`DatagramHandler` class intended to communicate with a remote machine whose address is given by *host* and *port*. + .. note:: As UDP is not a streaming protocol, there is no persistent connection + between an instance of this handler and *host*. For this reason, when using a + network socket, a DNS lookup might have to be made each time an event is + logged, which can introduce some latency into the system. If this affects you, + you can do a lookup yourself and initialize this handler using the looked-up IP + address rather than the hostname. + .. versionchanged:: 3.4 If ``port`` is specified as ``None``, a Unix domain socket is created using the value in ``host`` - otherwise, a UDP socket is created. From webhook-mailer at python.org Mon Aug 29 18:50:50 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Mon, 29 Aug 2022 22:50:50 -0000 Subject: [Python-checkins] Docs: normalize SQL style in sqlite3 docs (#96403) Message-ID: <mailman.889.1661813452.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6d403e264a7dcd1544a91708f139c6dd8612204d commit: 6d403e264a7dcd1544a91708f139c6dd8612204d branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-30T00:50:42+02:00 summary: Docs: normalize SQL style in sqlite3 docs (#96403) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index f6a86e69f1e..31a0e7f0b53 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -387,7 +387,7 @@ Module functions ... print(f"Error message: {unraisable.err_msg}") >>> import sys >>> sys.unraisablehook = debug - >>> cur = con.execute("select 1") + >>> cur = con.execute("SELECT 1") ZeroDivisionError('division by zero') in callback evil_trace Error message: None @@ -1219,7 +1219,7 @@ Cursor objects ("row2",), ] # cur is an sqlite3.Cursor object - cur.executemany("insert into data values(?)", rows) + cur.executemany("INSERT INTO data VALUES(?)", rows) .. method:: executescript(sql_script, /) @@ -1237,11 +1237,11 @@ Cursor objects # cur is an sqlite3.Cursor object cur.executescript(""" - begin; - create table person(firstname, lastname, age); - create table book(title, author, published); - create table publisher(name, address); - commit; + BEGIN; + CREATE TABLE person(firstname, lastname, age); + CREATE TABLE book(title, author, published); + CREATE TABLE publisher(name, address); + COMMIT; """) From webhook-mailer at python.org Mon Aug 29 18:59:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 29 Aug 2022 22:59:18 -0000 Subject: [Python-checkins] Docs: normalize SQL style in sqlite3 docs (GH-96403) Message-ID: <mailman.890.1661813959.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4cfb6395e18b4846e92c9f685d534e6ec17822a2 commit: 4cfb6395e18b4846e92c9f685d534e6ec17822a2 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-29T15:59:13-07:00 summary: Docs: normalize SQL style in sqlite3 docs (GH-96403) (cherry picked from commit 6d403e264a7dcd1544a91708f139c6dd8612204d) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 50499b001e2..21ad3540ccb 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -384,7 +384,7 @@ Module functions ... print(f"Error message: {unraisable.err_msg}") >>> import sys >>> sys.unraisablehook = debug - >>> cur = con.execute("select 1") + >>> cur = con.execute("SELECT 1") ZeroDivisionError('division by zero') in callback evil_trace Error message: None @@ -1206,7 +1206,7 @@ Cursor objects ("row2",), ] # cur is an sqlite3.Cursor object - cur.executemany("insert into data values(?)", rows) + cur.executemany("INSERT INTO data VALUES(?)", rows) .. method:: executescript(sql_script, /) @@ -1224,11 +1224,11 @@ Cursor objects # cur is an sqlite3.Cursor object cur.executescript(""" - begin; - create table person(firstname, lastname, age); - create table book(title, author, published); - create table publisher(name, address); - commit; + BEGIN; + CREATE TABLE person(firstname, lastname, age); + CREATE TABLE book(title, author, published); + CREATE TABLE publisher(name, address); + COMMIT; """) From webhook-mailer at python.org Tue Aug 30 00:36:52 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 30 Aug 2022 04:36:52 -0000 Subject: [Python-checkins] gh-96320: WASI socket fixes (#96388) Message-ID: <mailman.891.1661834213.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d0b3d235dbc560ada459e386b6fa5b5ce1952c7e commit: d0b3d235dbc560ada459e386b6fa5b5ce1952c7e branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-30T06:36:11+02:00 summary: gh-96320: WASI socket fixes (#96388) * gh-96320: WASI socket fixes - ignore missing functions in ``socket.__repr__`` - bundle network files with assets * blurb files: A Misc/NEWS.d/next/Library/2022-08-29-16-54-36.gh-issue-96388.dCpJcu.rst M Lib/socket.py M Tools/wasm/wasm_assets.py diff --git a/Lib/socket.py b/Lib/socket.py index 0ed86afb4a9e..1c8cef6ce658 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -255,17 +255,18 @@ def __repr__(self): self.type, self.proto) if not closed: + # getsockname and getpeername may not be available on WASI. try: laddr = self.getsockname() if laddr: s += ", laddr=%s" % str(laddr) - except error: + except (error, AttributeError): pass try: raddr = self.getpeername() if raddr: s += ", raddr=%s" % str(raddr) - except error: + except (error, AttributeError): pass s += '>' return s diff --git a/Misc/NEWS.d/next/Library/2022-08-29-16-54-36.gh-issue-96388.dCpJcu.rst b/Misc/NEWS.d/next/Library/2022-08-29-16-54-36.gh-issue-96388.dCpJcu.rst new file mode 100644 index 000000000000..3a35c4734871 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-29-16-54-36.gh-issue-96388.dCpJcu.rst @@ -0,0 +1,2 @@ +Work around missing socket functions in :class:`~socket.socket`'s +``__repr__``. diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py index a300d594414a..a35acfd9387b 100755 --- a/Tools/wasm/wasm_assets.py +++ b/Tools/wasm/wasm_assets.py @@ -230,7 +230,8 @@ def main(): extmods = detect_extension_modules(args) omit_files = list(OMIT_FILES) - omit_files.extend(OMIT_NETWORKING_FILES) + if sysconfig.get_platform().startswith("emscripten"): + omit_files.extend(OMIT_NETWORKING_FILES) for modname, modfiles in OMIT_MODULE_FILES.items(): if not extmods.get(modname): omit_files.extend(modfiles) From webhook-mailer at python.org Tue Aug 30 01:56:35 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 30 Aug 2022 05:56:35 -0000 Subject: [Python-checkins] gh-95853: Improve WASM build script (GH-96389) Message-ID: <mailman.892.1661838997.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2eb9008d726e15838a2c8b36c8bd0bf67f229458 commit: 2eb9008d726e15838a2c8b36c8bd0bf67f229458 branch: main author: Christian Heimes <christian at python.org> committer: tiran <christian at python.org> date: 2022-08-30T07:56:26+02:00 summary: gh-95853: Improve WASM build script (GH-96389) - pre-build Emscripten ports and system libraries - check for broken EMSDK versions - use EMSDK's node for wasm32-emscripten - warn when PKG_CONFIG_PATH is set - add support level information files: A Misc/NEWS.d/next/Tools-Demos/2022-08-29-17-25-13.gh-issue-95853.Ce17cT.rst M Tools/wasm/wasm_build.py diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-08-29-17-25-13.gh-issue-95853.Ce17cT.rst b/Misc/NEWS.d/next/Tools-Demos/2022-08-29-17-25-13.gh-issue-95853.Ce17cT.rst new file mode 100644 index 000000000000..1cd1ce14fac0 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2022-08-29-17-25-13.gh-issue-95853.Ce17cT.rst @@ -0,0 +1,2 @@ +The ``wasm_build.py`` script now pre-builds Emscripten ports, checks for +broken EMSDK versions, and warns about pkg-config env vars. diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py index 5ccf88cbc44f..9054370e5e2f 100755 --- a/Tools/wasm/wasm_build.py +++ b/Tools/wasm/wasm_build.py @@ -25,9 +25,11 @@ import shutil import subprocess import sysconfig +import tempfile +import warnings # for Python 3.8 -from typing import Any, Dict, Callable, Iterable, List, Optional, Union +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union SRCDIR = pathlib.Path(__file__).parent.parent.parent.absolute() WASMTOOLS = SRCDIR / "Tools" / "wasm" @@ -45,6 +47,11 @@ EM_CONFIG = pathlib.Path(os.environ.setdefault("EM_CONFIG", "/opt/emsdk/.emscripten")) # 3.1.16 has broken utime() EMSDK_MIN_VERSION = (3, 1, 17) +EMSDK_BROKEN_VERSION = { + (3, 1, 14): "https://github.com/emscripten-core/emscripten/issues/17338", + (3, 1, 16): "https://github.com/emscripten-core/emscripten/issues/17393", + (3, 1, 20): "https://github.com/emscripten-core/emscripten/issues/17720", +} _MISSING = pathlib.PurePath("MISSING") # WASM_WEBSERVER = WASMTOOLS / "wasmwebserver.py" @@ -80,24 +87,28 @@ """ -def get_emscripten_root(emconfig: pathlib.Path = EM_CONFIG) -> pathlib.PurePath: - """Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT +def parse_emconfig( + emconfig: pathlib.Path = EM_CONFIG, +) -> Tuple[pathlib.PurePath, pathlib.PurePath]: + """Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT and NODE_JS. The ".emscripten" config file is a Python snippet that uses "EM_CONFIG" environment variable. EMSCRIPTEN_ROOT is the "upstream/emscripten" subdirectory with tools like "emconfigure". """ if not emconfig.exists(): - return _MISSING + return _MISSING, _MISSING with open(emconfig, encoding="utf-8") as f: code = f.read() # EM_CONFIG file is a Python snippet local: Dict[str, Any] = {} exec(code, globals(), local) - return pathlib.Path(local["EMSCRIPTEN_ROOT"]) + emscripten_root = pathlib.Path(local["EMSCRIPTEN_ROOT"]) + node_js = pathlib.Path(local["NODE_JS"]) + return emscripten_root, node_js -EMSCRIPTEN_ROOT = get_emscripten_root() +EMSCRIPTEN_ROOT, NODE_JS = parse_emconfig() def read_python_version(configure: pathlib.Path = CONFIGURE) -> str: @@ -153,6 +164,9 @@ class Platform: make_wrapper: Optional[pathlib.PurePath] environ: dict check: Callable[[], None] + # Used for build_emports(). + ports: Optional[pathlib.PurePath] + cc: Optional[pathlib.PurePath] def getenv(self, profile: "BuildProfile") -> dict: return self.environ.copy() @@ -174,6 +188,8 @@ def _check_clean_src(): pythonexe=sysconfig.get_config_var("BUILDPYTHON") or "python", config_site=None, configure_wrapper=None, + ports=None, + cc=None, make_wrapper=None, environ={}, check=_check_clean_src, @@ -198,12 +214,26 @@ def _check_emscripten(): version = version[:-4] version_tuple = tuple(int(v) for v in version.split(".")) if version_tuple < EMSDK_MIN_VERSION: - raise MissingDependency( + raise ConditionError( os.fspath(version_txt), f"Emscripten SDK {version} in '{EMSCRIPTEN_ROOT}' is older than " "minimum required version " f"{'.'.join(str(v) for v in EMSDK_MIN_VERSION)}.", ) + broken = EMSDK_BROKEN_VERSION.get(version_tuple) + if broken is not None: + raise ConditionError( + os.fspath(version_txt), + ( + f"Emscripten SDK {version} in '{EMSCRIPTEN_ROOT}' has known " + f"bugs, see {broken}." + ), + ) + if os.environ.get("PKG_CONFIG_PATH"): + warnings.warn( + "PKG_CONFIG_PATH is set and not empty. emconfigure overrides " + "this environment variable. Use EM_PKG_CONFIG_PATH instead." + ) _check_clean_src() @@ -212,11 +242,14 @@ def _check_emscripten(): pythonexe="python.js", config_site=WASMTOOLS / "config.site-wasm32-emscripten", configure_wrapper=EMSCRIPTEN_ROOT / "emconfigure", + ports=EMSCRIPTEN_ROOT / "embuilder", + cc=EMSCRIPTEN_ROOT / "emcc", make_wrapper=EMSCRIPTEN_ROOT / "emmake", environ={ # workaround for https://github.com/emscripten-core/emscripten/issues/17635 "TZ": "UTC", "EM_COMPILER_WRAPPER": "ccache" if HAS_CCACHE else None, + "PATH": [EMSCRIPTEN_ROOT, os.environ["PATH"]], }, check=_check_emscripten, ) @@ -237,6 +270,8 @@ def _check_wasi(): pythonexe="python.wasm", config_site=WASMTOOLS / "config.site-wasm32-wasi", configure_wrapper=WASMTOOLS / "wasi-env", + ports=None, + cc=WASI_SDK_PATH / "bin" / "clang", make_wrapper=None, environ={ "WASI_SDK_PATH": WASI_SDK_PATH, @@ -246,6 +281,7 @@ def _check_wasi(): "--env PYTHONPATH=/{relbuilddir}/build/lib.wasi-wasm32-{version}:/Lib " "--mapdir /::{srcdir} --" ), + "PATH": [WASI_SDK_PATH / "bin", os.environ["PATH"]], }, check=_check_wasi, ) @@ -280,6 +316,42 @@ def is_wasi(self) -> bool: cls = type(self) return self in {cls.wasm32_wasi, cls.wasm64_wasi} + def get_extra_paths(self) -> Iterable[pathlib.PurePath]: + """Host-specific os.environ["PATH"] entries. + + Emscripten's Node version 14.x works well for wasm32-emscripten. + wasm64-emscripten requires more recent v8 version, e.g. node 16.x. + Attempt to use system's node command. + """ + cls = type(self) + if self == cls.wasm32_emscripten: + return [NODE_JS.parent] + elif self == cls.wasm64_emscripten: + # TODO: look for recent node + return [] + else: + return [] + + @property + def emport_args(self) -> List[str]: + """Host-specific port args (Emscripten).""" + cls = type(self) + if self is cls.wasm64_emscripten: + return ["-sMEMORY64=1"] + elif self is cls.wasm32_emscripten: + return ["-sMEMORY64=0"] + else: + return [] + + @property + def embuilder_args(self) -> List[str]: + """Host-specific embuilder args (Emscripten).""" + cls = type(self) + if self is cls.wasm64_emscripten: + return ["--wasm64"] + else: + return [] + class EmscriptenTarget(enum.Enum): """Emscripten-specific targets (--with-emscripten-target)""" @@ -294,10 +366,32 @@ def can_execute(self) -> bool: cls = type(self) return self not in {cls.browser, cls.browser_debug} + @property + def emport_args(self) -> List[str]: + """Target-specific port args.""" + cls = type(self) + if self in {cls.browser_debug, cls.node_debug}: + # some libs come in debug and non-debug builds + return ["-O0"] + else: + return ["-O2"] + + +class SupportLevel(enum.Enum): + supported = "tier 3, supported" + working = "working, unsupported" + experimental = "experimental, may be broken" + broken = "broken / unavailable" + + def __bool__(self): + cls = type(self) + return self in {cls.supported, cls.working} + @dataclasses.dataclass class BuildProfile: name: str + support_level: SupportLevel host: Host target: Union[EmscriptenTarget, None] = None dynamic_linking: Union[bool, None] = None @@ -380,6 +474,12 @@ def getenv(self) -> dict: for key, value in platenv.items(): if value is None: env.pop(key, None) + elif key == "PATH": + # list of path items, prefix with extra paths + new_path: List[pathlib.PurePath] = [] + new_path.extend(self.host.get_extra_paths()) + new_path.extend(value) + env[key] = os.pathsep.join(os.fspath(p) for p in new_path) elif isinstance(value, str): env[key] = value.format( relbuilddir=self.builddir.relative_to(SRCDIR), @@ -390,12 +490,19 @@ def getenv(self) -> dict: env[key] = value return env - def _run_cmd(self, cmd: Iterable[str], args: Iterable[str]): + def _run_cmd( + self, + cmd: Iterable[str], + args: Iterable[str] = (), + cwd: Optional[pathlib.Path] = None, + ): cmd = list(cmd) cmd.extend(args) + if cwd is None: + cwd = self.builddir return subprocess.check_call( cmd, - cwd=os.fspath(self.builddir), + cwd=os.fspath(cwd), env=self.getenv(), ) @@ -443,10 +550,58 @@ def clean(self, all: bool = False): elif self.makefile.exists(): self.run_make("clean") + def build_emports(self, force: bool = False): + """Pre-build emscripten ports.""" + platform = self.host.platform + if platform.ports is None or platform.cc is None: + raise ValueError("Need ports and CC command") + + embuilder_cmd = [os.fspath(platform.ports)] + embuilder_cmd.extend(self.host.embuilder_args) + if force: + embuilder_cmd.append("--force") + + ports_cmd = [os.fspath(platform.cc)] + ports_cmd.extend(self.host.emport_args) + if self.target: + ports_cmd.extend(self.target.emport_args) + + if self.dynamic_linking: + # Trigger PIC build. + ports_cmd.append("-sMAIN_MODULE") + embuilder_cmd.append("--pic") + if self.pthreads: + # Trigger multi-threaded build. + ports_cmd.append("-sUSE_PTHREADS") + # https://github.com/emscripten-core/emscripten/pull/17729 + # embuilder_cmd.append("--pthreads") + + # Pre-build libbz2, libsqlite3, libz, and some system libs. + ports_cmd.extend(["-sUSE_ZLIB", "-sUSE_BZIP2", "-sUSE_SQLITE3"]) + embuilder_cmd.extend(["build", "bzip2", "sqlite3", "zlib"]) + + if not self.pthreads: + # Emscripten <= 3.1.20 has no option to build multi-threaded ports. + self._run_cmd(embuilder_cmd, cwd=SRCDIR) + + with tempfile.TemporaryDirectory(suffix="-py-emport") as tmpdir: + tmppath = pathlib.Path(tmpdir) + main_c = tmppath / "main.c" + main_js = tmppath / "main.js" + with main_c.open("w") as f: + f.write("int main(void) { return 0; }\n") + args = [ + os.fspath(main_c), + "-o", + os.fspath(main_js), + ] + self._run_cmd(ports_cmd, args, cwd=tmppath) + # native build (build Python) BUILD = BuildProfile( "build", + support_level=SupportLevel.working, host=Host.build, ) @@ -455,43 +610,59 @@ def clean(self, all: bool = False): # wasm32-emscripten BuildProfile( "emscripten-browser", + support_level=SupportLevel.supported, host=Host.wasm32_emscripten, target=EmscriptenTarget.browser, dynamic_linking=True, ), BuildProfile( "emscripten-browser-debug", + support_level=SupportLevel.working, host=Host.wasm32_emscripten, target=EmscriptenTarget.browser_debug, dynamic_linking=True, ), BuildProfile( "emscripten-node-dl", + support_level=SupportLevel.supported, host=Host.wasm32_emscripten, target=EmscriptenTarget.node, dynamic_linking=True, ), BuildProfile( "emscripten-node-dl-debug", + support_level=SupportLevel.working, host=Host.wasm32_emscripten, target=EmscriptenTarget.node_debug, dynamic_linking=True, ), BuildProfile( "emscripten-node-pthreads", + support_level=SupportLevel.supported, host=Host.wasm32_emscripten, target=EmscriptenTarget.node, pthreads=True, ), BuildProfile( "emscripten-node-pthreads-debug", + support_level=SupportLevel.working, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node_debug, + pthreads=True, + ), + # Emscripten build with both pthreads and dynamic linking is crashing. + BuildProfile( + "emscripten-node-dl-pthreads-debug", + support_level=SupportLevel.broken, host=Host.wasm32_emscripten, target=EmscriptenTarget.node_debug, + dynamic_linking=True, pthreads=True, ), - # wasm64-emscripten (currently not working) + # wasm64-emscripten (requires unreleased Emscripten >= 3.1.21) BuildProfile( "wasm64-emscripten-node-debug", + support_level=SupportLevel.experimental, host=Host.wasm64_emscripten, target=EmscriptenTarget.node_debug, # MEMORY64 is not compatible with dynamic linking @@ -501,6 +672,7 @@ def clean(self, all: bool = False): # wasm32-wasi BuildProfile( "wasi", + support_level=SupportLevel.supported, host=Host.wasm32_wasi, # skip sysconfig test_srcdir testopts="-i '*.test_srcdir' -j2", @@ -508,6 +680,7 @@ def clean(self, all: bool = False): # no SDK available yet # BuildProfile( # "wasm64-wasi", + # support_level=SupportLevel.broken, # host=Host.wasm64_wasi, # ), ] @@ -523,15 +696,17 @@ def clean(self, all: bool = False): "--clean", "-c", help="Clean build directories first", action="store_true" ) -platforms = list(PROFILES) + ["cleanall"] +# Don't list broken and experimental variants in help +platforms_choices = list(p.name for p in _profiles) + ["cleanall"] +platforms_help = list(p.name for p in _profiles if p.support_level) + ["cleanall"] parser.add_argument( "platform", metavar="PLATFORM", - help=f"Build platform: {', '.join(platforms)}", - choices=platforms, + help=f"Build platform: {', '.join(platforms_help)}", + choices=platforms_choices, ) -ops = ["compile", "pythoninfo", "test", "repl", "clean", "cleanall"] +ops = ["compile", "pythoninfo", "test", "repl", "clean", "cleanall", "emports"] parser.add_argument( "op", metavar="OP", @@ -572,6 +747,8 @@ def main(): builder.clean(all=False) if args.op == "compile": + if builder.host.is_emscripten: + builder.build_emports() builder.run_build(force_configure=True) else: if not builder.makefile.exists(): @@ -586,6 +763,8 @@ def main(): builder.clean(all=False) elif args.op == "cleanall": builder.clean(all=True) + elif args.op == "emports": + builder.build_emports(force=args.clean) else: raise ValueError(args.op) From webhook-mailer at python.org Tue Aug 30 03:03:46 2022 From: webhook-mailer at python.org (methane) Date: Tue, 30 Aug 2022 07:03:46 -0000 Subject: [Python-checkins] gh-46845: clean up unused DK_IXSIZE (GH-96405) Message-ID: <mailman.893.1661843027.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d21d2f0793ce32d72759d5cfc11622d13e3e6b81 commit: d21d2f0793ce32d72759d5cfc11622d13e3e6b81 branch: main author: Matthias G?rgens <matthias.goergens at gmail.com> committer: methane <songofacandy at gmail.com> date: 2022-08-30T16:03:30+09:00 summary: gh-46845: clean up unused DK_IXSIZE (GH-96405) files: M Include/internal/pycore_dict.h diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 5370106d529f..464092996cae 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -141,17 +141,8 @@ struct _dictvalues { #define DK_LOG_SIZE(dk) ((dk)->dk_log2_size) #if SIZEOF_VOID_P > 4 #define DK_SIZE(dk) (((int64_t)1)<<DK_LOG_SIZE(dk)) -#define DK_IXSIZE(dk) \ - (DK_LOG_SIZE(dk) <= 7 ? \ - 1 : DK_LOG_SIZE(dk) <= 15 ? \ - 2 : DK_LOG_SIZE(dk) <= 31 ? \ - 4 : sizeof(int64_t)) #else #define DK_SIZE(dk) (1<<DK_LOG_SIZE(dk)) -#define DK_IXSIZE(dk) \ - (DK_LOG_SIZE(dk) <= 7 ? \ - 1 : DK_LOG_SIZE(dk) <= 15 ? \ - 2 : sizeof(int32_t)) #endif #define DK_ENTRIES(dk) \ (assert((dk)->dk_kind == DICT_KEYS_GENERAL), \ From webhook-mailer at python.org Tue Aug 30 03:29:02 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 07:29:02 -0000 Subject: [Python-checkins] gh-46845: clean up unused DK_IXSIZE (GH-96405) Message-ID: <mailman.894.1661844542.3313.python-checkins@python.org> https://github.com/python/cpython/commit/1901ee7a5251a3a2a2d9f65f25205b0b918d5c97 commit: 1901ee7a5251a3a2a2d9f65f25205b0b918d5c97 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T00:28:51-07:00 summary: gh-46845: clean up unused DK_IXSIZE (GH-96405) (cherry picked from commit d21d2f0793ce32d72759d5cfc11622d13e3e6b81) Co-authored-by: Matthias G?rgens <matthias.goergens at gmail.com> files: M Include/internal/pycore_dict.h diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 24d2a711878c..dc308fe5e218 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -141,17 +141,8 @@ struct _dictvalues { #define DK_LOG_SIZE(dk) ((dk)->dk_log2_size) #if SIZEOF_VOID_P > 4 #define DK_SIZE(dk) (((int64_t)1)<<DK_LOG_SIZE(dk)) -#define DK_IXSIZE(dk) \ - (DK_LOG_SIZE(dk) <= 7 ? \ - 1 : DK_LOG_SIZE(dk) <= 15 ? \ - 2 : DK_LOG_SIZE(dk) <= 31 ? \ - 4 : sizeof(int64_t)) #else #define DK_SIZE(dk) (1<<DK_LOG_SIZE(dk)) -#define DK_IXSIZE(dk) \ - (DK_LOG_SIZE(dk) <= 7 ? \ - 1 : DK_LOG_SIZE(dk) <= 15 ? \ - 2 : sizeof(int32_t)) #endif #define DK_ENTRIES(dk) \ (assert(dk->dk_kind == DICT_KEYS_GENERAL), (PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) From webhook-mailer at python.org Tue Aug 30 03:35:07 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Tue, 30 Aug 2022 07:35:07 -0000 Subject: [Python-checkins] gh-96385: Correctly raise error on `[*T, *V]` substitution (GH-96386) Message-ID: <mailman.895.1661844907.3313.python-checkins@python.org> https://github.com/python/cpython/commit/75177358a62afeabd1d3aa0e9f395c2b9d4495ca commit: 75177358a62afeabd1d3aa0e9f395c2b9d4495ca branch: main author: Nikita Sobolev <mail at sobolevn.me> committer: serhiy-storchaka <storchaka at gmail.com> date: 2022-08-30T10:34:55+03:00 summary: gh-96385: Correctly raise error on `[*T, *V]` substitution (GH-96386) files: A Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index ca7bd8e083c4..7eea01909ec8 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -596,6 +596,7 @@ class GenericAliasSubstitutionTests(BaseTestCase): def test_one_parameter(self): T = TypeVar('T') Ts = TypeVarTuple('Ts') + Ts2 = TypeVarTuple('Ts2') class C(Generic[T]): pass @@ -621,6 +622,8 @@ class C(Generic[T]): pass # Should definitely raise TypeError: list only takes one argument. ('list[T, *tuple_type[int, ...]]', '[int]', 'list[int, *tuple_type[int, ...]]'), ('List[T, *tuple_type[int, ...]]', '[int]', 'TypeError'), + # Should raise, because more than one `TypeVarTuple` is not supported. + ('generic[*Ts, *Ts2]', '[int]', 'TypeError'), ] for alias_template, args_template, expected_template in tests: diff --git a/Lib/typing.py b/Lib/typing.py index 43ef07e50cfe..596744ed1322 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1074,7 +1074,7 @@ def __typing_subst__(self, arg): def __typing_prepare_subst__(self, alias, args): params = alias.__parameters__ typevartuple_index = params.index(self) - for param in enumerate(params[typevartuple_index + 1:]): + for param in params[typevartuple_index + 1:]: if isinstance(param, TypeVarTuple): raise TypeError(f"More than one TypeVarTuple parameter in {alias}") diff --git a/Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst b/Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst new file mode 100644 index 000000000000..57354826f349 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst @@ -0,0 +1,3 @@ +Fix ``TypeVarTuple.__typing_prepare_subst__``. ``TypeError`` was not raised +when using more than one ``TypeVarTuple``, like ``[*T, *V]`` in type alias +substitutions. From webhook-mailer at python.org Tue Aug 30 04:00:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 08:00:31 -0000 Subject: [Python-checkins] gh-95231: Disable md5 & crypt modules if FIPS is enabled (GH-94742) Message-ID: <mailman.896.1661846432.3313.python-checkins@python.org> https://github.com/python/cpython/commit/069fefdaf42490f1e00243614fb5f3d5d2614b81 commit: 069fefdaf42490f1e00243614fb5f3d5d2614b81 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T00:59:56-07:00 summary: gh-95231: Disable md5 & crypt modules if FIPS is enabled (GH-94742) If kernel fips is enabled, we get permission error upon doing `import crypt`. So, if kernel fips is enabled, disable the unallowed hashing methods. Python 3.9.1 (default, May 10 2022, 11:36:26) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import crypt Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.9/crypt.py", line 117, in <module> _add_method('MD5', '1', 8, 34) File "/usr/lib/python3.9/crypt.py", line 94, in _add_method result = crypt('', salt) File "/usr/lib/python3.9/crypt.py", line 82, in crypt return _crypt.crypt(word, salt) PermissionError: [Errno 1] Operation not permitted Signed-off-by: Shreenidhi Shedi <sshedi at vmware.com> (cherry picked from commit 2fa03b1b0708d5d74630c351ec9abd2aac7550da) Co-authored-by: Shreenidhi Shedi <53473811+sshedi at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst M Lib/crypt.py diff --git a/Lib/crypt.py b/Lib/crypt.py index 33dbc46bb3e9..b296c3edb0f5 100644 --- a/Lib/crypt.py +++ b/Lib/crypt.py @@ -94,7 +94,7 @@ def _add_method(name, *args, rounds=None): result = crypt('', salt) except OSError as e: # Not all libc libraries support all encryption methods. - if e.errno == errno.EINVAL: + if e.errno in {errno.EINVAL, errno.EPERM, errno.ENOSYS}: return False raise if result and len(result) == method.total_size: diff --git a/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst b/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst new file mode 100644 index 000000000000..aa53f2938bc9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-25-15-45-06.gh-issue-95231.i807-g.rst @@ -0,0 +1,3 @@ +Fail gracefully if :data:`~errno.EPERM` or :data:`~errno.ENOSYS` is raised when loading +:mod:`crypt` methods. This may happen when trying to load ``MD5`` on a Linux kernel +with :abbr:`FIPS (Federal Information Processing Standard)` enabled. From webhook-mailer at python.org Tue Aug 30 04:31:36 2022 From: webhook-mailer at python.org (methane) Date: Tue, 30 Aug 2022 08:31:36 -0000 Subject: [Python-checkins] Doc: Update Py_TPFLAGS_HAVE_FINALIZE in docs (GH-96273) Message-ID: <mailman.897.1661848297.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9625de6fab4597bcd04ec390b680b053b0533816 commit: 9625de6fab4597bcd04ec390b680b053b0533816 branch: main author: da-woods <dw-git at d-woods.co.uk> committer: methane <songofacandy at gmail.com> date: 2022-08-30T17:31:14+09:00 summary: Doc: Update Py_TPFLAGS_HAVE_FINALIZE in docs (GH-96273) It is now deprecated and the docs should reflect that. files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index dfe91ee358d0..20cdffed110c 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2005,9 +2005,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) PyErr_Restore(error_type, error_value, error_traceback); } - For this field to be taken into account (even through inheritance), - you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. - Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from any Python thread, not just the thread which created the object (if the object @@ -2025,6 +2022,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.4 + .. versionchanged:: 3.8 + + Before version 3.8 it was necessary to set the + :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be + used. This is no longer required. + .. seealso:: "Safe object finalization" (:pep:`442`) From webhook-mailer at python.org Tue Aug 30 04:35:27 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 30 Aug 2022 08:35:27 -0000 Subject: [Python-checkins] [3.10] Docs: normalize SQL style in sqlite3 docs (GH-96403). (#96409) Message-ID: <mailman.898.1661848527.3313.python-checkins@python.org> https://github.com/python/cpython/commit/af9fbec27e83252b6dc1bb27f228f80319ac85bd commit: af9fbec27e83252b6dc1bb27f228f80319ac85bd branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-30T10:35:21+02:00 summary: [3.10] Docs: normalize SQL style in sqlite3 docs (GH-96403). (#96409) (cherry picked from commit 6d403e264a7dcd1544a91708f139c6dd8612204d) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 6d9f929fb59..18a03a26e29 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -964,7 +964,7 @@ Cursor objects ("row2",), ] # cur is an sqlite3.Cursor object - cur.executemany("insert into data values(?)", rows) + cur.executemany("INSERT INTO data VALUES(?)", rows) .. method:: executescript(sql_script, /) @@ -982,11 +982,11 @@ Cursor objects # cur is an sqlite3.Cursor object cur.executescript(""" - begin; - create table person(firstname, lastname, age); - create table book(title, author, published); - create table publisher(name, address); - commit; + BEGIN; + CREATE TABLE person(firstname, lastname, age); + CREATE TABLE book(title, author, published); + CREATE TABLE publisher(name, address); + COMMIT; """) From webhook-mailer at python.org Tue Aug 30 04:38:58 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 08:38:58 -0000 Subject: [Python-checkins] Doc: Update Py_TPFLAGS_HAVE_FINALIZE in docs (GH-96273) Message-ID: <mailman.899.1661848740.3313.python-checkins@python.org> https://github.com/python/cpython/commit/e89f8b0ae4f00677b3111ed563ad67acd21e9cbf commit: e89f8b0ae4f00677b3111ed563ad67acd21e9cbf branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T01:38:53-07:00 summary: Doc: Update Py_TPFLAGS_HAVE_FINALIZE in docs (GH-96273) It is now deprecated and the docs should reflect that. (cherry picked from commit 9625de6fab4597bcd04ec390b680b053b0533816) Co-authored-by: da-woods <dw-git at d-woods.co.uk> files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 9bb0e6dbbcf8..b939d930b18c 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1990,9 +1990,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) PyErr_Restore(error_type, error_value, error_traceback); } - For this field to be taken into account (even through inheritance), - you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. - Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from any Python thread, not just the thread which created the object (if the object @@ -2010,6 +2007,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.4 + .. versionchanged:: 3.8 + + Before version 3.8 it was necessary to set the + :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be + used. This is no longer required. + .. seealso:: "Safe object finalization" (:pep:`442`) From webhook-mailer at python.org Tue Aug 30 04:38:58 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 08:38:58 -0000 Subject: [Python-checkins] Doc: Update Py_TPFLAGS_HAVE_FINALIZE in docs (GH-96273) Message-ID: <mailman.900.1661848740.3313.python-checkins@python.org> https://github.com/python/cpython/commit/53a344ef8099f131934d9d5032e8a1cd605cf963 commit: 53a344ef8099f131934d9d5032e8a1cd605cf963 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T01:38:40-07:00 summary: Doc: Update Py_TPFLAGS_HAVE_FINALIZE in docs (GH-96273) It is now deprecated and the docs should reflect that. (cherry picked from commit 9625de6fab4597bcd04ec390b680b053b0533816) Co-authored-by: da-woods <dw-git at d-woods.co.uk> files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 01d67a5a498f..8be489ad1efc 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1984,9 +1984,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) PyErr_Restore(error_type, error_value, error_traceback); } - For this field to be taken into account (even through inheritance), - you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. - Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from any Python thread, not just the thread which created the object (if the object @@ -2004,6 +2001,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.4 + .. versionchanged:: 3.8 + + Before version 3.8 it was necessary to set the + :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be + used. This is no longer required. + .. seealso:: "Safe object finalization" (:pep:`442`) From webhook-mailer at python.org Tue Aug 30 04:58:27 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 30 Aug 2022 08:58:27 -0000 Subject: [Python-checkins] [3.10] gh-91305: Add a note about DatagramHandler and DNS latency. (GH-96380) (GH-96400) Message-ID: <mailman.901.1661849908.3313.python-checkins@python.org> https://github.com/python/cpython/commit/57f447267c16e67901f3454b5f37151786c43927 commit: 57f447267c16e67901f3454b5f37151786c43927 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-30T09:58:14+01:00 summary: [3.10] gh-91305: Add a note about DatagramHandler and DNS latency. (GH-96380) (GH-96400) files: M Doc/library/logging.handlers.rst diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index f125dfe64a0..a0129279f4d 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -572,6 +572,13 @@ over UDP sockets. Returns a new instance of the :class:`DatagramHandler` class intended to communicate with a remote machine whose address is given by *host* and *port*. + .. note:: As UDP is not a streaming protocol, there is no persistent connection + between an instance of this handler and *host*. For this reason, when using a + network socket, a DNS lookup might have to be made each time an event is + logged, which can introduce some latency into the system. If this affects you, + you can do a lookup yourself and initialize this handler using the looked-up IP + address rather than the hostname. + .. versionchanged:: 3.4 If ``port`` is specified as ``None``, a Unix domain socket is created using the value in ``host`` - otherwise, a UDP socket is created. From webhook-mailer at python.org Tue Aug 30 04:58:43 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 30 Aug 2022 08:58:43 -0000 Subject: [Python-checkins] [3.11] gh-91305: Add a note about DatagramHandler and DNS latency. (GH-96380) (GH-96401) Message-ID: <mailman.902.1661849924.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8e2d347183df4b4fcd2f3bd963bd7575c6db663b commit: 8e2d347183df4b4fcd2f3bd963bd7575c6db663b branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-30T09:58:37+01:00 summary: [3.11] gh-91305: Add a note about DatagramHandler and DNS latency. (GH-96380) (GH-96401) files: M Doc/library/logging.handlers.rst diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 1e61a519bc0..c4f501faca6 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -572,6 +572,13 @@ over UDP sockets. Returns a new instance of the :class:`DatagramHandler` class intended to communicate with a remote machine whose address is given by *host* and *port*. + .. note:: As UDP is not a streaming protocol, there is no persistent connection + between an instance of this handler and *host*. For this reason, when using a + network socket, a DNS lookup might have to be made each time an event is + logged, which can introduce some latency into the system. If this affects you, + you can do a lookup yourself and initialize this handler using the looked-up IP + address rather than the hostname. + .. versionchanged:: 3.4 If ``port`` is specified as ``None``, a Unix domain socket is created using the value in ``host`` - otherwise, a UDP socket is created. From webhook-mailer at python.org Tue Aug 30 06:58:49 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 30 Aug 2022 10:58:49 -0000 Subject: [Python-checkins] [3.10] Clean up junk & fix typo in 3.10.6 release notes (#95997) Message-ID: <mailman.903.1661857130.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0a096e01c65aab42dc2a4a0100402e53a8be603a commit: 0a096e01c65aab42dc2a4a0100402e53a8be603a branch: 3.10 author: Marti Raudsepp <marti at juffo.org> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-30T11:58:21+01:00 summary: [3.10] Clean up junk & fix typo in 3.10.6 release notes (#95997) files: M Misc/NEWS.d/3.10.6.rst diff --git a/Misc/NEWS.d/3.10.6.rst b/Misc/NEWS.d/3.10.6.rst index fbbb77d91ab..93d5121de25 100644 --- a/Misc/NEWS.d/3.10.6.rst +++ b/Misc/NEWS.d/3.10.6.rst @@ -587,7 +587,7 @@ The minimum Sphinx version required to build the documentation is now 3.2. .. section: Documentation Augmented documentation of asyncio.create_task(). Clarified the need to keep -strong references to tasks and added a code snippet detailing how to to +strong references to tasks and added a code snippet detailing how to do this. .. @@ -630,11 +630,6 @@ parallel-safe. Added more tests for :mod:`dataclasses` to cover behavior with data descriptor-based fields. -# Write your Misc/NEWS entry below. It should be a simple ReST paragraph. # -Don't start with "- Issue #<n>: " or "- gh-issue-<n>: " or that sort of -stuff. -########################################################################### - .. .. date: 2022-06-27-21-27-20 From webhook-mailer at python.org Tue Aug 30 06:59:00 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 30 Aug 2022 10:59:00 -0000 Subject: [Python-checkins] gh-96385: Correctly raise error on `[*T, *V]` substitution (GH-96386) (#96407) Message-ID: <mailman.904.1661857141.3313.python-checkins@python.org> https://github.com/python/cpython/commit/16d8948c31537355f64f38de4f4ebc4ef5b9e7b8 commit: 16d8948c31537355f64f38de4f4ebc4ef5b9e7b8 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-30T11:58:54+01:00 summary: gh-96385: Correctly raise error on `[*T, *V]` substitution (GH-96386) (#96407) (cherry picked from commit 75177358a62afeabd1d3aa0e9f395c2b9d4495ca) Co-authored-by: Nikita Sobolev <mail at sobolevn.me> Co-authored-by: Nikita Sobolev <mail at sobolevn.me> files: A Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 2fd57822726e..776a6f003c06 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -591,6 +591,7 @@ class GenericAliasSubstitutionTests(BaseTestCase): def test_one_parameter(self): T = TypeVar('T') Ts = TypeVarTuple('Ts') + Ts2 = TypeVarTuple('Ts2') class C(Generic[T]): pass @@ -616,6 +617,8 @@ class C(Generic[T]): pass # Should definitely raise TypeError: list only takes one argument. ('list[T, *tuple_type[int, ...]]', '[int]', 'list[int, *tuple_type[int, ...]]'), ('List[T, *tuple_type[int, ...]]', '[int]', 'TypeError'), + # Should raise, because more than one `TypeVarTuple` is not supported. + ('generic[*Ts, *Ts2]', '[int]', 'TypeError'), ] for alias_template, args_template, expected_template in tests: diff --git a/Lib/typing.py b/Lib/typing.py index 9d6babefe6c2..354976caaaa0 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1071,7 +1071,7 @@ def __typing_subst__(self, arg): def __typing_prepare_subst__(self, alias, args): params = alias.__parameters__ typevartuple_index = params.index(self) - for param in enumerate(params[typevartuple_index + 1:]): + for param in params[typevartuple_index + 1:]: if isinstance(param, TypeVarTuple): raise TypeError(f"More than one TypeVarTuple parameter in {alias}") diff --git a/Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst b/Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst new file mode 100644 index 000000000000..57354826f349 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-29-15-28-39.gh-issue-96385.uLRTsf.rst @@ -0,0 +1,3 @@ +Fix ``TypeVarTuple.__typing_prepare_subst__``. ``TypeError`` was not raised +when using more than one ``TypeVarTuple``, like ``[*T, *V]`` in type alias +substitutions. From webhook-mailer at python.org Tue Aug 30 06:59:37 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 30 Aug 2022 10:59:37 -0000 Subject: [Python-checkins] gh-90467: StreamReaderProtocol - add strong reference to created task (GH-96323) (#96344) Message-ID: <mailman.905.1661857177.3313.python-checkins@python.org> https://github.com/python/cpython/commit/126ec34558ef9e2fd688cc85b0951b559ce6a889 commit: 126ec34558ef9e2fd688cc85b0951b559ce6a889 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-30T11:59:32+01:00 summary: gh-90467: StreamReaderProtocol - add strong reference to created task (GH-96323) (#96344) (cherry picked from commit e860e521ec0d84e175269aeb15cf24bd6053ad17) Co-authored-by: Kirill <iam at python273.pw> Co-authored-by: Kirill <iam at python273.pw> files: A Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst M Lib/asyncio/streams.py M Misc/ACKS diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index a568c4e4b295..af78e6b45881 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -206,6 +206,7 @@ def __init__(self, stream_reader, client_connected_cb=None, loop=None): self._strong_reader = stream_reader self._reject_connection = False self._stream_writer = None + self._task = None self._transport = None self._client_connected_cb = client_connected_cb self._over_ssl = False @@ -248,7 +249,7 @@ def connection_made(self, transport): res = self._client_connected_cb(reader, self._stream_writer) if coroutines.iscoroutine(res): - self._loop.create_task(res) + self._task = self._loop.create_task(res) self._strong_reader = None def connection_lost(self, exc): @@ -266,6 +267,7 @@ def connection_lost(self, exc): super().connection_lost(exc) self._stream_reader_wr = None self._stream_writer = None + self._task = None self._transport = None def data_received(self, data): diff --git a/Misc/ACKS b/Misc/ACKS index 6e53d5a7cc4b..58b29c19400e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1438,6 +1438,7 @@ Ram Rachum Jeffrey Rackauckas J?r?me Radix Burton Radons +Kirill (python273) R. Abhilash Raj Shorya Raj Ajith Ramachandran @@ -1981,6 +1982,7 @@ Gordon Worley Darren Worrall Thomas Wouters Daniel Wozniak +Simon Wrede Marcin Niemira Wei Wu Heiko Wundram diff --git a/Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst b/Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst new file mode 100644 index 000000000000..282c0e76a8c8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst @@ -0,0 +1,2 @@ +Fix :class:`asyncio.streams.StreamReaderProtocol` to keep a strong reference +to the created task, so that it's not garbage collected From webhook-mailer at python.org Tue Aug 30 07:00:26 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 30 Aug 2022 11:00:26 -0000 Subject: [Python-checkins] GH-74116: Allow multiple drain waiters for asyncio.StreamWriter (GH-94705) (#96395) Message-ID: <mailman.906.1661857228.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2e9f29e6a660a33f84d64a5bce5b422e72c06e39 commit: 2e9f29e6a660a33f84d64a5bce5b422e72c06e39 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-30T12:00:21+01:00 summary: GH-74116: Allow multiple drain waiters for asyncio.StreamWriter (GH-94705) (#96395) (cherry picked from commit e5b2453e61ba5376831093236d598ef5f9f1de61) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst M Lib/asyncio/streams.py M Lib/test/test_asyncio/test_streams.py diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index af78e6b45881..d21a31d1860d 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -2,6 +2,7 @@ 'StreamReader', 'StreamWriter', 'StreamReaderProtocol', 'open_connection', 'start_server') +import collections import socket import sys import warnings @@ -129,7 +130,7 @@ def __init__(self, loop=None): else: self._loop = loop self._paused = False - self._drain_waiter = None + self._drain_waiters = collections.deque() self._connection_lost = False def pause_writing(self): @@ -144,38 +145,34 @@ def resume_writing(self): if self._loop.get_debug(): logger.debug("%r resumes writing", self) - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None + for waiter in self._drain_waiters: if not waiter.done(): waiter.set_result(None) def connection_lost(self, exc): self._connection_lost = True - # Wake up the writer if currently paused. + # Wake up the writer(s) if currently paused. if not self._paused: return - waiter = self._drain_waiter - if waiter is None: - return - self._drain_waiter = None - if waiter.done(): - return - if exc is None: - waiter.set_result(None) - else: - waiter.set_exception(exc) + + for waiter in self._drain_waiters: + if not waiter.done(): + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) async def _drain_helper(self): if self._connection_lost: raise ConnectionResetError('Connection lost') if not self._paused: return - waiter = self._drain_waiter - assert waiter is None or waiter.cancelled() waiter = self._loop.create_future() - self._drain_waiter = waiter - await waiter + self._drain_waiters.append(waiter) + try: + await waiter + finally: + self._drain_waiters.remove(waiter) def _get_close_waiter(self, stream): raise NotImplementedError diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 098a0da344d0..0c49099bc499 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -864,6 +864,25 @@ def test_streamreaderprotocol_constructor_use_global_loop(self): self.assertEqual(cm.filename, __file__) self.assertIs(protocol._loop, self.loop) + def test_multiple_drain(self): + # See https://github.com/python/cpython/issues/74116 + drained = 0 + + async def drainer(stream): + nonlocal drained + await stream._drain_helper() + drained += 1 + + async def main(): + loop = asyncio.get_running_loop() + stream = asyncio.streams.FlowControlMixin(loop) + stream.pause_writing() + loop.call_later(0.1, stream.resume_writing) + await asyncio.gather(*[drainer(stream) for _ in range(10)]) + self.assertEqual(drained, 10) + + self.loop.run_until_complete(main()) + def test_drain_raises(self): # See http://bugs.python.org/issue25441 diff --git a/Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst b/Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst new file mode 100644 index 000000000000..33782598745b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-09-08-55-04.gh-issue-74116.0XwYC1.rst @@ -0,0 +1 @@ +Allow :meth:`asyncio.StreamWriter.drain` to be awaited concurrently by multiple tasks. Patch by Kumar Aditya. From webhook-mailer at python.org Tue Aug 30 07:10:04 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 30 Aug 2022 11:10:04 -0000 Subject: [Python-checkins] Docs: Improve clarity for bytes.hex() (#95257) Message-ID: <mailman.907.1661857805.3313.python-checkins@python.org> https://github.com/python/cpython/commit/860fa351452de1502da12ec6f027d3f72dfc309f commit: 860fa351452de1502da12ec6f027d3f72dfc309f branch: main author: Tim Burke <tim.burke at gmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-30T13:09:56+02:00 summary: Docs: Improve clarity for bytes.hex() (#95257) files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 2480e71dded..2c021866e29 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2548,9 +2548,10 @@ data and are closely related to string objects in a variety of other ways. If you want to make the hex string easier to read, you can specify a single character separator *sep* parameter to include in the output. - By default between each byte. A second optional *bytes_per_sep* - parameter controls the spacing. Positive values calculate the - separator position from the right, negative values from the left. + By default, this separator will be included between each byte. + A second optional *bytes_per_sep* parameter controls the spacing. + Positive values calculate the separator position from the right, + negative values from the left. >>> value = b'\xf0\xf1\xf2' >>> value.hex('-') From webhook-mailer at python.org Tue Aug 30 07:14:16 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 30 Aug 2022 11:14:16 -0000 Subject: [Python-checkins] gh-95413: Remove references to deprecated CGI library (#95414) Message-ID: <mailman.908.1661858058.3313.python-checkins@python.org> https://github.com/python/cpython/commit/b17aae8bbd13bec28b7ecbb5a147503f2e9cf365 commit: b17aae8bbd13bec28b7ecbb5a147503f2e9cf365 branch: main author: partev <petrosyan at gmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-30T13:14:08+02:00 summary: gh-95413: Remove references to deprecated CGI library (#95414) files: M Doc/faq/general.rst M Doc/tutorial/whatnow.rst diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 510ebb5cf904..6c7e4fc67c0a 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -113,8 +113,8 @@ to many different classes of problems. The language comes with a large standard library that covers areas such as string processing (regular expressions, Unicode, calculating differences between -files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI -programming), software engineering (unit testing, logging, profiling, parsing +files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP), +software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for :ref:`library-index` to get an idea of what's available. A wide variety of third-party extensions are also diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 5f7010cb12e9..dbe2d7fc0992 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -17,7 +17,7 @@ the set are: reference material about types, functions, and the modules in the standard library. The standard Python distribution includes a *lot* of additional code. There are modules to read Unix mailboxes, retrieve documents via HTTP, generate - random numbers, parse command-line options, write CGI programs, compress data, + random numbers, parse command-line options, compress data, and many other tasks. Skimming through the Library Reference will give you an idea of what's available. From webhook-mailer at python.org Tue Aug 30 07:16:41 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 11:16:41 -0000 Subject: [Python-checkins] Docs: Improve clarity for bytes.hex() (GH-95257) Message-ID: <mailman.909.1661858202.3313.python-checkins@python.org> https://github.com/python/cpython/commit/9389e2f08c9fcd998fc758a32d6e554a407bbc7c commit: 9389e2f08c9fcd998fc758a32d6e554a407bbc7c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T04:16:34-07:00 summary: Docs: Improve clarity for bytes.hex() (GH-95257) (cherry picked from commit 860fa351452de1502da12ec6f027d3f72dfc309f) Co-authored-by: Tim Burke <tim.burke at gmail.com> files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 5c0d259ba98..529dae871d3 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2508,9 +2508,10 @@ data and are closely related to string objects in a variety of other ways. If you want to make the hex string easier to read, you can specify a single character separator *sep* parameter to include in the output. - By default between each byte. A second optional *bytes_per_sep* - parameter controls the spacing. Positive values calculate the - separator position from the right, negative values from the left. + By default, this separator will be included between each byte. + A second optional *bytes_per_sep* parameter controls the spacing. + Positive values calculate the separator position from the right, + negative values from the left. >>> value = b'\xf0\xf1\xf2' >>> value.hex('-') From webhook-mailer at python.org Tue Aug 30 07:18:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 11:18:36 -0000 Subject: [Python-checkins] Docs: Improve clarity for bytes.hex() (GH-95257) Message-ID: <mailman.910.1661858317.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d9d0d097a298132773e72a5a0a25eec19645140e commit: d9d0d097a298132773e72a5a0a25eec19645140e branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T04:18:30-07:00 summary: Docs: Improve clarity for bytes.hex() (GH-95257) (cherry picked from commit 860fa351452de1502da12ec6f027d3f72dfc309f) Co-authored-by: Tim Burke <tim.burke at gmail.com> files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 2480e71dded..2c021866e29 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2548,9 +2548,10 @@ data and are closely related to string objects in a variety of other ways. If you want to make the hex string easier to read, you can specify a single character separator *sep* parameter to include in the output. - By default between each byte. A second optional *bytes_per_sep* - parameter controls the spacing. Positive values calculate the - separator position from the right, negative values from the left. + By default, this separator will be included between each byte. + A second optional *bytes_per_sep* parameter controls the spacing. + Positive values calculate the separator position from the right, + negative values from the left. >>> value = b'\xf0\xf1\xf2' >>> value.hex('-') From webhook-mailer at python.org Tue Aug 30 07:22:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 11:22:36 -0000 Subject: [Python-checkins] gh-95413: Remove references to deprecated CGI library (GH-95414) Message-ID: <mailman.911.1661858556.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a1671a97d35dcec1df2152150fb0790b74d84729 commit: a1671a97d35dcec1df2152150fb0790b74d84729 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T04:22:19-07:00 summary: gh-95413: Remove references to deprecated CGI library (GH-95414) (cherry picked from commit b17aae8bbd13bec28b7ecbb5a147503f2e9cf365) Co-authored-by: partev <petrosyan at gmail.com> files: M Doc/faq/general.rst M Doc/tutorial/whatnow.rst diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 510ebb5cf904..6c7e4fc67c0a 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -113,8 +113,8 @@ to many different classes of problems. The language comes with a large standard library that covers areas such as string processing (regular expressions, Unicode, calculating differences between -files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI -programming), software engineering (unit testing, logging, profiling, parsing +files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP), +software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for :ref:`library-index` to get an idea of what's available. A wide variety of third-party extensions are also diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 5f7010cb12e9..dbe2d7fc0992 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -17,7 +17,7 @@ the set are: reference material about types, functions, and the modules in the standard library. The standard Python distribution includes a *lot* of additional code. There are modules to read Unix mailboxes, retrieve documents via HTTP, generate - random numbers, parse command-line options, write CGI programs, compress data, + random numbers, parse command-line options, compress data, and many other tasks. Skimming through the Library Reference will give you an idea of what's available. From webhook-mailer at python.org Tue Aug 30 08:10:11 2022 From: webhook-mailer at python.org (corona10) Date: Tue, 30 Aug 2022 12:10:11 -0000 Subject: [Python-checkins] gh-96349: fix minor performance regression initializing threading.Event (gh-96350) Message-ID: <mailman.912.1661861411.3313.python-checkins@python.org> https://github.com/python/cpython/commit/22ed5233b76fe33f9767c6a5665608e7f398e7d7 commit: 22ed5233b76fe33f9767c6a5665608e7f398e7d7 branch: main author: Daniel Giger <danielg1111 at verizon.net> committer: corona10 <donghee.na92 at gmail.com> date: 2022-08-30T21:10:02+09:00 summary: gh-96349: fix minor performance regression initializing threading.Event (gh-96350) files: A Misc/NEWS.d/next/Library/2022-08-27-21-26-52.gh-issue-96349.XyYLlO.rst M Lib/threading.py diff --git a/Lib/threading.py b/Lib/threading.py index 7237a149ecc..d030e124362 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -262,18 +262,12 @@ def __init__(self, lock=None): # If the lock defines _release_save() and/or _acquire_restore(), # these override the default implementations (which just call # release() and acquire() on the lock). Ditto for _is_owned(). - try: + if hasattr(lock, '_release_save'): self._release_save = lock._release_save - except AttributeError: - pass - try: + if hasattr(lock, '_acquire_restore'): self._acquire_restore = lock._acquire_restore - except AttributeError: - pass - try: + if hasattr(lock, '_is_owned'): self._is_owned = lock._is_owned - except AttributeError: - pass self._waiters = _deque() def _at_fork_reinit(self): diff --git a/Misc/NEWS.d/next/Library/2022-08-27-21-26-52.gh-issue-96349.XyYLlO.rst b/Misc/NEWS.d/next/Library/2022-08-27-21-26-52.gh-issue-96349.XyYLlO.rst new file mode 100644 index 00000000000..59eb3517191 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-27-21-26-52.gh-issue-96349.XyYLlO.rst @@ -0,0 +1 @@ +Fixed a minor performance regression in :func:`threading.Event.__init__` From webhook-mailer at python.org Tue Aug 30 10:57:37 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 30 Aug 2022 14:57:37 -0000 Subject: [Python-checkins] gh-95337: update TypeVarTuple example (#95338) Message-ID: <mailman.913.1661871458.3313.python-checkins@python.org> https://github.com/python/cpython/commit/07f12b5c1567581aa77d523e462b0e7f75c1f05c commit: 07f12b5c1567581aa77d523e462b0e7f75c1f05c branch: main author: Adrian Garcia Badaracco <1755071+adriangb at users.noreply.github.com> committer: JelleZijlstra <jelle.zijlstra at gmail.com> date: 2022-08-30T07:57:03-07:00 summary: gh-95337: update TypeVarTuple example (#95338) Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index c6dd6976f23..0939973cf24 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1305,20 +1305,25 @@ These are not used in annotations. They are building blocks for creating generic T = TypeVar('T') Ts = TypeVarTuple('Ts') - def remove_first_element(tup: tuple[T, *Ts]) -> tuple[*Ts]: - return tup[1:] + def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: + return (*tup[1:], tup[0]) # T is bound to int, Ts is bound to () - # Return value is (), which has type tuple[()] - remove_first_element(tup=(1,)) + # Return value is (1,), which has type tuple[int] + move_first_element_to_last(tup=(1,)) # T is bound to int, Ts is bound to (str,) - # Return value is ('spam',), which has type tuple[str] - remove_first_element(tup=(1, 'spam')) + # Return value is ('spam', 1), which has type tuple[str, int] + move_first_element_to_last(tup=(1, 'spam')) # T is bound to int, Ts is bound to (str, float) - # Return value is ('spam', 3.0), which has type tuple[str, float] - remove_first_element(tup=(1, 'spam', 3.0)) + # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] + move_first_element_to_last(tup=(1, 'spam', 3.0)) + + # This fails to type check (and fails at runtime) + # because tuple[()] is not compatible with tuple[T, *Ts] + # (at least one element is required) + move_first_element_to_last(tup=()) Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. Conceptually, you can think of ``Ts`` as a tuple of type variables From webhook-mailer at python.org Tue Aug 30 11:06:29 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 15:06:29 -0000 Subject: [Python-checkins] gh-95337: update TypeVarTuple example (GH-95338) Message-ID: <mailman.914.1661871991.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d00a9e0176e9a1e2dd213a137757da36e071bd81 commit: d00a9e0176e9a1e2dd213a137757da36e071bd81 branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T08:06:19-07:00 summary: gh-95337: update TypeVarTuple example (GH-95338) Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com> (cherry picked from commit 07f12b5c1567581aa77d523e462b0e7f75c1f05c) Co-authored-by: Adrian Garcia Badaracco <1755071+adriangb at users.noreply.github.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 0951916f080..76394066431 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1305,20 +1305,25 @@ These are not used in annotations. They are building blocks for creating generic T = TypeVar('T') Ts = TypeVarTuple('Ts') - def remove_first_element(tup: tuple[T, *Ts]) -> tuple[*Ts]: - return tup[1:] + def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: + return (*tup[1:], tup[0]) # T is bound to int, Ts is bound to () - # Return value is (), which has type tuple[()] - remove_first_element(tup=(1,)) + # Return value is (1,), which has type tuple[int] + move_first_element_to_last(tup=(1,)) # T is bound to int, Ts is bound to (str,) - # Return value is ('spam',), which has type tuple[str] - remove_first_element(tup=(1, 'spam')) + # Return value is ('spam', 1), which has type tuple[str, int] + move_first_element_to_last(tup=(1, 'spam')) # T is bound to int, Ts is bound to (str, float) - # Return value is ('spam', 3.0), which has type tuple[str, float] - remove_first_element(tup=(1, 'spam', 3.0)) + # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] + move_first_element_to_last(tup=(1, 'spam', 3.0)) + + # This fails to type check (and fails at runtime) + # because tuple[()] is not compatible with tuple[T, *Ts] + # (at least one element is required) + move_first_element_to_last(tup=()) Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. Conceptually, you can think of ``Ts`` as a tuple of type variables From webhook-mailer at python.org Tue Aug 30 11:26:21 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 30 Aug 2022 15:26:21 -0000 Subject: [Python-checkins] GH-95245: Document use of `MANAGED` flags instead of offsets. (GH-96044) Message-ID: <mailman.915.1661873182.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0f733fffe8f4caaac3ce1b5306af86b42fb0c7fa commit: 0f733fffe8f4caaac3ce1b5306af86b42fb0c7fa branch: main author: Mark Shannon <mark at hotpy.org> committer: markshannon <mark at hotpy.org> date: 2022-08-30T16:26:08+01:00 summary: GH-95245: Document use of `MANAGED` flags instead of offsets. (GH-96044) files: M Doc/c-api/structures.rst M Doc/c-api/type.rst M Doc/c-api/typeobj.rst M Doc/extending/newtypes.rst diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 86d4536f8d28..f1eb09bb5691 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -469,19 +469,21 @@ Accessing attributes of extension types .. _pymemberdef-offsets: Heap allocated types (created using :c:func:`PyType_FromSpec` or similar), - ``PyMemberDef`` may contain definitions for the special members - ``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``, - corresponding to - :c:member:`~PyTypeObject.tp_dictoffset`, - :c:member:`~PyTypeObject.tp_weaklistoffset` and + ``PyMemberDef`` may contain definitions for the special member + ``__vectorcalloffset__``, corresponding to :c:member:`~PyTypeObject.tp_vectorcall_offset` in type objects. These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example:: static PyMemberDef spam_type_members[] = { - {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY}, + {"__vectorcalloffset__", T_PYSSIZET, offsetof(Spam_object, vectorcall), READONLY}, {NULL} /* Sentinel */ }; + The legacy offsets :c:member:`~PyTypeObject.tp_dictoffset` and + :c:member:`~PyTypeObject.tp_weaklistoffset` are still supported, but extensions are + strongly encouraged to use ``Py_TPFLAGS_MANAGED_DICT`` and + ``Py_TPFLAGS_MANAGED_WEAKREF`` instead. + .. c:function:: PyObject* PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index aa77c285e3b8..deb5502a4dff 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -327,9 +327,9 @@ The following functions and structs are used to create * :c:member:`~PyTypeObject.tp_weaklist` * :c:member:`~PyTypeObject.tp_vectorcall` * :c:member:`~PyTypeObject.tp_weaklistoffset` - (see :ref:`PyMemberDef <pymemberdef-offsets>`) + (use :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead) * :c:member:`~PyTypeObject.tp_dictoffset` - (see :ref:`PyMemberDef <pymemberdef-offsets>`) + (use :const:`Py_TPFLAGS_MANAGED_DICT` instead) * :c:member:`~PyTypeObject.tp_vectorcall_offset` (see :ref:`PyMemberDef <pymemberdef-offsets>`) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 20cdffed110c..2439f7c41b56 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -96,7 +96,7 @@ Quick Reference | | | __gt__, | | | | | | | | __ge__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_weaklistoffset` | :c:type:`Py_ssize_t` | | | X | | ? | + | (:c:member:`~PyTypeObject.tp_weaklistoffset`) | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -117,7 +117,7 @@ Quick Reference | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | | | | __delete__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dictoffset` | :c:type:`Py_ssize_t` | | | X | | ? | + | (:c:member:`~PyTypeObject.tp_dictoffset`) | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -1018,7 +1018,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have ``NULL`` values. - .. XXX are most flag bits *really* inherited individually? **Default:** @@ -1135,6 +1134,33 @@ and :c:type:`PyType_Type` effectively act as defaults.) :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is inherited whenever :c:member:`~PyTypeObject.tp_descr_get` is inherited. + .. data:: Py_TPFLAGS_MANAGED_DICT + + This bit indicates that instances of the class have a ``__dict___`` + attribute, and that the space for the dictionary is managed by the VM. + + If this flag is set, :const:`Py_TPFLAGS_HAVE_GC` should also be set. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited unless the + :c:member:`~PyTypeObject.tp_dictoffset` field is set in a superclass. + + + .. data:: Py_TPFLAGS_MANAGED_WEAKREF + + This bit indicates that instances of the class should be weakly + referenceable. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited unless the + :c:member:`~PyTypeObject.tp_weaklistoffset` field is set in a superclass. + .. XXX Document more flags here? @@ -1487,6 +1513,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset + While this field is still supported, :const:`Py_TPFLAGS_MANAGED_WEAKREF` + should be used instead, if at all possible. + If the instances of this type are weakly referenceable, this field is greater 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 @@ -1497,6 +1526,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for weak references to the type object itself. + It is an error to set both the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + :c:member:`~PyTypeObject.tp_weaklist`. + **Inheritance:** This field is inherited by subtypes, but see the rules listed below. A subtype @@ -1504,19 +1536,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) reference list head than the base type. Since the list head is always found via :c:member:`~PyTypeObject.tp_weaklistoffset`, this should not be a problem. - When a type defined by a class statement has no :attr:`~object.__slots__` declaration, - and none of its base types are weakly referenceable, the type is made weakly - referenceable by adding a weak reference list head slot to the instance layout - and setting the :c:member:`~PyTypeObject.tp_weaklistoffset` of that slot's offset. - - When a type's :attr:`__slots__` declaration contains a slot named - :attr:`__weakref__`, that slot becomes the weak reference list head for - instances of the type, and the slot's offset is stored in the type's - :c:member:`~PyTypeObject.tp_weaklistoffset`. + **Default:** - When a type's :attr:`__slots__` declaration does not contain a slot named - :attr:`__weakref__`, the type inherits its :c:member:`~PyTypeObject.tp_weaklistoffset` from its - base type. + If the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit is set in the + :c:member:`~PyTypeObject.tp_dict` field, then + :c:member:`~PyTypeObject.tp_weaklistoffset` will be set to a negative value, + to indicate that it is unsafe to use this field. .. c:member:: getiterfunc PyTypeObject.tp_iter @@ -1695,6 +1720,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_dictoffset + While this field is still supported, :const:`Py_TPFLAGS_MANAGED_DICT` should be + used instead, if at all possible. + If the instances of this type have a dictionary containing instance variables, this field is non-zero and contains the offset in the instances of the type of the instance variable dictionary; this offset is used by @@ -1703,17 +1731,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) Do not confuse this field with :c:member:`~PyTypeObject.tp_dict`; that is the dictionary for attributes of the type object itself. - If the value of this field is greater than zero, it specifies the offset from - the start of the instance structure. If the value is less than zero, it - specifies the offset from the *end* of the instance structure. A negative - offset is more expensive to use, and should only be used when the instance - structure contains a variable-length part. This is used for example to add an - instance variable dictionary to subtypes of :class:`str` or :class:`tuple`. Note - that the :c:member:`~PyTypeObject.tp_basicsize` field should account for the dictionary added to - the end in that case, even though the dictionary is not included in the basic - object layout. On a system with a pointer size of 4 bytes, - :c:member:`~PyTypeObject.tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is - at the very end of the structure. + The value specifies the offset of the dictionary from the start of the instance structure. The :c:member:`~PyTypeObject.tp_dictoffset` should be regarded as write-only. To get the pointer to the dictionary call :c:func:`PyObject_GenericGetDict`. @@ -1721,30 +1739,26 @@ and :c:type:`PyType_Type` effectively act as defaults.) dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr` when accessing an attribute on the object. - **Inheritance:** - - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype instances store the - dictionary at a difference offset than the base type. Since the dictionary is - always found via :c:member:`~PyTypeObject.tp_dictoffset`, this should not be a problem. + It is an error to set both the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + :c:member:`~PyTypeObject.tp_dictoffset`. - When a type defined by a class statement has no :attr:`~object.__slots__` declaration, - and none of its base types has an instance variable dictionary, a dictionary - slot is added to the instance layout and the :c:member:`~PyTypeObject.tp_dictoffset` is set to - that slot's offset. - - When a type defined by a class statement has a :attr:`__slots__` declaration, - the type inherits its :c:member:`~PyTypeObject.tp_dictoffset` from its base type. + **Inheritance:** - (Adding a slot named :attr:`~object.__dict__` to the :attr:`__slots__` declaration does - not have the expected effect, it just causes confusion. Maybe this should be - added as a feature just like :attr:`__weakref__` though.) + This field is inherited by subtypes. A subtype should not override this offset; + doing so could be unsafe, if C code tries to access the dictionary at the + previous offset. + To properly support inheritance, use :const:`Py_TPFLAGS_MANAGED_DICT`. **Default:** This slot has no default. For :ref:`static types <static-types>`, if the field is ``NULL`` then no :attr:`__dict__` gets created for instances. + If the :const:`Py_TPFLAGS_MANAGED_DICT` bit is set in the + :c:member:`~PyTypeObject.tp_dict` field, then + :c:member:`~PyTypeObject.tp_dictoffset` will be set to ``-1``, to indicate + that it is unsafe to use this field. + .. c:member:: initproc PyTypeObject.tp_init @@ -2663,8 +2677,6 @@ A type that supports weakrefs, instance dicts, and hashing:: typedef struct { PyObject_HEAD const char *data; - PyObject *inst_dict; - PyObject *weakreflist; } MyObject; static PyTypeObject MyObject_Type = { @@ -2672,9 +2684,9 @@ A type that supports weakrefs, instance dicts, and hashing:: .tp_name = "mymod.MyObject", .tp_basicsize = sizeof(MyObject), .tp_doc = PyDoc_STR("My objects"), - .tp_weaklistoffset = offsetof(MyObject, weakreflist), - .tp_dictoffset = offsetof(MyObject, inst_dict), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT | + Py_TPFLAGS_MANAGED_WEAKREF, .tp_new = myobj_new, .tp_traverse = (traverseproc)myobj_traverse, .tp_clear = (inquiry)myobj_clear, diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index c7c434e58bf0..b797dc2817c8 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -570,43 +570,28 @@ performance-critical objects (such as numbers). .. seealso:: Documentation for the :mod:`weakref` module. -For an object to be weakly referencable, the extension type must do two things: +For an object to be weakly referencable, the extension type must set the +``Py_TPFLAGS_MANAGED_WEAKREF`` bit of the :c:member:`~PyTypeObject.tp_flags` +field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should +be left as zero. -#. Include a :c:type:`PyObject\*` field in the C object structure dedicated to - the weak reference mechanism. The object's constructor should leave it - ``NULL`` (which is automatic when using the default - :c:member:`~PyTypeObject.tp_alloc`). - -#. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member - to the offset of the aforementioned field in the C object structure, - so that the interpreter knows how to access and modify that field. - -Concretely, here is how a trivial object structure would be augmented -with the required field:: - - typedef struct { - PyObject_HEAD - PyObject *weakreflist; /* List of weak references */ - } TrivialObject; - -And the corresponding member in the statically declared type object:: +Concretely, here is how the statically declared type object would look:: static PyTypeObject TrivialType = { PyVarObject_HEAD_INIT(NULL, 0) /* ... other members omitted for brevity ... */ - .tp_weaklistoffset = offsetof(TrivialObject, weakreflist), + .tp_flags = Py_TPFLAGS_MANAGED_WEAKREF | ..., }; + The only further addition is that ``tp_dealloc`` needs to clear any weak -references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is -non-``NULL``:: +references (by calling :c:func:`PyObject_ClearWeakRefs`):: static void Trivial_dealloc(TrivialObject *self) { /* Clear weakrefs first before calling any destructors */ - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); + PyObject_ClearWeakRefs((PyObject *) self); /* ... remainder of destruction code omitted for brevity ... */ Py_TYPE(self)->tp_free((PyObject *) self); } From webhook-mailer at python.org Tue Aug 30 13:11:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 17:11:31 -0000 Subject: [Python-checkins] gh-96143: Allow Linux perf profiler to see Python calls (GH-96123) Message-ID: <mailman.916.1661879491.3313.python-checkins@python.org> https://github.com/python/cpython/commit/6d791a97364b68d5f9c3514a0470aac487fc538d commit: 6d791a97364b68d5f9c3514a0470aac487fc538d branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T10:11:18-07:00 summary: gh-96143: Allow Linux perf profiler to see Python calls (GH-96123) :warning: :warning: Note for reviewers, hackers and fellow systems/low-level/compiler engineers :warning: :warning: If you have a lot of experience with this kind of shenanigans and want to improve the **first** version, **please make a PR against my branch** or **reach out by email** or **suggest code changes directly on GitHub**. If you have any **refinements or optimizations** please, wait until the first version is merged before starting hacking or proposing those so we can keep this PR productive. files: A Doc/howto/perf_profiling.rst A Lib/test/test_perf_profiler.py A Misc/NEWS.d/next/Core and Builtins/2022-08-20-18-36-40.gh-issue-96143.nh3GFM.rst A Objects/asm_trampoline.S A Objects/perf_trampoline.c M Doc/c-api/init_config.rst M Doc/howto/index.rst M Doc/using/cmdline.rst M Include/cpython/initconfig.h M Include/internal/pycore_ceval.h M Lib/test/test_embed.py M Makefile.pre.in M Modules/posixmodule.c M PCbuild/_freeze_module.vcxproj M PCbuild/_freeze_module.vcxproj.filters M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters M Python/clinic/sysmodule.c.h M Python/initconfig.c M Python/pylifecycle.c M Python/sysmodule.c M configure M configure.ac M pyconfig.h.in diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 2074ec4e0e8e..c4a342ee811c 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -1155,6 +1155,20 @@ PyConfig Default: ``-1`` in Python mode, ``0`` in isolated mode. + .. c:member:: int perf_profiling + + Enable compatibility mode with the perf profiler? + + If non-zero, initialize the perf trampoline. See :ref:`perf_profiling` + for more information. + + Set by :option:`-X perf <-X>` command line option and by the + :envvar:`PYTHONPERFSUPPORT` environment variable. + + Default: ``-1``. + + .. versionadded:: 3.12 + .. c:member:: int use_environment Use :ref:`environment variables <using-on-envvars>`? diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst index 8a378e6659ef..f521276a5a83 100644 --- a/Doc/howto/index.rst +++ b/Doc/howto/index.rst @@ -30,6 +30,7 @@ Currently, the HOWTOs are: ipaddress.rst clinic.rst instrumentation.rst + perf_profiling.rst annotations.rst isolating-extensions.rst diff --git a/Doc/howto/perf_profiling.rst b/Doc/howto/perf_profiling.rst new file mode 100644 index 000000000000..2e1bb48af8c8 --- /dev/null +++ b/Doc/howto/perf_profiling.rst @@ -0,0 +1,200 @@ +.. highlight:: shell-session + +.. _perf_profiling: + +============================================== +Python support for the Linux ``perf`` profiler +============================================== + +:author: Pablo Galindo + +The Linux ``perf`` profiler is a very powerful tool that allows you to profile and +obtain information about the performance of your application. ``perf`` also has +a very vibrant ecosystem of tools that aid with the analysis of the data that it +produces. + +The main problem with using the ``perf`` profiler with Python applications is that +``perf`` only allows to get information about native symbols, this is, the names of +the functions and procedures written in C. This means that the names and file names +of the Python functions in your code will not appear in the output of the ``perf``. + +Since Python 3.12, the interpreter can run in a special mode that allows Python +functions to appear in the output of the ``perf`` profiler. When this mode is +enabled, the interpreter will interpose a small piece of code compiled on the +fly before the execution of every Python function and it will teach ``perf`` the +relationship between this piece of code and the associated Python function using +`perf map files`_. + +.. warning:: + + Support for the ``perf`` profiler is only currently available for Linux on + selected architectures. Check the output of the configure build step or + check the output of ``python -m sysconfig | grep HAVE_PERF_TRAMPOLINE`` + to see if your system is supported. + +For example, consider the following script: + +.. code-block:: python + + def foo(n): + result = 0 + for _ in range(n): + result += 1 + return result + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + if __name__ == "__main__": + baz(1000000) + +We can run perf to sample CPU stack traces at 9999 Hertz: + + $ perf record -F 9999 -g -o perf.data python my_script.py + +Then we can use perf report to analyze the data: + +.. code-block:: shell-session + + $ perf report --stdio -n -g + + # Children Self Samples Command Shared Object Symbol + # ........ ........ ............ .......... .................. .......................................... + # + 91.08% 0.00% 0 python.exe python.exe [.] _start + | + ---_start + | + --90.71%--__libc_start_main + Py_BytesMain + | + |--56.88%--pymain_run_python.constprop.0 + | | + | |--56.13%--_PyRun_AnyFileObject + | | _PyRun_SimpleFileObject + | | | + | | |--55.02%--run_mod + | | | | + | | | --54.65%--PyEval_EvalCode + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | | + | | | |--51.67%--_PyEval_EvalFrameDefault + | | | | | + | | | | |--11.52%--_PyLong_Add + | | | | | | + | | | | | |--2.97%--_PyObject_Malloc + ... + +As you can see here, the Python functions are not shown in the output, only ``_Py_Eval_EvalFrameDefault`` appears +(the function that evaluates the Python bytecode) shows up. Unfortunately that's not very useful because all Python +functions use the same C function to evaluate bytecode so we cannot know which Python function corresponds to which +bytecode-evaluating function. + +Instead, if we run the same experiment with perf support activated we get: + +.. code-block:: shell-session + + $ perf report --stdio -n -g + + # Children Self Samples Command Shared Object Symbol + # ........ ........ ............ .......... .................. ..................................................................... + # + 90.58% 0.36% 1 python.exe python.exe [.] _start + | + ---_start + | + --89.86%--__libc_start_main + Py_BytesMain + | + |--55.43%--pymain_run_python.constprop.0 + | | + | |--54.71%--_PyRun_AnyFileObject + | | _PyRun_SimpleFileObject + | | | + | | |--53.62%--run_mod + | | | | + | | | --53.26%--PyEval_EvalCode + | | | py::<module>:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::baz:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::bar:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::foo:/src/script.py + | | | | + | | | |--51.81%--_PyEval_EvalFrameDefault + | | | | | + | | | | |--13.77%--_PyLong_Add + | | | | | | + | | | | | |--3.26%--_PyObject_Malloc + + + +Enabling perf profiling mode +---------------------------- + +There are two main ways to activate the perf profiling mode. If you want it to be +active since the start of the Python interpreter, you can use the `-Xperf` option: + + $ python -Xperf my_script.py + +There is also support for dynamically activating and deactivating the perf +profiling mode by using the APIs in the :mod:`sys` module: + +.. code-block:: python + + import sys + sys.activate_stack_trampoline("perf") + + # Run some code with Perf profiling active + + sys.deactivate_stack_trampoline() + + # Perf profiling is not active anymore + +These APIs can be handy if you want to activate/deactivate profiling mode in +response to a signal or other communication mechanism with your process. + + + +Now we can analyze the data with ``perf report``: + + $ perf report -g -i perf.data + + +How to obtain the best results +------------------------------- + +For the best results, Python should be compiled with +``CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"`` as this allows +profilers to unwind using only the frame pointer and not on DWARF debug +information. This is because as the code that is interposed to allow perf +support is dynamically generated it doesn't have any DWARF debugging information +available. + +You can check if you system has been compiled with this flag by running: + + $ python -m sysconfig | grep 'no-omit-frame-pointer' + +If you don't see any output it means that your interpreter has not been compiled with +frame pointers and therefore it may not be able to show Python functions in the output +of ``perf``. + +.. _perf map files: https://github.com/torvalds/linux/blob/0513e464f9007b70b96740271a948ca5ab6e7dd7/tools/perf/Documentation/jit-interface.txt diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 6678d476fa83..5ecc882d818f 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -535,6 +535,12 @@ Miscellaneous options development (running from the source tree) then the default is "off". Note that the "importlib_bootstrap" and "importlib_bootstrap_external" frozen modules are always used, even if this flag is set to "off". + * ``-X perf`` to activate compatibility mode with the ``perf`` profiler. + When this option is activated, the Linux ``perf`` profiler will be able to + report Python calls. This option is only available on some platforms and + will do nothing if is not supported on the current system. The default value + is "off". See also :envvar:`PYTHONPERFSUPPORT` and :ref:`perf_profiling` + for more information. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -1025,6 +1031,13 @@ conflict. .. versionadded:: 3.11 +.. envvar:: PYTHONPERFSUPPORT + + If this variable is set to a nonzero value, it activates compatibility mode + with the ``perf`` profiler so Python calls can be detected by it. See the + :ref:`perf_profiling` section for more information. + + .. versionadded:: 3.12 Debug-mode variables diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 3b6d59389f26..c6057a4c3ed9 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -142,6 +142,7 @@ typedef struct PyConfig { unsigned long hash_seed; int faulthandler; int tracemalloc; + int perf_profiling; int import_time; int code_debug_ranges; int show_ref_count; diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 2fcdaad358b0..4914948c6ca7 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -65,6 +65,27 @@ extern PyObject* _PyEval_BuiltinsFromGlobals( PyThreadState *tstate, PyObject *globals); +// Trampoline API + +typedef struct { + // Callback to initialize the trampoline state + void* (*init_state)(void); + // Callback to register every trampoline being created + void (*write_state)(void* state, const void *code_addr, + unsigned int code_size, PyCodeObject* code); + // Callback to free the trampoline state + int (*free_state)(void* state); +} _PyPerf_Callbacks; + +extern int _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *); +extern void _PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *); +extern int _PyPerfTrampoline_Init(int activate); +extern int _PyPerfTrampoline_Fini(void); +extern int _PyIsPerfTrampolineActive(void); +extern PyStatus _PyPerfTrampoline_AfterFork_Child(void); +#ifdef PY_HAVE_PERF_TRAMPOLINE +extern _PyPerf_Callbacks _Py_perfmap_callbacks; +#endif static inline PyObject* _PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index c546bb08e297..70d7367ea9e6 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -436,6 +436,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'hash_seed': 0, 'faulthandler': 0, 'tracemalloc': 0, + 'perf_profiling': 0, 'import_time': 0, 'code_debug_ranges': 1, 'show_ref_count': 0, @@ -520,6 +521,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): use_hash_seed=0, faulthandler=0, tracemalloc=0, + perf_profiling=0, pathconfig_warnings=0, ) if MS_WINDOWS: @@ -828,6 +830,7 @@ def test_init_from_config(self): 'use_hash_seed': 1, 'hash_seed': 123, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, 'code_debug_ranges': 0, 'show_ref_count': 1, @@ -890,6 +893,7 @@ def test_init_compat_env(self): 'use_hash_seed': 1, 'hash_seed': 42, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, 'code_debug_ranges': 0, 'malloc_stats': 1, @@ -921,6 +925,7 @@ def test_init_python_env(self): 'use_hash_seed': 1, 'hash_seed': 42, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, 'code_debug_ranges': 0, 'malloc_stats': 1, diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py new file mode 100644 index 000000000000..c2aad85b652e --- /dev/null +++ b/Lib/test/test_perf_profiler.py @@ -0,0 +1,348 @@ +import unittest +import subprocess +import sys +import sysconfig +import os +import pathlib +from test import support +from test.support.script_helper import ( + make_script, + assert_python_failure, + assert_python_ok, +) +from test.support.os_helper import temp_dir + + +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + +def supports_trampoline_profiling(): + perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") + if not perf_trampoline: + return False + return int(perf_trampoline) == 1 + + +if not supports_trampoline_profiling(): + raise unittest.SkipTest("perf trampoline profiling not supported") + + +class TestPerfTrampoline(unittest.TestCase): + def setUp(self): + super().setUp() + self.perf_files = set(pathlib.Path("/tmp/").glob("perf-*.map")) + + def tearDown(self) -> None: + super().tearDown() + files_to_delete = ( + set(pathlib.Path("/tmp/").glob("perf-*.map")) - self.perf_files + ) + for file in files_to_delete: + file.unlink() + + def test_trampoline_works(self): + code = """if 1: + def foo(): + pass + + def bar(): + foo() + + def baz(): + bar() + + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + universal_newlines=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(stderr, "") + self.assertEqual(stdout, "") + + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + self.assertTrue(perf_file.exists()) + perf_file_contents = perf_file.read_text() + self.assertIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + def test_trampoline_works_with_forks(self): + code = """if 1: + import os, sys + + def foo_fork(): + pass + + def bar_fork(): + foo_fork() + + def baz_fork(): + bar_fork() + + def foo(): + pid = os.fork() + if pid == 0: + print(os.getpid()) + baz_fork() + else: + _, status = os.waitpid(-1, 0) + sys.exit(status) + + def bar(): + foo() + + def baz(): + bar() + + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + universal_newlines=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(process.returncode, 0) + self.assertEqual(stderr, "") + child_pid = int(stdout.strip()) + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + perf_child_file = pathlib.Path(f"/tmp/perf-{child_pid}.map") + self.assertTrue(perf_file.exists()) + self.assertTrue(perf_child_file.exists()) + + perf_file_contents = perf_file.read_text() + self.assertIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + child_perf_file_contents = perf_child_file.read_text() + self.assertIn(f"py::foo_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::bar_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::baz_fork:{script}", child_perf_file_contents) + + def test_sys_api(self): + code = """if 1: + import sys + def foo(): + pass + + def spam(): + pass + + def bar(): + sys.deactivate_stack_trampoline() + foo() + sys.activate_stack_trampoline("perf") + spam() + + def baz(): + bar() + + sys.activate_stack_trampoline("perf") + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, script], + universal_newlines=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(stderr, "") + self.assertEqual(stdout, "") + + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + self.assertTrue(perf_file.exists()) + perf_file_contents = perf_file.read_text() + self.assertNotIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::spam:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + def test_sys_api_with_existing_trampoline(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("perf") + sys.activate_stack_trampoline("perf") + """ + assert_python_ok("-c", code) + + def test_sys_api_with_invalid_trampoline(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("invalid") + """ + rc, out, err = assert_python_failure("-c", code) + self.assertIn("invalid backend: invalid", err.decode()) + + def test_sys_api_get_status(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("perf") + assert sys.is_stack_trampoline_active() is True + sys.deactivate_stack_trampoline() + assert sys.is_stack_trampoline_active() is False + """ + assert_python_ok("-c", code) + + +def is_unwinding_reliable(): + cflags = sysconfig.get_config_var("PY_CORE_CFLAGS") + if not cflags: + return False + return "no-omit-frame-pointer" in cflags + + +def perf_command_works(): + try: + cmd = ["perf", "--help"] + stdout = subprocess.check_output(cmd, universal_newlines=True) + except (subprocess.SubprocessError, OSError): + return False + + # perf version does not return a version number on Fedora. Use presence + # of "perf.data" in help as indicator that it's perf from Linux tools. + if "perf.data" not in stdout: + return False + + # Check that we can run a simple perf run + with temp_dir() as script_dir: + try: + output_file = script_dir + "/perf_output.perf" + cmd = ( + "perf", + "record", + "-g", + "--call-graph=fp", + "-o", + output_file, + "--", + sys.executable, + "-c", + 'print("hello")', + ) + stdout = subprocess.check_output( + cmd, cwd=script_dir, universal_newlines=True, stderr=subprocess.STDOUT + ) + except (subprocess.SubprocessError, OSError): + return False + + if "hello" not in stdout: + return False + + return True + + +def run_perf(cwd, *args, **env_vars): + if env_vars: + env = os.environ.copy() + env.update(env_vars) + else: + env = None + output_file = cwd + "/perf_output.perf" + base_cmd = ("perf", "record", "-g", "--call-graph=fp", "-o", output_file, "--") + proc = subprocess.run( + base_cmd + args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + ) + if proc.returncode: + print(proc.stderr) + raise ValueError(f"Perf failed with return code {proc.returncode}") + + base_cmd = ("perf", "script") + proc = subprocess.run( + ("perf", "script", "-i", output_file), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + check=True, + ) + return proc.stdout.decode("utf-8", "replace"), proc.stderr.decode( + "utf-8", "replace" + ) + + + at unittest.skipUnless(perf_command_works(), "perf command doesn't work") + at unittest.skipUnless(is_unwinding_reliable(), "Unwinding is unreliable") + at support.skip_if_sanitizer(address=True, memory=True, ub=True) +class TestPerfProfiler(unittest.TestCase): + def setUp(self): + super().setUp() + self.perf_files = set(pathlib.Path("/tmp/").glob("perf-*.map")) + + def tearDown(self) -> None: + super().tearDown() + files_to_delete = ( + set(pathlib.Path("/tmp/").glob("perf-*.map")) - self.perf_files + ) + for file in files_to_delete: + file.unlink() + + def test_python_calls_appear_in_the_stack_if_perf_activated(self): + with temp_dir() as script_dir: + code = """if 1: + def foo(n): + x = 0 + for i in range(n): + x += i + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + """ + script = make_script(script_dir, "perftest", code) + stdout, stderr = run_perf(script_dir, sys.executable, "-Xperf", script) + self.assertEqual(stderr, "") + + self.assertIn(f"py::foo:{script}", stdout) + self.assertIn(f"py::bar:{script}", stdout) + self.assertIn(f"py::baz:{script}", stdout) + + def test_python_calls_do_not_appear_in_the_stack_if_perf_activated(self): + with temp_dir() as script_dir: + code = """if 1: + def foo(n): + x = 0 + for i in range(n): + x += i + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + """ + script = make_script(script_dir, "perftest", code) + stdout, stderr = run_perf(script_dir, sys.executable, script) + self.assertEqual(stderr, "") + + self.assertNotIn(f"py::foo:{script}", stdout) + self.assertNotIn(f"py::bar:{script}", stdout) + self.assertNotIn(f"py::baz:{script}", stdout) + + +if __name__ == "__main__": + unittest.main() diff --git a/Makefile.pre.in b/Makefile.pre.in index 94ddfa4b1bed..107a7075ebf6 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -478,7 +478,9 @@ OBJECT_OBJS= \ Objects/unicodeobject.o \ Objects/unicodectype.o \ Objects/unionobject.o \ - Objects/weakrefobject.o + Objects/weakrefobject.o \ + Objects/perf_trampoline.o \ + @PERF_TRAMPOLINE_OBJ@ DEEPFREEZE_OBJS = Python/deepfreeze/deepfreeze.o @@ -2358,6 +2360,9 @@ config.status: $(srcdir)/configure .PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre +Objects/asm_trampoline.o: $(srcdir)/Objects/asm_trampoline.S + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + # Some make's put the object file in the current directory .c.o: $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-20-18-36-40.gh-issue-96143.nh3GFM.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-20-18-36-40.gh-issue-96143.nh3GFM.rst new file mode 100644 index 000000000000..30f44fd453a5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-20-18-36-40.gh-issue-96143.nh3GFM.rst @@ -0,0 +1,7 @@ +Add a new ``-X perf`` Python command line option as well as +:func:`sys.activate_stack_trampoline` and :func:`sys.deactivate_stack_trampoline` +function in the :mod:`sys` module that allows to set/unset the interpreter in a +way that the Linux ``perf`` profiler can detect Python calls. The new +:func:`sys.is_stack_trampoline_active` function allows to query the state of the +perf trampoline. Design by Pablo Galindo. Patch by Pablo Galindo and Christian Heimes +with contributions from Gregory P. Smith [Google] and Mark Shannon. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d45fa231ae5e..3810bc87c1fb 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -606,6 +606,11 @@ PyOS_AfterFork_Child(void) } assert(_PyThreadState_GET() == tstate); + status = _PyPerfTrampoline_AfterFork_Child(); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + run_at_forkers(tstate->interp->after_forkers_child, 0); return; diff --git a/Objects/asm_trampoline.S b/Objects/asm_trampoline.S new file mode 100644 index 000000000000..460707717df0 --- /dev/null +++ b/Objects/asm_trampoline.S @@ -0,0 +1,28 @@ + .text + .globl _Py_trampoline_func_start +# The following assembly is equivalent to: +# PyObject * +# trampoline(PyThreadState *ts, _PyInterpreterFrame *f, +# int throwflag, py_evaluator evaluator) +# { +# return evaluator(ts, f, throwflag); +# } +_Py_trampoline_func_start: +#ifdef __x86_64__ + sub $8, %rsp + call *%rcx + add $8, %rsp + ret +#endif // __x86_64__ +#if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__) + // ARM64 little endian, 64bit ABI + // generate with aarch64-linux-gnu-gcc 12.1 + stp x29, x30, [sp, -16]! + mov x29, sp + blr x3 + ldp x29, x30, [sp], 16 + ret +#endif + .globl _Py_trampoline_func_end +_Py_trampoline_func_end: + .section .note.GNU-stack,"", at progbits diff --git a/Objects/perf_trampoline.c b/Objects/perf_trampoline.c new file mode 100644 index 000000000000..02206b2786c8 --- /dev/null +++ b/Objects/perf_trampoline.c @@ -0,0 +1,501 @@ +/* + +Perf trampoline instrumentation +=============================== + +This file contains instrumentation to allow to associate +calls to the CPython eval loop back to the names of the Python +functions and filename being executed. + +Many native performance profilers like the Linux perf tools are +only available to 'see' the C stack when sampling from the profiled +process. This means that if we have the following python code: + + import time + def foo(n): + # Some CPU intensive code + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + +A performance profiler that is only able to see native frames will +produce the following backtrace when sampling from foo(): + + _PyEval_EvalFrameDefault -----> Evaluation frame of foo() + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault ------> Evaluation frame of bar() + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault -------> Evaluation frame of baz() + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + ... + + Py_RunMain + +Because the profiler is only able to see the native frames and the native +function that runs the evaluation loop is the same (_PyEval_EvalFrameDefault) +then the profiler and any reporter generated by it will not be able to +associate the names of the Python functions and the filenames associated with +those calls, rendering the results useless in the Python world. + +To fix this problem, we introduce the concept of a trampoline frame. A +trampoline frame is a piece of code that is unique per Python code object that +is executed before entering the CPython eval loop. This piece of code just +calls the original Python evaluation function (_PyEval_EvalFrameDefault) and +forwards all the arguments received. In this way, when a profiler samples +frames from the previous example it will see; + + _PyEval_EvalFrameDefault -----> Evaluation frame of foo() + [Jit compiled code 3] + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault ------> Evaluation frame of bar() + [Jit compiled code 2] + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault -------> Evaluation frame of baz() + [Jit compiled code 1] + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + ... + + Py_RunMain + +When we generate every unique copy of the trampoline (what here we called "[Jit +compiled code N]") we write the relationship between the compiled code and the +Python function that is associated with it. Every profiler requires this +information in a different format. For example, the Linux "perf" profiler +requires a file in "/tmp/perf-PID.map" (name and location not configurable) +with the following format: + + <compiled code address> <compiled code size> <name of the compiled code> + +If this file is available when "perf" generates reports, it will automatically +associate every trampoline with the Python function that it is associated with +allowing it to generate reports that include Python information. These reports +then can also be filtered in a way that *only* Python information appears. + +Notice that for this to work, there must be a unique copied of the trampoline +per Python code object even if the code in the trampoline is the same. To +achieve this we have a assembly template in Objects/asm_trampiline.S that is +compiled into the Python executable/shared library. This template generates a +symbol that maps the start of the assembly code and another that marks the end +of the assembly code for the trampoline. Then, every time we need a unique +trampoline for a Python code object, we copy the assembly code into a mmaped +area that has executable permissions and we return the start of that area as +our trampoline function. + +Asking for a mmap-ed memory area for trampoline is very wasteful so we +allocate big arenas of memory in a single mmap call, we populate the entire +arena with copies of the trampoline (this allows us to now have to invalidate +the icache for the instructions in the page) and then we return the next +available chunk every time someone asks for a new trampoline. We keep a linked +list of arenas in case the current memory arena is exhausted and another one is +needed. + +For the best results, Python should be compiled with +CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" as this allows +profilers to unwind using only the frame pointer and not on DWARF debug +information (note that as trampilines are dynamically generated there won't be +any DWARF information available for them). +*/ + +#include "Python.h" +#include "pycore_ceval.h" +#include "pycore_frame.h" +#include "pycore_interp.h" + +typedef enum { + PERF_STATUS_FAILED = -1, // Perf trampoline is in an invalid state + PERF_STATUS_NO_INIT = 0, // Perf trampoline is not initialized + PERF_STATUS_OK = 1, // Perf trampoline is ready to be executed +} perf_status_t; + +#ifdef PY_HAVE_PERF_TRAMPOLINE + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> + +/* The function pointer is passed as last argument. The other three arguments + * are passed in the same order as the function requires. This results in + * shorter, more efficient ASM code for trampoline. + */ +typedef PyObject *(*py_evaluator)(PyThreadState *, _PyInterpreterFrame *, + int throwflag); +typedef PyObject *(*py_trampoline)(PyThreadState *, _PyInterpreterFrame *, int, + py_evaluator); + +extern void *_Py_trampoline_func_start; // Start of the template of the + // assembly trampoline +extern void * + _Py_trampoline_func_end; // End of the template of the assembly trampoline + +struct code_arena_st { + char *start_addr; // Start of the memory arena + char *current_addr; // Address of the current trampoline within the arena + size_t size; // Size of the memory arena + size_t size_left; // Remaining size of the memory arena + size_t code_size; // Size of the code of every trampoline in the arena + struct code_arena_st + *prev; // Pointer to the arena or NULL if this is the first arena. +}; + +typedef struct code_arena_st code_arena_t; + +struct trampoline_api_st { + void* (*init_state)(void); + void (*write_state)(void* state, const void *code_addr, + unsigned int code_size, PyCodeObject* code); + int (*free_state)(void* state); + void *state; +}; + +typedef struct trampoline_api_st trampoline_api_t; + +static perf_status_t perf_status = PERF_STATUS_NO_INIT; +static Py_ssize_t extra_code_index = -1; +static code_arena_t *code_arena; +static trampoline_api_t trampoline_api; + +static FILE *perf_map_file; + +static void * +perf_map_get_file(void) +{ + if (perf_map_file) { + return perf_map_file; + } + char filename[100]; + pid_t pid = getpid(); + // Location and file name of perf map is hard-coded in perf tool. + // Use exclusive create flag wit nofollow to prevent symlink attacks. + int flags = O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC; + snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map", + (intmax_t)pid); + int fd = open(filename, flags, 0600); + if (fd == -1) { + perf_status = PERF_STATUS_FAILED; + PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); + return NULL; + } + perf_map_file = fdopen(fd, "w"); + if (!perf_map_file) { + perf_status = PERF_STATUS_FAILED; + PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); + close(fd); + return NULL; + } + return perf_map_file; +} + +static int +perf_map_close(void *state) +{ + FILE *fp = (FILE *)state; + int ret = 0; + if (fp) { + ret = fclose(fp); + } + perf_map_file = NULL; + perf_status = PERF_STATUS_NO_INIT; + return ret; +} + +static void +perf_map_write_entry(void *state, const void *code_addr, + unsigned int code_size, PyCodeObject *co) +{ + assert(state != NULL); + FILE *method_file = (FILE *)state; + const char *entry = PyUnicode_AsUTF8(co->co_qualname); + if (entry == NULL) { + _PyErr_WriteUnraisableMsg("Failed to get qualname from code object", + NULL); + return; + } + const char *filename = PyUnicode_AsUTF8(co->co_filename); + if (filename == NULL) { + _PyErr_WriteUnraisableMsg("Failed to get filename from code object", + NULL); + return; + } + fprintf(method_file, "%p %x py::%s:%s\n", code_addr, code_size, entry, + filename); + fflush(method_file); +} + +_PyPerf_Callbacks _Py_perfmap_callbacks = { + &perf_map_get_file, + &perf_map_write_entry, + &perf_map_close +}; + +static int +new_code_arena(void) +{ + // non-trivial programs typically need 64 to 256 kiB. + size_t mem_size = 4096 * 16; + assert(mem_size % sysconf(_SC_PAGESIZE) == 0); + char *memory = + mmap(NULL, // address + mem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, // fd (not used here) + 0); // offset (not used here) + if (!memory) { + PyErr_SetFromErrno(PyExc_OSError); + _PyErr_WriteUnraisableMsg( + "Failed to create new mmap for perf trampoline", NULL); + perf_status = PERF_STATUS_FAILED; + return -1; + } + void *start = &_Py_trampoline_func_start; + void *end = &_Py_trampoline_func_end; + size_t code_size = end - start; + + size_t n_copies = mem_size / code_size; + for (size_t i = 0; i < n_copies; i++) { + memcpy(memory + i * code_size, start, code_size * sizeof(char)); + } + // Some systems may prevent us from creating executable code on the fly. + int res = mprotect(memory, mem_size, PROT_READ | PROT_EXEC); + if (res == -1) { + PyErr_SetFromErrno(PyExc_OSError); + munmap(memory, mem_size); + _PyErr_WriteUnraisableMsg( + "Failed to set mmap for perf trampoline to PROT_READ | PROT_EXEC", + NULL); + return -1; + } + + code_arena_t *new_arena = PyMem_RawCalloc(1, sizeof(code_arena_t)); + if (new_arena == NULL) { + PyErr_NoMemory(); + munmap(memory, mem_size); + _PyErr_WriteUnraisableMsg("Failed to allocate new code arena struct", + NULL); + return -1; + } + + new_arena->start_addr = memory; + new_arena->current_addr = memory; + new_arena->size = mem_size; + new_arena->size_left = mem_size; + new_arena->code_size = code_size; + new_arena->prev = code_arena; + code_arena = new_arena; + return 0; +} + +static void +free_code_arenas(void) +{ + code_arena_t *cur = code_arena; + code_arena_t *prev; + code_arena = NULL; // invalid static pointer + while (cur) { + munmap(cur->start_addr, cur->size); + prev = cur->prev; + PyMem_RawFree(cur); + cur = prev; + } +} + +static inline py_trampoline +code_arena_new_code(code_arena_t *code_arena) +{ + py_trampoline trampoline = (py_trampoline)code_arena->current_addr; + code_arena->size_left -= code_arena->code_size; + code_arena->current_addr += code_arena->code_size; + return trampoline; +} + +static inline py_trampoline +compile_trampoline(void) +{ + if ((code_arena == NULL) || + (code_arena->size_left <= code_arena->code_size)) { + if (new_code_arena() < 0) { + return NULL; + } + } + assert(code_arena->size_left <= code_arena->size); + return code_arena_new_code(code_arena); +} + +static PyObject * +py_trampoline_evaluator(PyThreadState *ts, _PyInterpreterFrame *frame, + int throw) +{ + if (perf_status == PERF_STATUS_FAILED || + perf_status == PERF_STATUS_NO_INIT) { + goto default_eval; + } + PyCodeObject *co = frame->f_code; + py_trampoline f = NULL; + assert(extra_code_index != -1); + int ret = _PyCode_GetExtra((PyObject *)co, extra_code_index, (void **)&f); + if (ret != 0 || f == NULL) { + // This is the first time we see this code object so we need + // to compile a trampoline for it. + py_trampoline new_trampoline = compile_trampoline(); + if (new_trampoline == NULL) { + goto default_eval; + } + trampoline_api.write_state(trampoline_api.state, new_trampoline, + code_arena->code_size, co); + _PyCode_SetExtra((PyObject *)co, extra_code_index, + (void *)new_trampoline); + f = new_trampoline; + } + assert(f != NULL); + return f(ts, frame, throw, _PyEval_EvalFrameDefault); +default_eval: + // Something failed, fall back to the default evaluator. + return _PyEval_EvalFrameDefault(ts, frame, throw); +} +#endif // PY_HAVE_PERF_TRAMPOLINE + +int +_PyIsPerfTrampolineActive(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + return tstate->interp->eval_frame == py_trampoline_evaluator; +#endif + return 0; +} + +void +_PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *callbacks) +{ + if (callbacks == NULL) { + return; + } +#ifdef PY_HAVE_PERF_TRAMPOLINE + callbacks->init_state = trampoline_api.init_state; + callbacks->write_state = trampoline_api.write_state; + callbacks->free_state = trampoline_api.free_state; +#endif + return; +} + +int +_PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *callbacks) +{ + if (callbacks == NULL) { + return -1; + } +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (trampoline_api.state) { + _PyPerfTrampoline_Fini(); + } + trampoline_api.init_state = callbacks->init_state; + trampoline_api.write_state = callbacks->write_state; + trampoline_api.free_state = callbacks->free_state; + trampoline_api.state = NULL; + perf_status = PERF_STATUS_OK; +#endif + return 0; +} + +int +_PyPerfTrampoline_Init(int activate) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->interp->eval_frame && + tstate->interp->eval_frame != py_trampoline_evaluator) { + PyErr_SetString(PyExc_RuntimeError, + "Trampoline cannot be initialized as a custom eval " + "frame is already present"); + return -1; + } + if (!activate) { + tstate->interp->eval_frame = NULL; + } + else { + tstate->interp->eval_frame = py_trampoline_evaluator; + if (new_code_arena() < 0) { + return -1; + } + if (trampoline_api.state == NULL) { + void *state = trampoline_api.init_state(); + if (state == NULL) { + return -1; + } + trampoline_api.state = state; + } + extra_code_index = _PyEval_RequestCodeExtraIndex(NULL); + if (extra_code_index == -1) { + return -1; + } + perf_status = PERF_STATUS_OK; + } +#endif + return 0; +} + +int +_PyPerfTrampoline_Fini(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->interp->eval_frame == py_trampoline_evaluator) { + tstate->interp->eval_frame = NULL; + } + free_code_arenas(); + if (trampoline_api.state != NULL) { + trampoline_api.free_state(trampoline_api.state); + trampoline_api.state = NULL; + } + extra_code_index = -1; +#endif + return 0; +} + +PyStatus +_PyPerfTrampoline_AfterFork_Child(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + // Restart trampoline in file in child. + int was_active = _PyIsPerfTrampolineActive(); + _PyPerfTrampoline_Fini(); + if (was_active) { + _PyPerfTrampoline_Init(1); + } +#endif + return PyStatus_Ok(); +} diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 4c0072971123..0e446fe46eb0 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -129,6 +129,7 @@ <ClCompile Include="..\Objects\cellobject.c" /> <ClCompile Include="..\Objects\classobject.c" /> <ClCompile Include="..\Objects\codeobject.c" /> + <ClCompile Include="..\Objects\perf_trampoline.c" /> <ClCompile Include="..\Objects\complexobject.c" /> <ClCompile Include="..\Objects\descrobject.c" /> <ClCompile Include="..\Objects\dictobject.c" /> diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 5c984999c0cd..96ab2f2a4aac 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -85,6 +85,9 @@ <ClCompile Include="..\Objects\codeobject.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\Objects\perf_trampoline.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\Python\compile.c"> <Filter>Source Files</Filter> </ClCompile> diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 45e5013e61f6..ff17304032cd 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -429,6 +429,7 @@ <ClCompile Include="..\Objects\cellobject.c" /> <ClCompile Include="..\Objects\classobject.c" /> <ClCompile Include="..\Objects\codeobject.c" /> + <ClCompile Include="..\Objects\perf_trampoline.c" /> <ClCompile Include="..\Objects\complexobject.c" /> <ClCompile Include="..\Objects\descrobject.c" /> <ClCompile Include="..\Objects\dictobject.c" /> diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 581ea6e3c58e..7d7fe7267c8f 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -923,6 +923,9 @@ <ClCompile Include="..\Objects\codeobject.c"> <Filter>Objects</Filter> </ClCompile> + <ClCompile Include="..\Objects\perf_trampoline.c"> + <Filter>Objects</Filter> + </ClCompile> <ClCompile Include="..\Objects\complexobject.c"> <Filter>Objects</Filter> </ClCompile> diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 0f9636690a40..ddf01a7ccdda 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -1151,6 +1151,79 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(ANDROID_API_LEVEL) */ +PyDoc_STRVAR(sys_activate_stack_trampoline__doc__, +"activate_stack_trampoline($module, backend, /)\n" +"--\n" +"\n" +"Activate the perf profiler trampoline."); + +#define SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF \ + {"activate_stack_trampoline", (PyCFunction)sys_activate_stack_trampoline, METH_O, sys_activate_stack_trampoline__doc__}, + +static PyObject * +sys_activate_stack_trampoline_impl(PyObject *module, const char *backend); + +static PyObject * +sys_activate_stack_trampoline(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *backend; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("activate_stack_trampoline", "argument", "str", arg); + goto exit; + } + Py_ssize_t backend_length; + backend = PyUnicode_AsUTF8AndSize(arg, &backend_length); + if (backend == NULL) { + goto exit; + } + if (strlen(backend) != (size_t)backend_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = sys_activate_stack_trampoline_impl(module, backend); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_deactivate_stack_trampoline__doc__, +"deactivate_stack_trampoline($module, /)\n" +"--\n" +"\n" +"Dectivate the perf profiler trampoline."); + +#define SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF \ + {"deactivate_stack_trampoline", (PyCFunction)sys_deactivate_stack_trampoline, METH_NOARGS, sys_deactivate_stack_trampoline__doc__}, + +static PyObject * +sys_deactivate_stack_trampoline_impl(PyObject *module); + +static PyObject * +sys_deactivate_stack_trampoline(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_deactivate_stack_trampoline_impl(module); +} + +PyDoc_STRVAR(sys_is_stack_trampoline_active__doc__, +"is_stack_trampoline_active($module, /)\n" +"--\n" +"\n" +"Returns *True* if the perf profiler trampoline is active."); + +#define SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF \ + {"is_stack_trampoline_active", (PyCFunction)sys_is_stack_trampoline_active, METH_NOARGS, sys_is_stack_trampoline_active__doc__}, + +static PyObject * +sys_is_stack_trampoline_active_impl(PyObject *module); + +static PyObject * +sys_is_stack_trampoline_active(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_is_stack_trampoline_active_impl(module); +} + #ifndef SYS_GETWINDOWSVERSION_METHODDEF #define SYS_GETWINDOWSVERSION_METHODDEF #endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ @@ -1194,4 +1267,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=322fb0409e376ad4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=43b44240211afe95 input=a9049054013a1b77]*/ diff --git a/Python/initconfig.c b/Python/initconfig.c index 70f0363297f3..33a8f276b19c 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -118,6 +118,11 @@ The following implementation-specific options are available:\n\ files are desired as well as suppressing the extra visual location indicators \n\ when the interpreter displays tracebacks.\n\ \n\ +-X perf: activate support for the Linux \"perf\" profiler by activating the \"perf\"\n\ + trampoline. When this option is activated, the Linux \"perf\" profiler will be \n\ + able to report Python calls. This option is only available on some platforms and will \n\ + do nothing if is not supported on the current system. The default value is \"off\".\n\ +\n\ -X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\ The default is \"on\" (or \"off\" if you are running a local build)."; @@ -745,6 +750,7 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->use_hash_seed = -1; config->faulthandler = -1; config->tracemalloc = -1; + config->perf_profiling = -1; config->module_search_paths_set = 0; config->parse_argv = 0; config->site_import = -1; @@ -829,6 +835,7 @@ PyConfig_InitIsolatedConfig(PyConfig *config) config->use_hash_seed = 0; config->faulthandler = 0; config->tracemalloc = 0; + config->perf_profiling = 0; config->safe_path = 1; config->pathconfig_warnings = 0; #ifdef MS_WINDOWS @@ -940,6 +947,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(_install_importlib); COPY_ATTR(faulthandler); COPY_ATTR(tracemalloc); + COPY_ATTR(perf_profiling); COPY_ATTR(import_time); COPY_ATTR(code_debug_ranges); COPY_ATTR(show_ref_count); @@ -1050,6 +1058,7 @@ _PyConfig_AsDict(const PyConfig *config) SET_ITEM_UINT(hash_seed); SET_ITEM_INT(faulthandler); SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(perf_profiling); SET_ITEM_INT(import_time); SET_ITEM_INT(code_debug_ranges); SET_ITEM_INT(show_ref_count); @@ -1331,6 +1340,7 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED); GET_UINT(faulthandler); GET_UINT(tracemalloc); + GET_UINT(perf_profiling); GET_UINT(import_time); GET_UINT(code_debug_ranges); GET_UINT(show_ref_count); @@ -1687,6 +1697,26 @@ config_read_env_vars(PyConfig *config) return _PyStatus_OK(); } +static PyStatus +config_init_perf_profiling(PyConfig *config) +{ + int active = 0; + const char *env = config_get_env(config, "PYTHONPERFSUPPORT"); + if (env) { + if (_Py_str_to_int(env, &active) != 0) { + active = 0; + } + if (active) { + config->perf_profiling = 1; + } + } + const wchar_t *xoption = config_get_xoption(config, L"perf"); + if (xoption) { + config->perf_profiling = 1; + } + return _PyStatus_OK(); + +} static PyStatus config_init_tracemalloc(PyConfig *config) @@ -1788,6 +1818,12 @@ config_read_complex_options(PyConfig *config) return status; } } + if (config->perf_profiling < 0) { + status = config_init_perf_profiling(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } if (config->pycache_prefix == NULL) { status = config_init_pycache_prefix(config); @@ -2104,6 +2140,9 @@ config_read(PyConfig *config, int compute_path_config) if (config->tracemalloc < 0) { config->tracemalloc = 0; } + if (config->perf_profiling < 0) { + config->perf_profiling = 0; + } if (config->use_hash_seed < 0) { config->use_hash_seed = 0; config->hash_seed = 0; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index bb646f1a0ee2..8ce6d71651c1 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1149,6 +1149,16 @@ init_interp_main(PyThreadState *tstate) if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { return _PyStatus_ERR("can't initialize tracemalloc"); } + + +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (config->perf_profiling) { + if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 || + _PyPerfTrampoline_Init(config->perf_profiling) < 0) { + return _PyStatus_ERR("can't initialize the perf trampoline"); + } + } +#endif } status = init_sys_streams(tstate); @@ -1723,6 +1733,7 @@ finalize_interp_clear(PyThreadState *tstate) _PyArg_Fini(); _Py_ClearFileSystemEncoding(); _Py_Deepfreeze_Fini(); + _PyPerfTrampoline_Fini(); } finalize_interp_types(tstate->interp); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index c28643879416..75e64553d88c 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2053,6 +2053,80 @@ sys_getandroidapilevel_impl(PyObject *module) } #endif /* ANDROID_API_LEVEL */ +/*[clinic input] +sys.activate_stack_trampoline + + backend: str + / + +Activate the perf profiler trampoline. +[clinic start generated code]*/ + +static PyObject * +sys_activate_stack_trampoline_impl(PyObject *module, const char *backend) +/*[clinic end generated code: output=5783cdeb51874b43 input=b09020e3a17c78c5]*/ +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (strcmp(backend, "perf") == 0) { + _PyPerf_Callbacks cur_cb; + _PyPerfTrampoline_GetCallbacks(&cur_cb); + if (cur_cb.init_state != _Py_perfmap_callbacks.init_state) { + if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) { + PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline"); + return NULL; + } + } + } + else { + PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend); + return NULL; + } + if (_PyPerfTrampoline_Init(1) < 0) { + return NULL; + } + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_ValueError, "perf trampoline not available"); + return NULL; +#endif +} + + +/*[clinic input] +sys.deactivate_stack_trampoline + +Dectivate the perf profiler trampoline. +[clinic start generated code]*/ + +static PyObject * +sys_deactivate_stack_trampoline_impl(PyObject *module) +/*[clinic end generated code: output=b50da25465df0ef1 input=491f4fc1ed615736]*/ +{ + if (_PyPerfTrampoline_Init(0) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +sys.is_stack_trampoline_active + +Returns *True* if the perf profiler trampoline is active. +[clinic start generated code]*/ + +static PyObject * +sys_is_stack_trampoline_active_impl(PyObject *module) +/*[clinic end generated code: output=ab2746de0ad9d293 input=061fa5776ac9dd59]*/ +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (_PyIsPerfTrampolineActive()) { + Py_RETURN_TRUE; + } +#endif + Py_RETURN_FALSE; +} + + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ SYS_ADDAUDITHOOK_METHODDEF @@ -2108,6 +2182,9 @@ static PyMethodDef sys_methods[] = { METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, SYS_GET_ASYNCGEN_HOOKS_METHODDEF SYS_GETANDROIDAPILEVEL_METHODDEF + SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF + SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF + SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF SYS_UNRAISABLEHOOK_METHODDEF #ifdef Py_STATS SYS__STATS_ON_METHODDEF diff --git a/configure b/configure index fc7f7fadedb8..9522977c8c70 100755 --- a/configure +++ b/configure @@ -861,6 +861,7 @@ LIBEXPAT_CFLAGS TZPATH LIBUUID_LIBS LIBUUID_CFLAGS +PERF_TRAMPOLINE_OBJ SHLIBS CFLAGSFORSHARED LINKFORSHARED @@ -11498,6 +11499,35 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHLIBS" >&5 $as_echo "$SHLIBS" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking perf trampoline" >&5 +$as_echo_n "checking perf trampoline... " >&6; } +case $PLATFORM_TRIPLET in #( + x86_64-linux-gnu) : + perf_trampoline=yes ;; #( + aarch64-linux-gnu) : + perf_trampoline=yes ;; #( + *) : + perf_trampoline=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $perf_trampoline" >&5 +$as_echo "$perf_trampoline" >&6; } + +if test "x$perf_trampoline" = xyes; then : + + +$as_echo "#define PY_HAVE_PERF_TRAMPOLINE 1" >>confdefs.h + + PERF_TRAMPOLINE_OBJ=Objects/asm_trampoline.o + + if test "x$Py_DEBUG" = xtrue; then : + + as_fn_append BASECFLAGS " -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" + +fi + +fi + # checks for libraries { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile in -lsendfile" >&5 diff --git a/configure.ac b/configure.ac index 2b927cd961fa..3a009bb5042a 100644 --- a/configure.ac +++ b/configure.ac @@ -3452,6 +3452,26 @@ case "$ac_sys_system" in esac AC_MSG_RESULT($SHLIBS) +dnl perf trampoline is Linux specific and requires an arch-specific +dnl trampoline in asssembly. +AC_MSG_CHECKING([perf trampoline]) +AS_CASE([$PLATFORM_TRIPLET], + [x86_64-linux-gnu], [perf_trampoline=yes], + [aarch64-linux-gnu], [perf_trampoline=yes], + [perf_trampoline=no] +) +AC_MSG_RESULT([$perf_trampoline]) + +AS_VAR_IF([perf_trampoline], [yes], [ + AC_DEFINE([PY_HAVE_PERF_TRAMPOLINE], [1], [Define to 1 if you have the perf trampoline.]) + PERF_TRAMPOLINE_OBJ=Objects/asm_trampoline.o + + dnl perf needs frame pointers for unwinding, include compiler option in debug builds + AS_VAR_IF([Py_DEBUG], [true], [ + AS_VAR_APPEND([BASECFLAGS], [" -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"]) + ]) +]) +AC_SUBST([PERF_TRAMPOLINE_OBJ]) # checks for libraries AC_CHECK_LIB(sendfile, sendfile) diff --git a/pyconfig.h.in b/pyconfig.h.in index 10e7ad12fa98..1ce09855f555 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1568,6 +1568,9 @@ /* Define if you want to coerce the C locale to a UTF-8 based locale */ #undef PY_COERCE_C_LOCALE +/* Define to 1 if you have the perf trampoline. */ +#undef PY_HAVE_PERF_TRAMPOLINE + /* Define to 1 to build the sqlite module with loadable extensions support. */ #undef PY_SQLITE_ENABLE_LOAD_EXTENSION From webhook-mailer at python.org Tue Aug 30 13:36:35 2022 From: webhook-mailer at python.org (gvanrossum) Date: Tue, 30 Aug 2022 17:36:35 -0000 Subject: [Python-checkins] gh-95987: Fix `repr` of `Any` type subclasses (#96412) Message-ID: <mailman.917.1661880997.3313.python-checkins@python.org> https://github.com/python/cpython/commit/4217393aeed42d67dd4b16a128528f5ca8d939c4 commit: 4217393aeed42d67dd4b16a128528f5ca8d939c4 branch: main author: Nikita Sobolev <mail at sobolevn.me> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-30T10:36:16-07:00 summary: gh-95987: Fix `repr` of `Any` type subclasses (#96412) files: A Misc/NEWS.d/next/Library/2022-08-30-11-46-36.gh-issue-95987.CV7_u4.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 7eea01909ec..9239673c248 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -113,6 +113,12 @@ def test_any_instance_type_error(self): def test_repr(self): self.assertEqual(repr(Any), 'typing.Any') + class Sub(Any): pass + self.assertEqual( + repr(Sub), + "<class 'test.test_typing.AnyTests.test_repr.<locals>.Sub'>", + ) + def test_errors(self): with self.assertRaises(TypeError): issubclass(42, Any) diff --git a/Lib/typing.py b/Lib/typing.py index 596744ed132..84fe007a9ee 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -493,7 +493,9 @@ def __instancecheck__(self, obj): return super().__instancecheck__(obj) def __repr__(self): - return "typing.Any" + if self is Any: + return "typing.Any" + return super().__repr__() # respect to subclasses class Any(metaclass=_AnyMeta): diff --git a/Misc/NEWS.d/next/Library/2022-08-30-11-46-36.gh-issue-95987.CV7_u4.rst b/Misc/NEWS.d/next/Library/2022-08-30-11-46-36.gh-issue-95987.CV7_u4.rst new file mode 100644 index 00000000000..232bba1b924 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-30-11-46-36.gh-issue-95987.CV7_u4.rst @@ -0,0 +1 @@ +Fix ``repr`` of ``Any`` subclasses. From webhook-mailer at python.org Tue Aug 30 13:41:40 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 30 Aug 2022 17:41:40 -0000 Subject: [Python-checkins] Fix regeneration of global objects through the Windows build files (GH-96394) Message-ID: <mailman.918.1661881301.3313.python-checkins@python.org> https://github.com/python/cpython/commit/13c309f1101dc86ca0138f239d45cb009d0e898d commit: 13c309f1101dc86ca0138f239d45cb009d0e898d branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: zooba <steve.dower at microsoft.com> date: 2022-08-30T18:41:27+01:00 summary: Fix regeneration of global objects through the Windows build files (GH-96394) files: M PCbuild/regen.targets diff --git a/PCbuild/regen.targets b/PCbuild/regen.targets index 9073bb6ab2b..3938b66678e 100644 --- a/PCbuild/regen.targets +++ b/PCbuild/regen.targets @@ -82,9 +82,16 @@ WorkingDirectory="$(PySourcePath)" /> </Target> + <Target Name="_RegenGlobalObjects" + DependsOnTargets="FindPythonForBuild"> + <Message Text="Regenerate Global Objects" Importance="high" /> + <Exec Command="$(PythonForBuild) Tools\scripts\generate_global_objects.py" + WorkingDirectory="$(PySourcePath)" /> + </Target> + <Target Name="Regen" Condition="$(Configuration) != 'PGUpdate'" - DependsOnTargets="_TouchRegenSources;_RegenPegen;_RegenAST_H;_RegenOpcodes;_RegenTokens;_RegenKeywords"> + DependsOnTargets="_TouchRegenSources;_RegenPegen;_RegenAST_H;_RegenOpcodes;_RegenTokens;_RegenKeywords;_RegenGlobalObjects"> <Message Text="Generated sources are up to date" Importance="high" /> </Target> From webhook-mailer at python.org Tue Aug 30 14:11:59 2022 From: webhook-mailer at python.org (ethanfurman) Date: Tue, 30 Aug 2022 18:11:59 -0000 Subject: [Python-checkins] gh-95149: Enhance `http.HTTPStatus` with properties that indicate the HTTP status category (GH-95453) Message-ID: <mailman.919.1661883120.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0ed778835d34bc1f39d2c6cdbc0c1709f6bcfd61 commit: 0ed778835d34bc1f39d2c6cdbc0c1709f6bcfd61 branch: main author: Alexandru M?r??teanu <alexei at users.noreply.github.com> committer: ethanfurman <ethan at stoneleaf.us> date: 2022-08-30T11:11:44-07:00 summary: gh-95149: Enhance `http.HTTPStatus` with properties that indicate the HTTP status category (GH-95453) files: A Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst M Doc/library/http.rst M Lib/enum.py M Lib/http/__init__.py M Lib/test/test_httplib.py diff --git a/Doc/library/http.rst b/Doc/library/http.rst index 5895a41d849b..521fd1b7f50c 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -137,6 +137,31 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as .. versionadded:: 3.9 Added ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` status codes. +HTTP status category +-------------------- + +.. versionadded:: 3.11 + +The enum values have several properties to indicate the HTTP status category: + +==================== ======================== =============================== +Property Indicates that Details +==================== ======================== =============================== +``is_informational`` ``100 <= status <= 199`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_success`` ``200 <= status <= 299`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_redirection`` ``300 <= status <= 399`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_client_error`` ``400 <= status <= 499`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_server_error`` ``500 <= status <= 599`` HTTP/1.1 :rfc:`7231`, Section 6 +==================== ======================== =============================== + + Usage:: + + >>> from http import HTTPStatus + >>> HTTPStatus.OK.is_success + True + >>> HTTPStatus.OK.is_client_error + False + .. class:: HTTPMethod .. versionadded:: 3.11 diff --git a/Lib/enum.py b/Lib/enum.py index 8ef69589a146..e7375e1eae69 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1887,7 +1887,7 @@ def _test_simple_enum(checked_enum, simple_enum): else: checked_value = checked_dict[key] simple_value = simple_dict[key] - if callable(checked_value): + if callable(checked_value) or isinstance(checked_value, bltns.property): continue if key == '__doc__': # remove all spaces/tabs diff --git a/Lib/http/__init__.py b/Lib/http/__init__.py index cd2885dc7757..e093a1fec4df 100644 --- a/Lib/http/__init__.py +++ b/Lib/http/__init__.py @@ -31,6 +31,26 @@ def __new__(cls, value, phrase, description=''): obj.description = description return obj + @property + def is_informational(self): + return 100 <= self <= 199 + + @property + def is_success(self): + return 200 <= self <= 299 + + @property + def is_redirection(self): + return 300 <= self <= 399 + + @property + def is_client_error(self): + return 400 <= self <= 499 + + @property + def is_server_error(self): + return 500 <= self <= 599 + # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 15dab0356f5e..b3d94e0a21cb 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -553,6 +553,27 @@ def __new__(cls, value, phrase, description=''): obj.phrase = phrase obj.description = description return obj + + @property + def is_informational(self): + return 100 <= self <= 199 + + @property + def is_success(self): + return 200 <= self <= 299 + + @property + def is_redirection(self): + return 300 <= self <= 399 + + @property + def is_client_error(self): + return 400 <= self <= 499 + + @property + def is_server_error(self): + return 500 <= self <= 599 + # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', @@ -669,6 +690,30 @@ def __new__(cls, value, phrase, description=''): 'The client needs to authenticate to gain network access') enum._test_simple_enum(CheckedHTTPStatus, HTTPStatus) + def test_httpstatus_range(self): + """Checks that the statuses are in the 100-599 range""" + + for member in HTTPStatus.__members__.values(): + self.assertGreaterEqual(member, 100) + self.assertLessEqual(member, 599) + + def test_httpstatus_category(self): + """Checks that the statuses belong to the standard categories""" + + categories = ( + ((100, 199), "is_informational"), + ((200, 299), "is_success"), + ((300, 399), "is_redirection"), + ((400, 499), "is_client_error"), + ((500, 599), "is_server_error"), + ) + for member in HTTPStatus.__members__.values(): + for (lower, upper), category in categories: + category_indicator = getattr(member, category) + if lower <= member <= upper: + self.assertTrue(category_indicator) + else: + self.assertFalse(category_indicator) def test_status_lines(self): # Test HTTP status lines diff --git a/Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst b/Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst new file mode 100644 index 000000000000..6393444b53fb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst @@ -0,0 +1,2 @@ +The :class:`HTTPStatus <http.HTTPStatus>` enum offers a couple of properties +to indicate the HTTP status category e.g. ``HTTPStatus.OK.is_success``. From webhook-mailer at python.org Tue Aug 30 14:13:04 2022 From: webhook-mailer at python.org (ezio-melotti) Date: Tue, 30 Aug 2022 18:13:04 -0000 Subject: [Python-checkins] Automatically update more GitHub projects. (#94921) Message-ID: <mailman.920.1661883184.3313.python-checkins@python.org> https://github.com/python/cpython/commit/45fd3685aad90de3be21c8f6eade7b5985629fb8 commit: 45fd3685aad90de3be21c8f6eade7b5985629fb8 branch: main author: Ezio Melotti <ezio.melotti at gmail.com> committer: ezio-melotti <ezio.melotti at gmail.com> date: 2022-08-30T20:12:55+02:00 summary: Automatically update more GitHub projects. (#94921) * Automatically update the `asyncio` GitHub project. * Use a matrix to add issues to projects. * Remove trailing whitespace. Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com> Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com> files: M .github/workflows/project-updater.yml diff --git a/.github/workflows/project-updater.yml b/.github/workflows/project-updater.yml index 716ed7841fea..ea98700e7fae 100644 --- a/.github/workflows/project-updater.yml +++ b/.github/workflows/project-updater.yml @@ -8,12 +8,20 @@ on: jobs: add-to-project: - name: Add to the Release and Deferred Blocker project + name: Add issues to projects runs-on: ubuntu-latest + strategy: + matrix: + include: + # if an issue has any of these labels, it will be added + # to the corresponding project + - { project: 2, label: "release-blocker, deferred-blocker" } + - { project: 3, label: expert-subinterpreters } + - { project: 29, label: expert-asyncio } + steps: - uses: actions/add-to-project at v0.1.0 with: - project-url: https://github.com/orgs/python/projects/2 + project-url: https://github.com/orgs/python/projects/${{ matrix.project }} github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - labeled: release-blocker, deferred-blocker - label-operator: OR + labeled: ${{ matrix.label }} From webhook-mailer at python.org Tue Aug 30 14:37:35 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 30 Aug 2022 18:37:35 -0000 Subject: [Python-checkins] gh-96143: Add some comments and minor fixes missed in the original PR (#96433) Message-ID: <mailman.921.1661884655.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f49dd54b72ec3fe6dbdcd2476a810929382bc196 commit: f49dd54b72ec3fe6dbdcd2476a810929382bc196 branch: main author: Pablo Galindo Salgado <Pablogsal at gmail.com> committer: pablogsal <Pablogsal at gmail.com> date: 2022-08-30T19:37:22+01:00 summary: gh-96143: Add some comments and minor fixes missed in the original PR (#96433) * gh-96132: Add some comments and minor fixes missed in the original PR * Update Doc/using/cmdline.rst Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: M Doc/howto/perf_profiling.rst M Doc/using/cmdline.rst M Lib/test/test_perf_profiler.py M Objects/perf_trampoline.c diff --git a/Doc/howto/perf_profiling.rst b/Doc/howto/perf_profiling.rst index 2e1bb48af8c8..ed8de888b3bc 100644 --- a/Doc/howto/perf_profiling.rst +++ b/Doc/howto/perf_profiling.rst @@ -155,6 +155,9 @@ active since the start of the Python interpreter, you can use the `-Xperf` optio $ python -Xperf my_script.py +You can also set the :envvar:`PYTHONPERFSUPPORT` to a nonzero value to actiavate perf +profiling mode globally. + There is also support for dynamically activating and deactivating the perf profiling mode by using the APIs in the :mod:`sys` module: diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 5ecc882d818f..fa2b07e468b3 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -582,6 +582,8 @@ Miscellaneous options .. versionadded:: 3.11 The ``-X frozen_modules`` option. + .. versionadded:: 3.12 + The ``-X perf`` option. Options you shouldn't use diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py index c2aad85b652e..f587995b008f 100644 --- a/Lib/test/test_perf_profiler.py +++ b/Lib/test/test_perf_profiler.py @@ -58,7 +58,7 @@ def baz(): script = make_script(script_dir, "perftest", code) with subprocess.Popen( [sys.executable, "-Xperf", script], - universal_newlines=True, + text=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, ) as process: diff --git a/Objects/perf_trampoline.c b/Objects/perf_trampoline.c index 02206b2786c8..2cbe3741f26f 100644 --- a/Objects/perf_trampoline.c +++ b/Objects/perf_trampoline.c @@ -284,12 +284,23 @@ new_code_arena(void) void *start = &_Py_trampoline_func_start; void *end = &_Py_trampoline_func_end; size_t code_size = end - start; + // TODO: Check the effect of alignment of the code chunks. Initial investigation + // showed that this has no effect on performance in x86-64 or aarch64 and the current + // version has the advantage that the unwinder in GDB can unwind across JIT-ed code. + // + // We should check the values in the future and see if there is a + // measurable performance improvement by rounding trampolines up to 32-bit + // or 64-bit alignment. size_t n_copies = mem_size / code_size; for (size_t i = 0; i < n_copies; i++) { memcpy(memory + i * code_size, start, code_size * sizeof(char)); } // Some systems may prevent us from creating executable code on the fly. + // TODO: Call icache invalidation intrinsics if available: + // __builtin___clear_cache/__clear_cache (depending if clang/gcc). This is + // technically not necessary but we could be missing something so better be + // safe. int res = mprotect(memory, mem_size, PROT_READ | PROT_EXEC); if (res == -1) { PyErr_SetFromErrno(PyExc_OSError); From webhook-mailer at python.org Tue Aug 30 15:39:31 2022 From: webhook-mailer at python.org (ethanfurman) Date: Tue, 30 Aug 2022 19:39:31 -0000 Subject: [Python-checkins] [3.11] [Enum] fix check in _test_simple_enum (GH-96435) Message-ID: <mailman.922.1661888373.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8f58db2279a97d826e5bfa99627ba9bb66f6f096 commit: 8f58db2279a97d826e5bfa99627ba9bb66f6f096 branch: 3.11 author: Ethan Furman <ethan at stoneleaf.us> committer: ethanfurman <ethan at stoneleaf.us> date: 2022-08-30T12:39:03-07:00 summary: [3.11] [Enum] fix check in _test_simple_enum (GH-96435) The builtin `property` is not a callable, so was failing the check in `_test_simple_enum` causing a match failure; this adds `property` to the bypass list. Co-authored-by: Alexandru M?r??teanu <alexei at users.noreply.github.com> files: M Lib/enum.py M Lib/test/test_enum.py diff --git a/Lib/enum.py b/Lib/enum.py index 63ca1605353..28b638c28f1 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1904,7 +1904,7 @@ def _test_simple_enum(checked_enum, simple_enum): else: checked_value = checked_dict[key] simple_value = simple_dict[key] - if callable(checked_value): + if callable(checked_value) or isinstance(checked_value, bltns.property): continue if key == '__doc__': # remove all spaces/tabs diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 4a42c738172..7964d3e474c 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -4337,10 +4337,16 @@ class SimpleColor: CYAN = 1 MAGENTA = 2 YELLOW = 3 + @bltns.property + def zeroth(self): + return 'zeroed %s' % self.name class CheckedColor(Enum): CYAN = 1 MAGENTA = 2 YELLOW = 3 + @bltns.property + def zeroth(self): + return 'zeroed %s' % self.name self.assertTrue(_test_simple_enum(CheckedColor, SimpleColor) is None) SimpleColor.MAGENTA._value_ = 9 self.assertRaisesRegex( From webhook-mailer at python.org Tue Aug 30 16:44:22 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Tue, 30 Aug 2022 20:44:22 -0000 Subject: [Python-checkins] Docs: normalise sqlite3 placeholder how-to heading (#96413) Message-ID: <mailman.923.1661892263.3313.python-checkins@python.org> https://github.com/python/cpython/commit/7b01ce7953c0e24aa7aeaf207216fc9e7aefd18a commit: 7b01ce7953c0e24aa7aeaf207216fc9e7aefd18a branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-30T22:44:14+02:00 summary: Docs: normalise sqlite3 placeholder how-to heading (#96413) files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 31a0e7f0b53..58343b1a0f7 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1653,8 +1653,8 @@ How-to guides .. _sqlite3-placeholders: -Using placeholders to bind values in SQL queries -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to use placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SQL operations usually need to use values from Python variables. However, beware of using Python's string operations to assemble queries, as they From webhook-mailer at python.org Tue Aug 30 16:56:12 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 20:56:12 -0000 Subject: [Python-checkins] Docs: normalise sqlite3 placeholder how-to heading (GH-96413) Message-ID: <mailman.924.1661892973.3313.python-checkins@python.org> https://github.com/python/cpython/commit/a0d0a77c1f78fee581294283a66bf198d69f2699 commit: a0d0a77c1f78fee581294283a66bf198d69f2699 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T13:56:02-07:00 summary: Docs: normalise sqlite3 placeholder how-to heading (GH-96413) (cherry picked from commit 7b01ce7953c0e24aa7aeaf207216fc9e7aefd18a) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 18a03a26e29..27645b05364 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1301,8 +1301,8 @@ How-to guides .. _sqlite3-placeholders: -Using placeholders to bind values in SQL queries -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to use placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SQL operations usually need to use values from Python variables. However, beware of using Python's string operations to assemble queries, as they From webhook-mailer at python.org Tue Aug 30 17:06:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 30 Aug 2022 21:06:21 -0000 Subject: [Python-checkins] Docs: normalise sqlite3 placeholder how-to heading (GH-96413) Message-ID: <mailman.925.1661893582.3313.python-checkins@python.org> https://github.com/python/cpython/commit/895c7a440168769fe96154c3476b7917a5874bcc commit: 895c7a440168769fe96154c3476b7917a5874bcc branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T14:06:11-07:00 summary: Docs: normalise sqlite3 placeholder how-to heading (GH-96413) (cherry picked from commit 7b01ce7953c0e24aa7aeaf207216fc9e7aefd18a) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: M Doc/library/sqlite3.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 21ad3540ccb..2c58ef71c33 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1615,8 +1615,8 @@ How-to guides .. _sqlite3-placeholders: -Using placeholders to bind values in SQL queries -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How to use placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SQL operations usually need to use values from Python variables. However, beware of using Python's string operations to assemble queries, as they From webhook-mailer at python.org Tue Aug 30 18:43:36 2022 From: webhook-mailer at python.org (rhettinger) Date: Tue, 30 Aug 2022 22:43:36 -0000 Subject: [Python-checkins] gh-96408: Test set operation on items dict view. (GH-96438) Message-ID: <mailman.926.1661899417.3313.python-checkins@python.org> https://github.com/python/cpython/commit/02dbb362d3fb7d82af9dce7c8caac08fe0d8efdb commit: 02dbb362d3fb7d82af9dce7c8caac08fe0d8efdb branch: main author: Filip ?ajszczak <filip.lajszczak at gmail.com> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-30T17:43:23-05:00 summary: gh-96408: Test set operation on items dict view. (GH-96438) files: M Lib/test/test_dictviews.py diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index be271bebaaf..7c48d800cd8 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -170,6 +170,10 @@ def test_items_set_operations(self): {('a', 1), ('b', 2)}) self.assertEqual(d1.items() & set(d2.items()), {('b', 2)}) self.assertEqual(d1.items() & set(d3.items()), set()) + self.assertEqual(d1.items() & (("a", 1), ("b", 2)), + {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() & (("a", 2), ("b", 2)), {('b', 2)}) + self.assertEqual(d1.items() & (("d", 4), ("e", 5)), set()) self.assertEqual(d1.items() | d1.items(), {('a', 1), ('b', 2)}) @@ -183,12 +187,23 @@ def test_items_set_operations(self): {('a', 1), ('a', 2), ('b', 2)}) self.assertEqual(d1.items() | set(d3.items()), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) + self.assertEqual(d1.items() | (('a', 1), ('b', 2)), + {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() | (('a', 2), ('b', 2)), + {('a', 1), ('a', 2), ('b', 2)}) + self.assertEqual(d1.items() | (('d', 4), ('e', 5)), + {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.items() ^ d1.items(), set()) self.assertEqual(d1.items() ^ d2.items(), {('a', 1), ('a', 2)}) self.assertEqual(d1.items() ^ d3.items(), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) + self.assertEqual(d1.items() ^ (('a', 1), ('b', 2)), set()) + self.assertEqual(d1.items() ^ (("a", 2), ("b", 2)), + {('a', 1), ('a', 2)}) + self.assertEqual(d1.items() ^ (("d", 4), ("e", 5)), + {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.items() - d1.items(), set()) self.assertEqual(d1.items() - d2.items(), {('a', 1)}) @@ -196,6 +211,9 @@ def test_items_set_operations(self): self.assertEqual(d1.items() - set(d1.items()), set()) self.assertEqual(d1.items() - set(d2.items()), {('a', 1)}) self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() - (('a', 1), ('b', 2)), set()) + self.assertEqual(d1.items() - (("a", 2), ("b", 2)), {('a', 1)}) + self.assertEqual(d1.items() - (("d", 4), ("e", 5)), {('a', 1), ('b', 2)}) self.assertFalse(d1.items().isdisjoint(d1.items())) self.assertFalse(d1.items().isdisjoint(d2.items())) From webhook-mailer at python.org Tue Aug 30 18:45:31 2022 From: webhook-mailer at python.org (brandtbucher) Date: Tue, 30 Aug 2022 22:45:31 -0000 Subject: [Python-checkins] Remove the binary_subscr_dict_error label (GH-96443) Message-ID: <mailman.927.1661899533.3313.python-checkins@python.org> https://github.com/python/cpython/commit/88671a9d6916229badc8b97a358a0f596f5aa0a1 commit: 88671a9d6916229badc8b97a358a0f596f5aa0a1 branch: main author: Brandt Bucher <brandtbucher at microsoft.com> committer: brandtbucher <brandtbucher at gmail.com> date: 2022-08-30T15:45:24-07:00 summary: Remove the binary_subscr_dict_error label (GH-96443) files: M Python/ceval.c diff --git a/Python/ceval.c b/Python/ceval.c index b3a0a3640eb..c61ccd7dfc6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1621,7 +1621,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *sub = TOP(); PyObject *res = PyDict_GetItemWithError(dict, sub); if (res == NULL) { - goto binary_subscr_dict_error; + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetKeyError(sub); + } + goto error; } Py_INCREF(res); STACK_SHRINK(1); @@ -5193,16 +5196,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH_GOTO(); } -binary_subscr_dict_error: - { - PyObject *sub = POP(); - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetKeyError(sub); - } - Py_DECREF(sub); - goto error; - } - unbound_local_error: { format_exc_check_arg(tstate, PyExc_UnboundLocalError, From webhook-mailer at python.org Tue Aug 30 21:40:30 2022 From: webhook-mailer at python.org (sweeneyde) Date: Wed, 31 Aug 2022 01:40:30 -0000 Subject: [Python-checkins] gh-95865: Speed up urllib.parse.quote_from_bytes() (GH-95872) Message-ID: <mailman.928.1661910031.3313.python-checkins@python.org> https://github.com/python/cpython/commit/8ba22b90cafdf83d26318905a021311c6932d2c0 commit: 8ba22b90cafdf83d26318905a021311c6932d2c0 branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-08-30T21:39:51-04:00 summary: gh-95865: Speed up urllib.parse.quote_from_bytes() (GH-95872) files: A Misc/NEWS.d/next/Library/2022-08-11-03-16-48.gh-issue-95865.0IOkFP.rst M Lib/urllib/parse.py diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index fd6d9f44c626..f25c770068bd 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -906,7 +906,7 @@ def quote_from_bytes(bs, safe='/'): if not bs.rstrip(_ALWAYS_SAFE_BYTES + safe): return bs.decode() quoter = _byte_quoter_factory(safe) - return ''.join([quoter(char) for char in bs]) + return ''.join(map(quoter, bs)) def urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus): diff --git a/Misc/NEWS.d/next/Library/2022-08-11-03-16-48.gh-issue-95865.0IOkFP.rst b/Misc/NEWS.d/next/Library/2022-08-11-03-16-48.gh-issue-95865.0IOkFP.rst new file mode 100644 index 000000000000..aa7c73ff1a35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-11-03-16-48.gh-issue-95865.0IOkFP.rst @@ -0,0 +1 @@ +Speed up :func:`urllib.parse.quote_from_bytes` by replacing a list comprehension with ``map()``. From webhook-mailer at python.org Wed Aug 31 01:55:04 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 31 Aug 2022 05:55:04 -0000 Subject: [Python-checkins] gh-96414: Inline code examples in sqlite3 docs (#96442) Message-ID: <mailman.929.1661925305.3313.python-checkins@python.org> https://github.com/python/cpython/commit/f7e7bf161aaec5a5cffdcec7c97e1f09e445421b commit: f7e7bf161aaec5a5cffdcec7c97e1f09e445421b branch: main author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-31T07:54:54+02:00 summary: gh-96414: Inline code examples in sqlite3 docs (#96442) files: D Doc/includes/sqlite3/adapter_point_1.py D Doc/includes/sqlite3/adapter_point_2.py D Doc/includes/sqlite3/blob.py D Doc/includes/sqlite3/collation_reverse.py D Doc/includes/sqlite3/converter_point.py D Doc/includes/sqlite3/ctx_manager.py D Doc/includes/sqlite3/execute_1.py D Doc/includes/sqlite3/load_extension.py D Doc/includes/sqlite3/md5func.py D Doc/includes/sqlite3/mysumaggr.py D Doc/includes/sqlite3/row_factory.py D Doc/includes/sqlite3/shortcut_methods.py D Doc/includes/sqlite3/sumintwindow.py D Doc/includes/sqlite3/text_factory.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py deleted file mode 100644 index 77daf8f16d22..000000000000 --- a/Doc/includes/sqlite3/adapter_point_1.py +++ /dev/null @@ -1,18 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __conform__(self, protocol): - if protocol is sqlite3.PrepareProtocol: - return "%f;%f" % (self.x, self.y) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py deleted file mode 100644 index cb86331692b6..000000000000 --- a/Doc/includes/sqlite3/adapter_point_2.py +++ /dev/null @@ -1,19 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - -def adapt_point(point): - return "%f;%f" % (point.x, point.y) - -sqlite3.register_adapter(Point, adapt_point) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/blob.py b/Doc/includes/sqlite3/blob.py deleted file mode 100644 index ff58d6c352b6..000000000000 --- a/Doc/includes/sqlite3/blob.py +++ /dev/null @@ -1,19 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.execute("create table test(blob_col blob)") -con.execute("insert into test(blob_col) values (zeroblob(13))") - -# Write to our blob, using two write operations: -with con.blobopen("test", "blob_col", 1) as blob: - blob.write(b"hello, ") - blob.write(b"world.") - # Modify the first and last bytes of our blob - blob[0] = ord("H") - blob[-1] = ord("!") - -# Read the contents of our blob -with con.blobopen("test", "blob_col", 1) as blob: - greeting = blob.read() - -print(greeting) # outputs "b'Hello, world!'" diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py deleted file mode 100644 index 3504a350a04e..000000000000 --- a/Doc/includes/sqlite3/collation_reverse.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -def collate_reverse(string1, string2): - if string1 == string2: - return 0 - elif string1 < string2: - return 1 - else: - return -1 - -con = sqlite3.connect(":memory:") -con.create_collation("reverse", collate_reverse) - -cur = con.cursor() -cur.execute("create table test(x)") -cur.executemany("insert into test(x) values (?)", [("a",), ("b",)]) -cur.execute("select x from test order by x collate reverse") -for row in cur: - print(row) -con.close() diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py deleted file mode 100644 index 147807a2225f..000000000000 --- a/Doc/includes/sqlite3/converter_point.py +++ /dev/null @@ -1,40 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __repr__(self): - return f"Point({self.x}, {self.y})" - -def adapt_point(point): - return f"{point.x};{point.y}".encode("utf-8") - -def convert_point(s): - x, y = list(map(float, s.split(b";"))) - return Point(x, y) - -# Register the adapter and converter -sqlite3.register_adapter(Point, adapt_point) -sqlite3.register_converter("point", convert_point) - -# 1) Parse using declared types -p = Point(4.0, -3.2) -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) -cur = con.execute("create table test(p point)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute("select p from test") -print("with declared types:", cur.fetchone()[0]) -cur.close() -con.close() - -# 2) Parse using column names -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) -cur = con.execute("create table test(p)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute('select p as "p [point]" from test') -print("with column names:", cur.fetchone()[0]) -cur.close() -con.close() diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py deleted file mode 100644 index 2e1175ef44c6..000000000000 --- a/Doc/includes/sqlite3/ctx_manager.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.execute("create table lang (id integer primary key, name varchar unique)") - -# Successful, con.commit() is called automatically afterwards -with con: - con.execute("insert into lang(name) values (?)", ("Python",)) - -# con.rollback() is called after the with block finishes with an exception, the -# exception is still raised and must be caught -try: - with con: - con.execute("insert into lang(name) values (?)", ("Python",)) -except sqlite3.IntegrityError: - print("couldn't add Python twice") - -# Connection object used as context manager only commits or rollbacks transactions, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py deleted file mode 100644 index ee0000e2b94a..000000000000 --- a/Doc/includes/sqlite3/execute_1.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.execute("create table lang (name, first_appeared)") - -# This is the qmark style: -cur.execute("insert into lang values (?, ?)", ("C", 1972)) - -# The qmark style used with executemany(): -lang_list = [ - ("Fortran", 1957), - ("Python", 1991), - ("Go", 2009), -] -cur.executemany("insert into lang values (?, ?)", lang_list) - -# And this is the named style: -cur.execute("select * from lang where first_appeared=:year", {"year": 1972}) -print(cur.fetchall()) - -con.close() diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py deleted file mode 100644 index 624cfe262f38..000000000000 --- a/Doc/includes/sqlite3/load_extension.py +++ /dev/null @@ -1,28 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") - -# enable extension loading -con.enable_load_extension(True) - -# Load the fulltext search extension -con.execute("select load_extension('./fts3.so')") - -# alternatively you can load the extension using an API call: -# con.load_extension("./fts3.so") - -# disable extension loading again -con.enable_load_extension(False) - -# example from SQLite wiki -con.execute("create virtual table recipe using fts3(name, ingredients)") -con.executescript(""" - insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes'); - insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery'); - insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour'); - insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter'); - """) -for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"): - print(row) - -con.close() diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py deleted file mode 100644 index 16dc348bf001..000000000000 --- a/Doc/includes/sqlite3/md5func.py +++ /dev/null @@ -1,13 +0,0 @@ -import sqlite3 -import hashlib - -def md5sum(t): - return hashlib.md5(t).hexdigest() - -con = sqlite3.connect(":memory:") -con.create_function("md5", 1, md5sum) -cur = con.cursor() -cur.execute("select md5(?)", (b"foo",)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py deleted file mode 100644 index 11f96395b6c4..000000000000 --- a/Doc/includes/sqlite3/mysumaggr.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -class MySum: - def __init__(self): - self.count = 0 - - def step(self, value): - self.count += value - - def finalize(self): - return self.count - -con = sqlite3.connect(":memory:") -con.create_aggregate("mysum", 1, MySum) -cur = con.cursor() -cur.execute("create table test(i)") -cur.execute("insert into test(i) values (1)") -cur.execute("insert into test(i) values (2)") -cur.execute("select mysum(i) from test") -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py deleted file mode 100644 index 9de6e7b1b905..000000000000 --- a/Doc/includes/sqlite3/row_factory.py +++ /dev/null @@ -1,15 +0,0 @@ -import sqlite3 - -def dict_factory(cursor, row): - d = {} - for idx, col in enumerate(cursor.description): - d[col[0]] = row[idx] - return d - -con = sqlite3.connect(":memory:") -con.row_factory = dict_factory -cur = con.cursor() -cur.execute("select 1 as a") -print(cur.fetchone()["a"]) - -con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py deleted file mode 100644 index 48ea6fad15a8..000000000000 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ /dev/null @@ -1,24 +0,0 @@ -import sqlite3 - -langs = [ - ("C++", 1985), - ("Objective-C", 1984), -] - -con = sqlite3.connect(":memory:") - -# Create the table -con.execute("create table lang(name, first_appeared)") - -# Fill the table -con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs) - -# Print the table contents -for row in con.execute("select name, first_appeared from lang"): - print(row) - -print("I just deleted", con.execute("delete from lang").rowcount, "rows") - -# close is not a shortcut method and it's not called automatically, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/sumintwindow.py b/Doc/includes/sqlite3/sumintwindow.py deleted file mode 100644 index 0e915d6cc6ae..000000000000 --- a/Doc/includes/sqlite3/sumintwindow.py +++ /dev/null @@ -1,46 +0,0 @@ -# Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc -import sqlite3 - - -class WindowSumInt: - def __init__(self): - self.count = 0 - - def step(self, value): - """Adds a row to the current window.""" - self.count += value - - def value(self): - """Returns the current value of the aggregate.""" - return self.count - - def inverse(self, value): - """Removes a row from the current window.""" - self.count -= value - - def finalize(self): - """Returns the final value of the aggregate. - - Any clean-up actions should be placed here. - """ - return self.count - - -con = sqlite3.connect(":memory:") -cur = con.execute("create table test(x, y)") -values = [ - ("a", 4), - ("b", 5), - ("c", 3), - ("d", 8), - ("e", 1), -] -cur.executemany("insert into test values(?, ?)", values) -con.create_window_function("sumint", 1, WindowSumInt) -cur.execute(""" - select x, sumint(y) over ( - order by x rows between 1 preceding and 1 following - ) as sum_y - from test order by x -""") -print(cur.fetchall()) diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py deleted file mode 100644 index c0d87cd55911..000000000000 --- a/Doc/includes/sqlite3/text_factory.py +++ /dev/null @@ -1,29 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -AUSTRIA = "?sterreich" - -# by default, rows are returned as str -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert row[0] == AUSTRIA - -# but we can make sqlite3 always return bytestrings ... -con.text_factory = bytes -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert type(row[0]) is bytes -# the bytestrings will be encoded in UTF-8, unless you stored garbage in the -# database ... -assert row[0] == AUSTRIA.encode("utf-8") - -# we can also implement a custom text_factory ... -# here we implement one that appends "foo" to all strings -con.text_factory = lambda x: x.decode("utf-8") + "foo" -cur.execute("select ?", ("bar",)) -row = cur.fetchone() -assert row[0] == "barfoo" - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 58343b1a0f77..7ac7162c2527 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -601,7 +601,25 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/row_factory.py + .. testcode:: + + def dict_factory(cursor, row): + d = {} + for idx, col in enumerate(cursor.description): + d[col[0]] = row[idx] + return d + + con = sqlite3.connect(":memory:") + con.row_factory = dict_factory + cur = con.execute("SELECT 1 AS a") + print(cur.fetchone()["a"]) + + con.close() + + .. testoutput:: + :hide: + + 1 If returning a tuple doesn't suffice and you want name-based access to columns, you should consider setting :attr:`row_factory` to the @@ -622,7 +640,35 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/text_factory.py + .. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + AUSTRIA = "?sterreich" + + # by default, rows are returned as str + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert row[0] == AUSTRIA + + # but we can make sqlite3 always return bytestrings ... + con.text_factory = bytes + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert type(row[0]) is bytes + # the bytestrings will be encoded in UTF-8, unless you stored garbage in the + # database ... + assert row[0] == AUSTRIA.encode("utf-8") + + # we can also implement a custom text_factory ... + # here we implement one that appends "foo" to all strings + con.text_factory = lambda x: x.decode("utf-8") + "foo" + cur.execute("SELECT ?", ("bar",)) + row = cur.fetchone() + assert row[0] == "barfoo" + + con.close() .. attribute:: total_changes @@ -738,7 +784,16 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/md5func.py + .. doctest:: + + >>> import hashlib + >>> def md5sum(t): + ... return hashlib.md5(t).hexdigest() + >>> con = sqlite3.connect(":memory:") + >>> con.create_function("md5", 1, md5sum) + >>> for row in con.execute("SELECT md5(?)", (b"foo",)): + ... print(row) + ('acbd18db4cc2f85cedef654fccc4a4d8',) .. method:: create_aggregate(name, /, n_arg, aggregate_class) @@ -767,7 +822,32 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/mysumaggr.py + .. testcode:: + + class MySum: + def __init__(self): + self.count = 0 + + def step(self, value): + self.count += value + + def finalize(self): + return self.count + + con = sqlite3.connect(":memory:") + con.create_aggregate("mysum", 1, MySum) + cur = con.execute("CREATE TABLE test(i)") + cur.execute("INSERT INTO test(i) VALUES(1)") + cur.execute("INSERT INTO test(i) VALUES(2)") + cur.execute("SELECT mysum(i) FROM test") + print(cur.fetchone()[0]) + + con.close() + + .. testoutput:: + :hide: + + 3 .. method:: create_window_function(name, num_params, aggregate_class, /) @@ -805,8 +885,56 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/sumintwindow.py + .. testcode:: + + # Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc + class WindowSumInt: + def __init__(self): + self.count = 0 + def step(self, value): + """Add a row to the current window.""" + self.count += value + + def value(self): + """Return the current value of the aggregate.""" + return self.count + + def inverse(self, value): + """Remove a row from the current window.""" + self.count -= value + + def finalize(self): + """Return the final value of the aggregate. + + Any clean-up actions should be placed here. + """ + return self.count + + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE test(x, y)") + values = [ + ("a", 4), + ("b", 5), + ("c", 3), + ("d", 8), + ("e", 1), + ] + cur.executemany("INSERT INTO test VALUES(?, ?)", values) + con.create_window_function("sumint", 1, WindowSumInt) + cur.execute(""" + SELECT x, sumint(y) OVER ( + ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) AS sum_y + FROM test ORDER BY x + """) + print(cur.fetchall()) + + .. testoutput:: + :hide: + + [('a', 9), ('b', 12), ('c', 16), ('d', 12), ('e', 9)] .. method:: create_collation(name, callable) @@ -820,7 +948,31 @@ Connection objects The following example shows a reverse sorting collation: - .. literalinclude:: ../includes/sqlite3/collation_reverse.py + .. testcode:: + + def collate_reverse(string1, string2): + if string1 == string2: + return 0 + elif string1 < string2: + return 1 + else: + return -1 + + con = sqlite3.connect(":memory:") + con.create_collation("reverse", collate_reverse) + + cur = con.execute("CREATE TABLE test(x)") + cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)]) + cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse") + for row in cur: + print(row) + con.close() + + .. testoutput:: + :hide: + + ('b',) + ('a',) Remove a collation function by setting *callable* to ``None``. @@ -925,7 +1077,43 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.enable_load_extension`` auditing event. - .. literalinclude:: ../includes/sqlite3/load_extension.py + .. testsetup:: sqlite3.loadext + + import sqlite3 + con = sqlite3.connect(":memory:") + + .. testcode:: sqlite3.loadext + :skipif: True # not testable at the moment + + con.enable_load_extension(True) + + # Load the fulltext search extension + con.execute("select load_extension('./fts3.so')") + + # alternatively you can load the extension using an API call: + # con.load_extension("./fts3.so") + + # disable extension loading again + con.enable_load_extension(False) + + # example from SQLite wiki + con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)") + con.executescript(""" + INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery'); + INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter'); + """) + for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"): + print(row) + + con.close() + + .. testoutput:: sqlite3.loadext + :hide: + + (2, 'broccoli pie', 'broccoli cheese onions flour') + (3, 'pumpkin pie', 'pumpkin sugar flour butter') .. method:: load_extension(path, /) @@ -1400,7 +1588,30 @@ Blob objects Use the :class:`Blob` as a :term:`context manager` to ensure that the blob handle is closed after use. - .. literalinclude:: ../includes/sqlite3/blob.py + .. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE test(blob_col blob)") + con.execute("INSERT INTO test(blob_col) VALUES(zeroblob(13))") + + # Write to our blob, using two write operations: + with con.blobopen("test", "blob_col", 1) as blob: + blob.write(b"hello, ") + blob.write(b"world.") + # Modify the first and last bytes of our blob + blob[0] = ord("H") + blob[-1] = ord("!") + + # Read the contents of our blob + with con.blobopen("test", "blob_col", 1) as blob: + greeting = blob.read() + + print(greeting) # outputs "b'Hello, world!'" + + .. testoutput:: + :hide: + + b'Hello, world!' .. method:: close() @@ -1678,7 +1889,30 @@ placeholders (named style). For the qmark style, ``parameters`` must be a keys for all named parameters. Any extra items are ignored. Here's an example of both styles: -.. literalinclude:: ../includes/sqlite3/execute_1.py +.. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE lang(name, first_appeared)") + + # This is the qmark style: + cur.execute("INSERT INTO lang VALUES(?, ?)", ("C", 1972)) + + # The qmark style used with executemany(): + lang_list = [ + ("Fortran", 1957), + ("Python", 1991), + ("Go", 2009), + ] + cur.executemany("INSERT INTO lang VALUES(?, ?)", lang_list) + + # And this is the named style: + cur.execute("SELECT * FROM lang WHERE first_appeared = :year", {"year": 1972}) + print(cur.fetchall()) + +.. testoutput:: + :hide: + + [('C', 1972)] .. _sqlite3-adapters: @@ -1712,7 +1946,26 @@ This can be implemented by adding a ``__conform__(self, protocol)`` method which returns the adapted value. The object passed to *protocol* will be of type :class:`PrepareProtocol`. -.. literalinclude:: ../includes/sqlite3/adapter_point_1.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __conform__(self, protocol): + if protocol is sqlite3.PrepareProtocol: + return f"{self.x};{self.y}" + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(4.0, -3.2),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 4.0;-3.2 How to register adapter callables @@ -1722,7 +1975,27 @@ The other possibility is to create a function that converts the Python object to an SQLite-compatible type. This function can then be registered using :func:`register_adapter`. -.. literalinclude:: ../includes/sqlite3/adapter_point_2.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def adapt_point(point): + return f"{point.x};{point.y}" + + sqlite3.register_adapter(Point, adapt_point) + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(1.0, 2.5),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 1.0;2.5 .. _sqlite3-converters: @@ -1764,7 +2037,50 @@ of :func:`connect`. There are three options: The following example illustrates the implicit and explicit approaches: -.. literalinclude:: ../includes/sqlite3/converter_point.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __repr__(self): + return f"Point({self.x}, {self.y})" + + def adapt_point(point): + return f"{point.x};{point.y}".encode("utf-8") + + def convert_point(s): + x, y = list(map(float, s.split(b";"))) + return Point(x, y) + + # Register the adapter and converter + sqlite3.register_adapter(Point, adapt_point) + sqlite3.register_converter("point", convert_point) + + # 1) Parse using declared types + p = Point(4.0, -3.2) + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) + cur = con.execute("CREATE TABLE test(p point)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute("SELECT p FROM test") + print("with declared types:", cur.fetchone()[0]) + cur.close() + con.close() + + # 2) Parse using column names + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) + cur = con.execute("CREATE TABLE test(p)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute('SELECT p AS "p [point]" FROM test') + print("with column names:", cur.fetchone()[0]) + +.. testoutput:: + :hide: + + with declared types: Point(4.0, -3.2) + with column names: Point(4.0, -3.2) .. _sqlite3-adapter-converter-recipes: @@ -1826,7 +2142,33 @@ objects are created implicitly and these shortcut methods return the cursor objects. This way, you can execute a ``SELECT`` statement and iterate over it directly using only a single call on the :class:`Connection` object. -.. literalinclude:: ../includes/sqlite3/shortcut_methods.py +.. testcode:: + + # Create and fill the table. + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(name, first_appeared)") + data = [ + ("C++", 1985), + ("Objective-C", 1984), + ] + con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data) + + # Print the table contents + for row in con.execute("SELECT name, first_appeared FROM lang"): + print(row) + + print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows") + + # close() is not a shortcut method and it's not called automatically; + # the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + ('C++', 1985) + ('Objective-C', 1984) + I just deleted 2 rows .. _sqlite3-connection-context-manager: @@ -1851,7 +2193,31 @@ the context manager is a no-op. The context manager neither implicitly opens a new transaction nor closes the connection. -.. literalinclude:: ../includes/sqlite3/ctx_manager.py +.. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)") + + # Successful, con.commit() is called automatically afterwards + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + + # con.rollback() is called after the with block finishes with an exception, + # the exception is still raised and must be caught + try: + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + except sqlite3.IntegrityError: + print("couldn't add Python twice") + + # Connection object used as context manager only commits or rollbacks transactions, + # so the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + couldn't add Python twice .. _sqlite3-uri-tricks: From webhook-mailer at python.org Wed Aug 31 02:03:43 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 31 Aug 2022 06:03:43 -0000 Subject: [Python-checkins] gh-96414: Inline code examples in sqlite3 docs (GH-96442) Message-ID: <mailman.930.1661925823.3313.python-checkins@python.org> https://github.com/python/cpython/commit/d4d5e605cd74b198a6e21d5bf8fa053de2069aae commit: d4d5e605cd74b198a6e21d5bf8fa053de2069aae branch: 3.11 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-08-30T23:03:33-07:00 summary: gh-96414: Inline code examples in sqlite3 docs (GH-96442) (cherry picked from commit f7e7bf161aaec5a5cffdcec7c97e1f09e445421b) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: D Doc/includes/sqlite3/adapter_point_1.py D Doc/includes/sqlite3/adapter_point_2.py D Doc/includes/sqlite3/blob.py D Doc/includes/sqlite3/collation_reverse.py D Doc/includes/sqlite3/converter_point.py D Doc/includes/sqlite3/ctx_manager.py D Doc/includes/sqlite3/execute_1.py D Doc/includes/sqlite3/load_extension.py D Doc/includes/sqlite3/md5func.py D Doc/includes/sqlite3/mysumaggr.py D Doc/includes/sqlite3/row_factory.py D Doc/includes/sqlite3/shortcut_methods.py D Doc/includes/sqlite3/sumintwindow.py D Doc/includes/sqlite3/text_factory.py M Doc/library/sqlite3.rst diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py deleted file mode 100644 index 77daf8f16d22..000000000000 --- a/Doc/includes/sqlite3/adapter_point_1.py +++ /dev/null @@ -1,18 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __conform__(self, protocol): - if protocol is sqlite3.PrepareProtocol: - return "%f;%f" % (self.x, self.y) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py deleted file mode 100644 index cb86331692b6..000000000000 --- a/Doc/includes/sqlite3/adapter_point_2.py +++ /dev/null @@ -1,19 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - -def adapt_point(point): - return "%f;%f" % (point.x, point.y) - -sqlite3.register_adapter(Point, adapt_point) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/blob.py b/Doc/includes/sqlite3/blob.py deleted file mode 100644 index ff58d6c352b6..000000000000 --- a/Doc/includes/sqlite3/blob.py +++ /dev/null @@ -1,19 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.execute("create table test(blob_col blob)") -con.execute("insert into test(blob_col) values (zeroblob(13))") - -# Write to our blob, using two write operations: -with con.blobopen("test", "blob_col", 1) as blob: - blob.write(b"hello, ") - blob.write(b"world.") - # Modify the first and last bytes of our blob - blob[0] = ord("H") - blob[-1] = ord("!") - -# Read the contents of our blob -with con.blobopen("test", "blob_col", 1) as blob: - greeting = blob.read() - -print(greeting) # outputs "b'Hello, world!'" diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py deleted file mode 100644 index 3504a350a04e..000000000000 --- a/Doc/includes/sqlite3/collation_reverse.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -def collate_reverse(string1, string2): - if string1 == string2: - return 0 - elif string1 < string2: - return 1 - else: - return -1 - -con = sqlite3.connect(":memory:") -con.create_collation("reverse", collate_reverse) - -cur = con.cursor() -cur.execute("create table test(x)") -cur.executemany("insert into test(x) values (?)", [("a",), ("b",)]) -cur.execute("select x from test order by x collate reverse") -for row in cur: - print(row) -con.close() diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py deleted file mode 100644 index 147807a2225f..000000000000 --- a/Doc/includes/sqlite3/converter_point.py +++ /dev/null @@ -1,40 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __repr__(self): - return f"Point({self.x}, {self.y})" - -def adapt_point(point): - return f"{point.x};{point.y}".encode("utf-8") - -def convert_point(s): - x, y = list(map(float, s.split(b";"))) - return Point(x, y) - -# Register the adapter and converter -sqlite3.register_adapter(Point, adapt_point) -sqlite3.register_converter("point", convert_point) - -# 1) Parse using declared types -p = Point(4.0, -3.2) -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) -cur = con.execute("create table test(p point)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute("select p from test") -print("with declared types:", cur.fetchone()[0]) -cur.close() -con.close() - -# 2) Parse using column names -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) -cur = con.execute("create table test(p)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute('select p as "p [point]" from test') -print("with column names:", cur.fetchone()[0]) -cur.close() -con.close() diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py deleted file mode 100644 index 2e1175ef44c6..000000000000 --- a/Doc/includes/sqlite3/ctx_manager.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.execute("create table lang (id integer primary key, name varchar unique)") - -# Successful, con.commit() is called automatically afterwards -with con: - con.execute("insert into lang(name) values (?)", ("Python",)) - -# con.rollback() is called after the with block finishes with an exception, the -# exception is still raised and must be caught -try: - with con: - con.execute("insert into lang(name) values (?)", ("Python",)) -except sqlite3.IntegrityError: - print("couldn't add Python twice") - -# Connection object used as context manager only commits or rollbacks transactions, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py deleted file mode 100644 index ee0000e2b94a..000000000000 --- a/Doc/includes/sqlite3/execute_1.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.execute("create table lang (name, first_appeared)") - -# This is the qmark style: -cur.execute("insert into lang values (?, ?)", ("C", 1972)) - -# The qmark style used with executemany(): -lang_list = [ - ("Fortran", 1957), - ("Python", 1991), - ("Go", 2009), -] -cur.executemany("insert into lang values (?, ?)", lang_list) - -# And this is the named style: -cur.execute("select * from lang where first_appeared=:year", {"year": 1972}) -print(cur.fetchall()) - -con.close() diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py deleted file mode 100644 index 624cfe262f38..000000000000 --- a/Doc/includes/sqlite3/load_extension.py +++ /dev/null @@ -1,28 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") - -# enable extension loading -con.enable_load_extension(True) - -# Load the fulltext search extension -con.execute("select load_extension('./fts3.so')") - -# alternatively you can load the extension using an API call: -# con.load_extension("./fts3.so") - -# disable extension loading again -con.enable_load_extension(False) - -# example from SQLite wiki -con.execute("create virtual table recipe using fts3(name, ingredients)") -con.executescript(""" - insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes'); - insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery'); - insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour'); - insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter'); - """) -for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"): - print(row) - -con.close() diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py deleted file mode 100644 index 16dc348bf001..000000000000 --- a/Doc/includes/sqlite3/md5func.py +++ /dev/null @@ -1,13 +0,0 @@ -import sqlite3 -import hashlib - -def md5sum(t): - return hashlib.md5(t).hexdigest() - -con = sqlite3.connect(":memory:") -con.create_function("md5", 1, md5sum) -cur = con.cursor() -cur.execute("select md5(?)", (b"foo",)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py deleted file mode 100644 index 11f96395b6c4..000000000000 --- a/Doc/includes/sqlite3/mysumaggr.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -class MySum: - def __init__(self): - self.count = 0 - - def step(self, value): - self.count += value - - def finalize(self): - return self.count - -con = sqlite3.connect(":memory:") -con.create_aggregate("mysum", 1, MySum) -cur = con.cursor() -cur.execute("create table test(i)") -cur.execute("insert into test(i) values (1)") -cur.execute("insert into test(i) values (2)") -cur.execute("select mysum(i) from test") -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py deleted file mode 100644 index 9de6e7b1b905..000000000000 --- a/Doc/includes/sqlite3/row_factory.py +++ /dev/null @@ -1,15 +0,0 @@ -import sqlite3 - -def dict_factory(cursor, row): - d = {} - for idx, col in enumerate(cursor.description): - d[col[0]] = row[idx] - return d - -con = sqlite3.connect(":memory:") -con.row_factory = dict_factory -cur = con.cursor() -cur.execute("select 1 as a") -print(cur.fetchone()["a"]) - -con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py deleted file mode 100644 index 48ea6fad15a8..000000000000 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ /dev/null @@ -1,24 +0,0 @@ -import sqlite3 - -langs = [ - ("C++", 1985), - ("Objective-C", 1984), -] - -con = sqlite3.connect(":memory:") - -# Create the table -con.execute("create table lang(name, first_appeared)") - -# Fill the table -con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs) - -# Print the table contents -for row in con.execute("select name, first_appeared from lang"): - print(row) - -print("I just deleted", con.execute("delete from lang").rowcount, "rows") - -# close is not a shortcut method and it's not called automatically, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/sumintwindow.py b/Doc/includes/sqlite3/sumintwindow.py deleted file mode 100644 index 0e915d6cc6ae..000000000000 --- a/Doc/includes/sqlite3/sumintwindow.py +++ /dev/null @@ -1,46 +0,0 @@ -# Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc -import sqlite3 - - -class WindowSumInt: - def __init__(self): - self.count = 0 - - def step(self, value): - """Adds a row to the current window.""" - self.count += value - - def value(self): - """Returns the current value of the aggregate.""" - return self.count - - def inverse(self, value): - """Removes a row from the current window.""" - self.count -= value - - def finalize(self): - """Returns the final value of the aggregate. - - Any clean-up actions should be placed here. - """ - return self.count - - -con = sqlite3.connect(":memory:") -cur = con.execute("create table test(x, y)") -values = [ - ("a", 4), - ("b", 5), - ("c", 3), - ("d", 8), - ("e", 1), -] -cur.executemany("insert into test values(?, ?)", values) -con.create_window_function("sumint", 1, WindowSumInt) -cur.execute(""" - select x, sumint(y) over ( - order by x rows between 1 preceding and 1 following - ) as sum_y - from test order by x -""") -print(cur.fetchall()) diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py deleted file mode 100644 index c0d87cd55911..000000000000 --- a/Doc/includes/sqlite3/text_factory.py +++ /dev/null @@ -1,29 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -AUSTRIA = "?sterreich" - -# by default, rows are returned as str -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert row[0] == AUSTRIA - -# but we can make sqlite3 always return bytestrings ... -con.text_factory = bytes -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert type(row[0]) is bytes -# the bytestrings will be encoded in UTF-8, unless you stored garbage in the -# database ... -assert row[0] == AUSTRIA.encode("utf-8") - -# we can also implement a custom text_factory ... -# here we implement one that appends "foo" to all strings -con.text_factory = lambda x: x.decode("utf-8") + "foo" -cur.execute("select ?", ("bar",)) -row = cur.fetchone() -assert row[0] == "barfoo" - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 2c58ef71c33f..fc288f6f7399 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -588,7 +588,25 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/row_factory.py + .. testcode:: + + def dict_factory(cursor, row): + d = {} + for idx, col in enumerate(cursor.description): + d[col[0]] = row[idx] + return d + + con = sqlite3.connect(":memory:") + con.row_factory = dict_factory + cur = con.execute("SELECT 1 AS a") + print(cur.fetchone()["a"]) + + con.close() + + .. testoutput:: + :hide: + + 1 If returning a tuple doesn't suffice and you want name-based access to columns, you should consider setting :attr:`row_factory` to the @@ -609,7 +627,35 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/text_factory.py + .. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + AUSTRIA = "?sterreich" + + # by default, rows are returned as str + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert row[0] == AUSTRIA + + # but we can make sqlite3 always return bytestrings ... + con.text_factory = bytes + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert type(row[0]) is bytes + # the bytestrings will be encoded in UTF-8, unless you stored garbage in the + # database ... + assert row[0] == AUSTRIA.encode("utf-8") + + # we can also implement a custom text_factory ... + # here we implement one that appends "foo" to all strings + con.text_factory = lambda x: x.decode("utf-8") + "foo" + cur.execute("SELECT ?", ("bar",)) + row = cur.fetchone() + assert row[0] == "barfoo" + + con.close() .. attribute:: total_changes @@ -725,7 +771,16 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/md5func.py + .. doctest:: + + >>> import hashlib + >>> def md5sum(t): + ... return hashlib.md5(t).hexdigest() + >>> con = sqlite3.connect(":memory:") + >>> con.create_function("md5", 1, md5sum) + >>> for row in con.execute("SELECT md5(?)", (b"foo",)): + ... print(row) + ('acbd18db4cc2f85cedef654fccc4a4d8',) .. method:: create_aggregate(name, /, n_arg, aggregate_class) @@ -754,7 +809,32 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/mysumaggr.py + .. testcode:: + + class MySum: + def __init__(self): + self.count = 0 + + def step(self, value): + self.count += value + + def finalize(self): + return self.count + + con = sqlite3.connect(":memory:") + con.create_aggregate("mysum", 1, MySum) + cur = con.execute("CREATE TABLE test(i)") + cur.execute("INSERT INTO test(i) VALUES(1)") + cur.execute("INSERT INTO test(i) VALUES(2)") + cur.execute("SELECT mysum(i) FROM test") + print(cur.fetchone()[0]) + + con.close() + + .. testoutput:: + :hide: + + 3 .. method:: create_window_function(name, num_params, aggregate_class, /) @@ -792,8 +872,56 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/sumintwindow.py + .. testcode:: + + # Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc + class WindowSumInt: + def __init__(self): + self.count = 0 + def step(self, value): + """Add a row to the current window.""" + self.count += value + + def value(self): + """Return the current value of the aggregate.""" + return self.count + + def inverse(self, value): + """Remove a row from the current window.""" + self.count -= value + + def finalize(self): + """Return the final value of the aggregate. + + Any clean-up actions should be placed here. + """ + return self.count + + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE test(x, y)") + values = [ + ("a", 4), + ("b", 5), + ("c", 3), + ("d", 8), + ("e", 1), + ] + cur.executemany("INSERT INTO test VALUES(?, ?)", values) + con.create_window_function("sumint", 1, WindowSumInt) + cur.execute(""" + SELECT x, sumint(y) OVER ( + ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) AS sum_y + FROM test ORDER BY x + """) + print(cur.fetchall()) + + .. testoutput:: + :hide: + + [('a', 9), ('b', 12), ('c', 16), ('d', 12), ('e', 9)] .. method:: create_collation(name, callable) @@ -807,7 +935,31 @@ Connection objects The following example shows a reverse sorting collation: - .. literalinclude:: ../includes/sqlite3/collation_reverse.py + .. testcode:: + + def collate_reverse(string1, string2): + if string1 == string2: + return 0 + elif string1 < string2: + return 1 + else: + return -1 + + con = sqlite3.connect(":memory:") + con.create_collation("reverse", collate_reverse) + + cur = con.execute("CREATE TABLE test(x)") + cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)]) + cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse") + for row in cur: + print(row) + con.close() + + .. testoutput:: + :hide: + + ('b',) + ('a',) Remove a collation function by setting *callable* to ``None``. @@ -912,7 +1064,43 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.enable_load_extension`` auditing event. - .. literalinclude:: ../includes/sqlite3/load_extension.py + .. testsetup:: sqlite3.loadext + + import sqlite3 + con = sqlite3.connect(":memory:") + + .. testcode:: sqlite3.loadext + :skipif: True # not testable at the moment + + con.enable_load_extension(True) + + # Load the fulltext search extension + con.execute("select load_extension('./fts3.so')") + + # alternatively you can load the extension using an API call: + # con.load_extension("./fts3.so") + + # disable extension loading again + con.enable_load_extension(False) + + # example from SQLite wiki + con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)") + con.executescript(""" + INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery'); + INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter'); + """) + for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"): + print(row) + + con.close() + + .. testoutput:: sqlite3.loadext + :hide: + + (2, 'broccoli pie', 'broccoli cheese onions flour') + (3, 'pumpkin pie', 'pumpkin sugar flour butter') .. method:: load_extension(path, /) @@ -1387,7 +1575,30 @@ Blob objects Use the :class:`Blob` as a :term:`context manager` to ensure that the blob handle is closed after use. - .. literalinclude:: ../includes/sqlite3/blob.py + .. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE test(blob_col blob)") + con.execute("INSERT INTO test(blob_col) VALUES(zeroblob(13))") + + # Write to our blob, using two write operations: + with con.blobopen("test", "blob_col", 1) as blob: + blob.write(b"hello, ") + blob.write(b"world.") + # Modify the first and last bytes of our blob + blob[0] = ord("H") + blob[-1] = ord("!") + + # Read the contents of our blob + with con.blobopen("test", "blob_col", 1) as blob: + greeting = blob.read() + + print(greeting) # outputs "b'Hello, world!'" + + .. testoutput:: + :hide: + + b'Hello, world!' .. method:: close() @@ -1640,7 +1851,30 @@ placeholders (named style). For the qmark style, ``parameters`` must be a keys for all named parameters. Any extra items are ignored. Here's an example of both styles: -.. literalinclude:: ../includes/sqlite3/execute_1.py +.. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE lang(name, first_appeared)") + + # This is the qmark style: + cur.execute("INSERT INTO lang VALUES(?, ?)", ("C", 1972)) + + # The qmark style used with executemany(): + lang_list = [ + ("Fortran", 1957), + ("Python", 1991), + ("Go", 2009), + ] + cur.executemany("INSERT INTO lang VALUES(?, ?)", lang_list) + + # And this is the named style: + cur.execute("SELECT * FROM lang WHERE first_appeared = :year", {"year": 1972}) + print(cur.fetchall()) + +.. testoutput:: + :hide: + + [('C', 1972)] .. _sqlite3-adapters: @@ -1674,7 +1908,26 @@ This can be implemented by adding a ``__conform__(self, protocol)`` method which returns the adapted value. The object passed to *protocol* will be of type :class:`PrepareProtocol`. -.. literalinclude:: ../includes/sqlite3/adapter_point_1.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __conform__(self, protocol): + if protocol is sqlite3.PrepareProtocol: + return f"{self.x};{self.y}" + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(4.0, -3.2),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 4.0;-3.2 How to register adapter callables @@ -1684,7 +1937,27 @@ The other possibility is to create a function that converts the Python object to an SQLite-compatible type. This function can then be registered using :func:`register_adapter`. -.. literalinclude:: ../includes/sqlite3/adapter_point_2.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def adapt_point(point): + return f"{point.x};{point.y}" + + sqlite3.register_adapter(Point, adapt_point) + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(1.0, 2.5),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 1.0;2.5 .. _sqlite3-converters: @@ -1726,7 +1999,50 @@ of :func:`connect`. There are three options: The following example illustrates the implicit and explicit approaches: -.. literalinclude:: ../includes/sqlite3/converter_point.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __repr__(self): + return f"Point({self.x}, {self.y})" + + def adapt_point(point): + return f"{point.x};{point.y}".encode("utf-8") + + def convert_point(s): + x, y = list(map(float, s.split(b";"))) + return Point(x, y) + + # Register the adapter and converter + sqlite3.register_adapter(Point, adapt_point) + sqlite3.register_converter("point", convert_point) + + # 1) Parse using declared types + p = Point(4.0, -3.2) + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) + cur = con.execute("CREATE TABLE test(p point)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute("SELECT p FROM test") + print("with declared types:", cur.fetchone()[0]) + cur.close() + con.close() + + # 2) Parse using column names + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) + cur = con.execute("CREATE TABLE test(p)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute('SELECT p AS "p [point]" FROM test') + print("with column names:", cur.fetchone()[0]) + +.. testoutput:: + :hide: + + with declared types: Point(4.0, -3.2) + with column names: Point(4.0, -3.2) .. _sqlite3-adapter-converter-recipes: @@ -1788,7 +2104,33 @@ objects are created implicitly and these shortcut methods return the cursor objects. This way, you can execute a ``SELECT`` statement and iterate over it directly using only a single call on the :class:`Connection` object. -.. literalinclude:: ../includes/sqlite3/shortcut_methods.py +.. testcode:: + + # Create and fill the table. + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(name, first_appeared)") + data = [ + ("C++", 1985), + ("Objective-C", 1984), + ] + con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data) + + # Print the table contents + for row in con.execute("SELECT name, first_appeared FROM lang"): + print(row) + + print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows") + + # close() is not a shortcut method and it's not called automatically; + # the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + ('C++', 1985) + ('Objective-C', 1984) + I just deleted 2 rows .. _sqlite3-connection-context-manager: @@ -1813,7 +2155,31 @@ the context manager is a no-op. The context manager neither implicitly opens a new transaction nor closes the connection. -.. literalinclude:: ../includes/sqlite3/ctx_manager.py +.. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)") + + # Successful, con.commit() is called automatically afterwards + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + + # con.rollback() is called after the with block finishes with an exception, + # the exception is still raised and must be caught + try: + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + except sqlite3.IntegrityError: + print("couldn't add Python twice") + + # Connection object used as context manager only commits or rollbacks transactions, + # so the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + couldn't add Python twice .. _sqlite3-uri-tricks: From webhook-mailer at python.org Wed Aug 31 04:11:01 2022 From: webhook-mailer at python.org (erlend-aasland) Date: Wed, 31 Aug 2022 08:11:01 -0000 Subject: [Python-checkins] [3.10] gh-96414: Inline code examples in sqlite3 docs (GH-96442). (#96453) Message-ID: <mailman.931.1661933462.3313.python-checkins@python.org> https://github.com/python/cpython/commit/2ecc195498f3b1256fabc2b66e0d8f6d671fa1d7 commit: 2ecc195498f3b1256fabc2b66e0d8f6d671fa1d7 branch: 3.10 author: Erlend E. Aasland <erlend.aasland at protonmail.com> committer: erlend-aasland <erlend.aasland at protonmail.com> date: 2022-08-31T10:10:55+02:00 summary: [3.10] gh-96414: Inline code examples in sqlite3 docs (GH-96442). (#96453) * [3.10] gh-96414: Inline code examples in sqlite3 docs (GH-96442). (cherry picked from commit f7e7bf161aaec5a5cffdcec7c97e1f09e445421b) Co-authored-by: Erlend E. Aasland <erlend.aasland at protonmail.com> files: D Doc/includes/sqlite3/adapter_point_1.py D Doc/includes/sqlite3/adapter_point_2.py D Doc/includes/sqlite3/collation_reverse.py D Doc/includes/sqlite3/converter_point.py D Doc/includes/sqlite3/ctx_manager.py D Doc/includes/sqlite3/execute_1.py D Doc/includes/sqlite3/load_extension.py D Doc/includes/sqlite3/md5func.py D Doc/includes/sqlite3/mysumaggr.py D Doc/includes/sqlite3/row_factory.py D Doc/includes/sqlite3/shortcut_methods.py D Doc/includes/sqlite3/text_factory.py M Doc/library/sqlite3.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py deleted file mode 100644 index 77daf8f16d22..000000000000 --- a/Doc/includes/sqlite3/adapter_point_1.py +++ /dev/null @@ -1,18 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __conform__(self, protocol): - if protocol is sqlite3.PrepareProtocol: - return "%f;%f" % (self.x, self.y) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py deleted file mode 100644 index cb86331692b6..000000000000 --- a/Doc/includes/sqlite3/adapter_point_2.py +++ /dev/null @@ -1,19 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - -def adapt_point(point): - return "%f;%f" % (point.x, point.y) - -sqlite3.register_adapter(Point, adapt_point) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py deleted file mode 100644 index 3504a350a04e..000000000000 --- a/Doc/includes/sqlite3/collation_reverse.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -def collate_reverse(string1, string2): - if string1 == string2: - return 0 - elif string1 < string2: - return 1 - else: - return -1 - -con = sqlite3.connect(":memory:") -con.create_collation("reverse", collate_reverse) - -cur = con.cursor() -cur.execute("create table test(x)") -cur.executemany("insert into test(x) values (?)", [("a",), ("b",)]) -cur.execute("select x from test order by x collate reverse") -for row in cur: - print(row) -con.close() diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py deleted file mode 100644 index 147807a2225f..000000000000 --- a/Doc/includes/sqlite3/converter_point.py +++ /dev/null @@ -1,40 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __repr__(self): - return f"Point({self.x}, {self.y})" - -def adapt_point(point): - return f"{point.x};{point.y}".encode("utf-8") - -def convert_point(s): - x, y = list(map(float, s.split(b";"))) - return Point(x, y) - -# Register the adapter and converter -sqlite3.register_adapter(Point, adapt_point) -sqlite3.register_converter("point", convert_point) - -# 1) Parse using declared types -p = Point(4.0, -3.2) -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) -cur = con.execute("create table test(p point)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute("select p from test") -print("with declared types:", cur.fetchone()[0]) -cur.close() -con.close() - -# 2) Parse using column names -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) -cur = con.execute("create table test(p)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute('select p as "p [point]" from test') -print("with column names:", cur.fetchone()[0]) -cur.close() -con.close() diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py deleted file mode 100644 index 2e1175ef44c6..000000000000 --- a/Doc/includes/sqlite3/ctx_manager.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.execute("create table lang (id integer primary key, name varchar unique)") - -# Successful, con.commit() is called automatically afterwards -with con: - con.execute("insert into lang(name) values (?)", ("Python",)) - -# con.rollback() is called after the with block finishes with an exception, the -# exception is still raised and must be caught -try: - with con: - con.execute("insert into lang(name) values (?)", ("Python",)) -except sqlite3.IntegrityError: - print("couldn't add Python twice") - -# Connection object used as context manager only commits or rollbacks transactions, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py deleted file mode 100644 index ee0000e2b94a..000000000000 --- a/Doc/includes/sqlite3/execute_1.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.execute("create table lang (name, first_appeared)") - -# This is the qmark style: -cur.execute("insert into lang values (?, ?)", ("C", 1972)) - -# The qmark style used with executemany(): -lang_list = [ - ("Fortran", 1957), - ("Python", 1991), - ("Go", 2009), -] -cur.executemany("insert into lang values (?, ?)", lang_list) - -# And this is the named style: -cur.execute("select * from lang where first_appeared=:year", {"year": 1972}) -print(cur.fetchall()) - -con.close() diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py deleted file mode 100644 index 624cfe262f38..000000000000 --- a/Doc/includes/sqlite3/load_extension.py +++ /dev/null @@ -1,28 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") - -# enable extension loading -con.enable_load_extension(True) - -# Load the fulltext search extension -con.execute("select load_extension('./fts3.so')") - -# alternatively you can load the extension using an API call: -# con.load_extension("./fts3.so") - -# disable extension loading again -con.enable_load_extension(False) - -# example from SQLite wiki -con.execute("create virtual table recipe using fts3(name, ingredients)") -con.executescript(""" - insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes'); - insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery'); - insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour'); - insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter'); - """) -for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"): - print(row) - -con.close() diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py deleted file mode 100644 index 16dc348bf001..000000000000 --- a/Doc/includes/sqlite3/md5func.py +++ /dev/null @@ -1,13 +0,0 @@ -import sqlite3 -import hashlib - -def md5sum(t): - return hashlib.md5(t).hexdigest() - -con = sqlite3.connect(":memory:") -con.create_function("md5", 1, md5sum) -cur = con.cursor() -cur.execute("select md5(?)", (b"foo",)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py deleted file mode 100644 index 11f96395b6c4..000000000000 --- a/Doc/includes/sqlite3/mysumaggr.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -class MySum: - def __init__(self): - self.count = 0 - - def step(self, value): - self.count += value - - def finalize(self): - return self.count - -con = sqlite3.connect(":memory:") -con.create_aggregate("mysum", 1, MySum) -cur = con.cursor() -cur.execute("create table test(i)") -cur.execute("insert into test(i) values (1)") -cur.execute("insert into test(i) values (2)") -cur.execute("select mysum(i) from test") -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py deleted file mode 100644 index 9de6e7b1b905..000000000000 --- a/Doc/includes/sqlite3/row_factory.py +++ /dev/null @@ -1,15 +0,0 @@ -import sqlite3 - -def dict_factory(cursor, row): - d = {} - for idx, col in enumerate(cursor.description): - d[col[0]] = row[idx] - return d - -con = sqlite3.connect(":memory:") -con.row_factory = dict_factory -cur = con.cursor() -cur.execute("select 1 as a") -print(cur.fetchone()["a"]) - -con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py deleted file mode 100644 index 48ea6fad15a8..000000000000 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ /dev/null @@ -1,24 +0,0 @@ -import sqlite3 - -langs = [ - ("C++", 1985), - ("Objective-C", 1984), -] - -con = sqlite3.connect(":memory:") - -# Create the table -con.execute("create table lang(name, first_appeared)") - -# Fill the table -con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs) - -# Print the table contents -for row in con.execute("select name, first_appeared from lang"): - print(row) - -print("I just deleted", con.execute("delete from lang").rowcount, "rows") - -# close is not a shortcut method and it's not called automatically, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py deleted file mode 100644 index c0d87cd55911..000000000000 --- a/Doc/includes/sqlite3/text_factory.py +++ /dev/null @@ -1,29 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -AUSTRIA = "?sterreich" - -# by default, rows are returned as str -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert row[0] == AUSTRIA - -# but we can make sqlite3 always return bytestrings ... -con.text_factory = bytes -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert type(row[0]) is bytes -# the bytestrings will be encoded in UTF-8, unless you stored garbage in the -# database ... -assert row[0] == AUSTRIA.encode("utf-8") - -# we can also implement a custom text_factory ... -# here we implement one that appends "foo" to all strings -con.text_factory = lambda x: x.decode("utf-8") + "foo" -cur.execute("select ?", ("bar",)) -row = cur.fetchone() -assert row[0] == "barfoo" - -con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 27645b05364e..b24fa48ef829 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -546,7 +546,25 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/row_factory.py + .. testcode:: + + def dict_factory(cursor, row): + d = {} + for idx, col in enumerate(cursor.description): + d[col[0]] = row[idx] + return d + + con = sqlite3.connect(":memory:") + con.row_factory = dict_factory + cur = con.execute("SELECT 1 AS a") + print(cur.fetchone()["a"]) + + con.close() + + .. testoutput:: + :hide: + + 1 If returning a tuple doesn't suffice and you want name-based access to columns, you should consider setting :attr:`row_factory` to the @@ -567,7 +585,35 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/text_factory.py + .. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + AUSTRIA = "?sterreich" + + # by default, rows are returned as str + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert row[0] == AUSTRIA + + # but we can make sqlite3 always return bytestrings ... + con.text_factory = bytes + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert type(row[0]) is bytes + # the bytestrings will be encoded in UTF-8, unless you stored garbage in the + # database ... + assert row[0] == AUSTRIA.encode("utf-8") + + # we can also implement a custom text_factory ... + # here we implement one that appends "foo" to all strings + con.text_factory = lambda x: x.decode("utf-8") + "foo" + cur.execute("SELECT ?", ("bar",)) + row = cur.fetchone() + assert row[0] == "barfoo" + + con.close() .. attribute:: total_changes @@ -648,7 +694,16 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/md5func.py + .. doctest:: + + >>> import hashlib + >>> def md5sum(t): + ... return hashlib.md5(t).hexdigest() + >>> con = sqlite3.connect(":memory:") + >>> con.create_function("md5", 1, md5sum) + >>> for row in con.execute("SELECT md5(?)", (b"foo",)): + ... print(row) + ('acbd18db4cc2f85cedef654fccc4a4d8',) .. method:: create_aggregate(name, /, n_arg, aggregate_class) @@ -677,7 +732,32 @@ Connection objects Example: - .. literalinclude:: ../includes/sqlite3/mysumaggr.py + .. testcode:: + + class MySum: + def __init__(self): + self.count = 0 + + def step(self, value): + self.count += value + + def finalize(self): + return self.count + + con = sqlite3.connect(":memory:") + con.create_aggregate("mysum", 1, MySum) + cur = con.execute("CREATE TABLE test(i)") + cur.execute("INSERT INTO test(i) VALUES(1)") + cur.execute("INSERT INTO test(i) VALUES(2)") + cur.execute("SELECT mysum(i) FROM test") + print(cur.fetchone()[0]) + + con.close() + + .. testoutput:: + :hide: + + 3 .. method:: create_collation(name, callable) @@ -692,7 +772,31 @@ Connection objects The following example shows a reverse sorting collation: - .. literalinclude:: ../includes/sqlite3/collation_reverse.py + .. testcode:: + + def collate_reverse(string1, string2): + if string1 == string2: + return 0 + elif string1 < string2: + return 1 + else: + return -1 + + con = sqlite3.connect(":memory:") + con.create_collation("reverse", collate_reverse) + + cur = con.execute("CREATE TABLE test(x)") + cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)]) + cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse") + for row in cur: + print(row) + con.close() + + .. testoutput:: + :hide: + + ('b',) + ('a',) Remove a collation function by setting *callable* to ``None``. @@ -788,7 +892,43 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.enable_load_extension`` auditing event. - .. literalinclude:: ../includes/sqlite3/load_extension.py + .. testsetup:: sqlite3.loadext + + import sqlite3 + con = sqlite3.connect(":memory:") + + .. testcode:: sqlite3.loadext + :skipif: True # not testable at the moment + + con.enable_load_extension(True) + + # Load the fulltext search extension + con.execute("select load_extension('./fts3.so')") + + # alternatively you can load the extension using an API call: + # con.load_extension("./fts3.so") + + # disable extension loading again + con.enable_load_extension(False) + + # example from SQLite wiki + con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)") + con.executescript(""" + INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery'); + INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter'); + """) + for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"): + print(row) + + con.close() + + .. testoutput:: sqlite3.loadext + :hide: + + (2, 'broccoli pie', 'broccoli cheese onions flour') + (3, 'pumpkin pie', 'pumpkin sugar flour butter') .. method:: load_extension(path, /) @@ -1326,7 +1466,30 @@ placeholders (named style). For the qmark style, ``parameters`` must be a keys for all named parameters. Any extra items are ignored. Here's an example of both styles: -.. literalinclude:: ../includes/sqlite3/execute_1.py +.. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE lang(name, first_appeared)") + + # This is the qmark style: + cur.execute("INSERT INTO lang VALUES(?, ?)", ("C", 1972)) + + # The qmark style used with executemany(): + lang_list = [ + ("Fortran", 1957), + ("Python", 1991), + ("Go", 2009), + ] + cur.executemany("INSERT INTO lang VALUES(?, ?)", lang_list) + + # And this is the named style: + cur.execute("SELECT * FROM lang WHERE first_appeared = :year", {"year": 1972}) + print(cur.fetchall()) + +.. testoutput:: + :hide: + + [('C', 1972)] .. _sqlite3-adapters: @@ -1360,7 +1523,26 @@ This can be implemented by adding a ``__conform__(self, protocol)`` method which returns the adapted value. The object passed to *protocol* will be of type :class:`PrepareProtocol`. -.. literalinclude:: ../includes/sqlite3/adapter_point_1.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __conform__(self, protocol): + if protocol is sqlite3.PrepareProtocol: + return f"{self.x};{self.y}" + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(4.0, -3.2),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 4.0;-3.2 How to register adapter callables @@ -1370,7 +1552,27 @@ The other possibility is to create a function that converts the Python object to an SQLite-compatible type. This function can then be registered using :func:`register_adapter`. -.. literalinclude:: ../includes/sqlite3/adapter_point_2.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def adapt_point(point): + return f"{point.x};{point.y}" + + sqlite3.register_adapter(Point, adapt_point) + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(1.0, 2.5),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 1.0;2.5 .. _sqlite3-converters: @@ -1412,7 +1614,50 @@ of :func:`connect`. There are three options: The following example illustrates the implicit and explicit approaches: -.. literalinclude:: ../includes/sqlite3/converter_point.py +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __repr__(self): + return f"Point({self.x}, {self.y})" + + def adapt_point(point): + return f"{point.x};{point.y}".encode("utf-8") + + def convert_point(s): + x, y = list(map(float, s.split(b";"))) + return Point(x, y) + + # Register the adapter and converter + sqlite3.register_adapter(Point, adapt_point) + sqlite3.register_converter("point", convert_point) + + # 1) Parse using declared types + p = Point(4.0, -3.2) + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) + cur = con.execute("CREATE TABLE test(p point)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute("SELECT p FROM test") + print("with declared types:", cur.fetchone()[0]) + cur.close() + con.close() + + # 2) Parse using column names + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) + cur = con.execute("CREATE TABLE test(p)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute('SELECT p AS "p [point]" FROM test') + print("with column names:", cur.fetchone()[0]) + +.. testoutput:: + :hide: + + with declared types: Point(4.0, -3.2) + with column names: Point(4.0, -3.2) .. _sqlite3-adapter-converter-recipes: @@ -1474,7 +1719,33 @@ objects are created implicitly and these shortcut methods return the cursor objects. This way, you can execute a ``SELECT`` statement and iterate over it directly using only a single call on the :class:`Connection` object. -.. literalinclude:: ../includes/sqlite3/shortcut_methods.py +.. testcode:: + + # Create and fill the table. + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(name, first_appeared)") + data = [ + ("C++", 1985), + ("Objective-C", 1984), + ] + con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data) + + # Print the table contents + for row in con.execute("SELECT name, first_appeared FROM lang"): + print(row) + + print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows") + + # close() is not a shortcut method and it's not called automatically; + # the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + ('C++', 1985) + ('Objective-C', 1984) + I just deleted 2 rows .. _sqlite3-connection-context-manager: @@ -1499,7 +1770,31 @@ the context manager is a no-op. The context manager neither implicitly opens a new transaction nor closes the connection. -.. literalinclude:: ../includes/sqlite3/ctx_manager.py +.. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)") + + # Successful, con.commit() is called automatically afterwards + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + + # con.rollback() is called after the with block finishes with an exception, + # the exception is still raised and must be caught + try: + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + except sqlite3.IntegrityError: + print("couldn't add Python twice") + + # Connection object used as context manager only commits or rollbacks transactions, + # so the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + couldn't add Python twice .. _sqlite3-uri-tricks: diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index a3380344db3b..75049783e19c 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -212,7 +212,7 @@ library/smtplib,,:port,method must support that as well as a regular host:port library/socket,,::,'5aef:2b::8' library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) -library/sqlite3,,:year,"cur.execute(""select * from lang where first_appeared=:year"", {""year"": 1972})" +library/sqlite3,,:year,"cur.execute(""SELECT * FROM lang WHERE first_appeared = :year"", {""year"": 1972})" library/sqlite3,,:memory, library/sqlite3,,:mem1,"db = ""file:mem1?mode=memory&cache=shared""" library/sqlite3,,:nosuchdb,">>> con = sqlite3.connect(""file:nosuchdb.db?mode=rw"", uri=True)" From webhook-mailer at python.org Wed Aug 31 05:50:59 2022 From: webhook-mailer at python.org (vsajip) Date: Wed, 31 Aug 2022 09:50:59 -0000 Subject: [Python-checkins] gh-89258: Add a getChildren() method to logging.Logger. (GH-96444) Message-ID: <mailman.932.1661939460.3313.python-checkins@python.org> https://github.com/python/cpython/commit/29f1b0bb1ff73dcc28f0ca7e11794141b6de58c9 commit: 29f1b0bb1ff73dcc28f0ca7e11794141b6de58c9 branch: main author: Vinay Sajip <vinay_sajip at yahoo.co.uk> committer: vsajip <vinay_sajip at yahoo.co.uk> date: 2022-08-31T10:50:29+01:00 summary: gh-89258: Add a getChildren() method to logging.Logger. (GH-96444) Co-authored-by: ?ric <merwok at netwok.org> files: A Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst M Doc/library/logging.rst M Lib/logging/__init__.py M Lib/test/test_logging.py diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 319340a39350..c3806b6f5bf8 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -170,6 +170,18 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 + .. method:: Logger.getChildren() + + Returns a set of loggers which are immediate children of this logger. So for + example ``logging.getLogger().getChildren()`` might return a set containing + loggers named ``foo`` and ``bar``, but a logger named ``foo.bar`` wouldn't be + included in the set. Likewise, ``logging.getLogger('foo').getChildren()`` might + return a set including a logger named ``foo.bar``, but it wouldn't include one + named ``foo.bar.baz``. + + .. versionadded:: 3.12 + + .. method:: Logger.debug(msg, *args, **kwargs) Logs a message with level :const:`DEBUG` on this logger. The *msg* is the diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index c3208a21f499..86e1efe6e653 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1828,6 +1828,25 @@ def getChild(self, suffix): suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) + def getChildren(self): + + def _hierlevel(logger): + if logger is logger.manager.root: + return 0 + return 1 + logger.name.count('.') + + d = self.manager.loggerDict + _acquireLock() + try: + # exclude PlaceHolders - the last check is to ensure that lower-level + # descendants aren't returned - if there are placeholders, a logger's + # parent field might point to a grandparent or ancestor thereof. + return set(item for item in d.values() + if isinstance(item, Logger) and item.parent is self and + _hierlevel(item) == 1 + _hierlevel(item.parent)) + finally: + _releaseLock() + def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index a67ed07f12c8..0c852fc1eda2 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -3717,6 +3717,20 @@ def test_child_loggers(self): self.assertIs(c2, logging.getLogger('abc.def.ghi')) self.assertIs(c2, c3) + def test_get_children(self): + r = logging.getLogger() + l1 = logging.getLogger('foo') + l2 = logging.getLogger('foo.bar') + l3 = logging.getLogger('foo.bar.baz.bozz') + l4 = logging.getLogger('bar') + kids = r.getChildren() + expected = {l1, l4} + self.assertEqual(expected, kids & expected) # might be other kids for root + self.assertNotIn(l2, expected) + kids = l1.getChildren() + self.assertEqual({l2}, kids) + kids = l2.getChildren() + self.assertEqual(set(), kids) class DerivedLogRecord(logging.LogRecord): pass diff --git a/Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst b/Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst new file mode 100644 index 000000000000..74300c108c89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst @@ -0,0 +1,2 @@ +Added a :meth:`~logging.Logger.getChildren` method to +:class:`logging.Logger`, to get the immediate child loggers of a logger. From webhook-mailer at python.org Wed Aug 31 17:24:02 2022 From: webhook-mailer at python.org (rhettinger) Date: Wed, 31 Aug 2022 21:24:02 -0000 Subject: [Python-checkins] gh-96408: Document difference between set-like view and sets. (GH-96439) Message-ID: <mailman.933.1661981042.3313.python-checkins@python.org> https://github.com/python/cpython/commit/615537e62f0a49f6888ac27046bd8de965512d9d commit: 615537e62f0a49f6888ac27046bd8de965512d9d branch: main author: Piotr Kaznowski <piotr at kazno.dev> committer: rhettinger <rhettinger at users.noreply.github.com> date: 2022-08-31T16:23:52-05:00 summary: gh-96408: Document difference between set-like view and sets. (GH-96439) files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 2c021866e29..f68cf46a6c6 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4694,7 +4694,9 @@ values are hashable, so that ``(key, value)`` pairs are unique and hashable, then the items view is also set-like. (Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class :class:`collections.abc.Set` are -available (for example, ``==``, ``<``, or ``^``). +available (for example, ``==``, ``<``, or ``^``). While using set operators, +set-like views accept any iterable as the other operand, unlike sets which only +accept sets as the input. An example of dictionary view usage:: @@ -4726,6 +4728,8 @@ An example of dictionary view usage:: {'bacon'} >>> keys ^ {'sausage', 'juice'} {'juice', 'sausage', 'bacon', 'spam'} + >>> keys | ['juice', 'juice', 'juice'] + {'juice', 'sausage', 'bacon', 'spam', 'eggs'} >>> # get back a read-only proxy for the original dictionary >>> values.mapping From webhook-mailer at python.org Wed Aug 31 19:02:33 2022 From: webhook-mailer at python.org (gvanrossum) Date: Wed, 31 Aug 2022 23:02:33 -0000 Subject: [Python-checkins] GH-96079 Fix missing field name for _AnnotatedAlias (#96080) Message-ID: <mailman.934.1661986954.3313.python-checkins@python.org> https://github.com/python/cpython/commit/0cd33e11fe6c77c423dbf3a7a9920daff012f006 commit: 0cd33e11fe6c77c423dbf3a7a9920daff012f006 branch: main author: Anh71me <iyumelive at gmail.com> committer: gvanrossum <gvanrossum at gmail.com> date: 2022-08-31T16:02:24-07:00 summary: GH-96079 Fix missing field name for _AnnotatedAlias (#96080) files: A Misc/NEWS.d/next/Library/2022-08-31-11-10-21.gh-issue-96079.uqrXdJ.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 9239673c248..015fa80942a 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -7143,6 +7143,7 @@ def test_special_attrs(self): typing.Self: 'Self', # Subscribed special forms typing.Annotated[Any, "Annotation"]: 'Annotated', + typing.Annotated[int, 'Annotation']: 'Annotated', typing.ClassVar[Any]: 'ClassVar', typing.Concatenate[Any, SpecialAttrsP]: 'Concatenate', typing.Final[Any]: 'Final', diff --git a/Lib/typing.py b/Lib/typing.py index 84fe007a9ee..95bd61c7f8c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -2101,7 +2101,7 @@ def __init__(self, origin, metadata): if isinstance(origin, _AnnotatedAlias): metadata = origin.__metadata__ + metadata origin = origin.__origin__ - super().__init__(origin, origin) + super().__init__(origin, origin, name='Annotated') self.__metadata__ = metadata def copy_with(self, params): @@ -2134,6 +2134,9 @@ def __getattr__(self, attr): return 'Annotated' return super().__getattr__(attr) + def __mro_entries__(self, bases): + return (self.__origin__,) + class Annotated: """Add context specific metadata to a type. diff --git a/Misc/NEWS.d/next/Library/2022-08-31-11-10-21.gh-issue-96079.uqrXdJ.rst b/Misc/NEWS.d/next/Library/2022-08-31-11-10-21.gh-issue-96079.uqrXdJ.rst new file mode 100644 index 00000000000..4cb8d276cbe --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-31-11-10-21.gh-issue-96079.uqrXdJ.rst @@ -0,0 +1 @@ +In :mod:`typing`, fix missing field ``name`` and incorrect ``__module__`` in _AnnotatedAlias.