diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 555e246e402bf9..f026b0f5f9454a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,3 +12,10 @@ updates: update-types: - "version-update:semver-minor" - "version-update:semver-patch" + - package-ecosystem: "pip" + directory: "/Tools/clinic/" + schedule: + interval: "monthly" + labels: + - "skip issue" + - "skip news" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f0a2dd5694c078..69b78e5567adb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -377,6 +377,8 @@ jobs: # failing when executed from inside a virtual environment. ${{ env.VENV_PYTHON }} -m test \ -W \ + -o \ + -j4 \ -x test_asyncio \ -x test_multiprocessing_fork \ -x test_multiprocessing_forkserver \ diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 00000000000000..1315bb5a966f01 --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,39 @@ +# Workflow to run mypy on select parts of the CPython repo +name: mypy + +on: + push: + branches: + - main + pull_request: + paths: + - "Tools/clinic/**" + - ".github/workflows/mypy.yml" + workflow_dispatch: + +permissions: + contents: read + +env: + PIP_DISABLE_PIP_VERSION_CHECK: 1 + FORCE_COLOR: 1 + TERM: xterm-256color # needed for FORCE_COLOR to work on mypy on Ubuntu, see https://github.com/python/mypy/issues/13817 + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + mypy: + name: Run mypy on Tools/clinic/ + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + cache: pip + cache-dependency-path: Tools/clinic/requirements-dev.txt + - run: pip install -r Tools/clinic/requirements-dev.txt + - run: mypy --config-file Tools/clinic/mypy.ini diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst index f7f038107d11fe..a2bd85b31c9a8d 100644 --- a/Doc/library/atexit.rst +++ b/Doc/library/atexit.rst @@ -20,6 +20,9 @@ at interpreter termination time they will be run in the order ``C``, ``B``, program is killed by a signal not handled by Python, when a Python fatal internal error is detected, or when :func:`os._exit` is called. +**Note:** The effect of registering or unregistering functions from within +a cleanup function is undefined. + .. versionchanged:: 3.7 When used with C-API subinterpreters, registered functions are local to the interpreter they were registered in. diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 158f4851634652..43a3286ba832cf 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -14,10 +14,7 @@ .. testsetup:: * - import warnings - # Ignore warning when ByteString is imported - with warnings.catch_warnings(action='ignore', category=DeprecationWarning): - from collections.abc import * + from collections.abc import * import itertools __name__ = '' diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 48a832db60e919..3d2bb8efc95d8e 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -168,6 +168,13 @@ are always available. They are listed here in alphabetical order. If :func:`sys.breakpointhook` is not accessible, this function will raise :exc:`RuntimeError`. + By default, the behavior of :func:`breakpoint` can be changed with + the :envvar:`PYTHONBREAKPOINT` environment variable. + See :func:`sys.breakpointhook` for usage details. + + Note that this is not guaranteed if :func:`sys.breakpointhook` + has been replaced. + .. audit-event:: builtins.breakpoint breakpointhook breakpoint .. versionadded:: 3.7 diff --git a/Doc/library/random.rst b/Doc/library/random.rst index c192919ac62e54..76ae97a8be7e63 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -334,8 +334,10 @@ be found in any statistics text. .. function:: gammavariate(alpha, beta) - Gamma distribution. (*Not* the gamma function!) Conditions on the - parameters are ``alpha > 0`` and ``beta > 0``. + Gamma distribution. (*Not* the gamma function!) The shape and + scale parameters, *alpha* and *beta*, must have positive values. + (Calling conventions vary and some sources define 'beta' + as the inverse of the scale). The probability distribution function is:: @@ -346,7 +348,8 @@ be found in any statistics text. .. function:: gauss(mu=0.0, sigma=1.0) - Normal distribution, also called the Gaussian distribution. *mu* is the mean, + Normal distribution, also called the Gaussian distribution. + *mu* is the mean, and *sigma* is the standard deviation. This is slightly faster than the :func:`normalvariate` function defined below. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index fb1c916b141a25..c300c4257f0e81 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -19,7 +19,7 @@ This module provides runtime support for type hints. The most fundamental support consists of the types :data:`Any`, :data:`Union`, :data:`Callable`, -:class:`TypeVar`, and :class:`Generic`. For a full specification, please see +:class:`TypeVar`, and :class:`Generic`. For a specification, please see :pep:`484`. For a simplified introduction to type hints, see :pep:`483`. @@ -592,7 +592,7 @@ The module defines the following classes, functions and decorators. when the checked program targets Python 3.9 or newer. The deprecated types will be removed from the :mod:`typing` module - in the first Python version released 5 years after the release of Python 3.9.0. + no sooner than the first Python version released 5 years after the release of Python 3.9.0. See details in :pep:`585`—*Type Hinting Generics In Standard Collections*. @@ -1291,6 +1291,8 @@ These are not used in annotations. They are building blocks for creating generic U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method +.. _typing-constrained-typevar: + Using a *constrained* type variable, however, means that the ``TypeVar`` can only ever be solved as being exactly one of the constraints given:: @@ -1550,7 +1552,7 @@ These are not used in annotations. They are building blocks for creating generic .. data:: AnyStr - ``AnyStr`` is a :class:`constrained type variable ` defined as + ``AnyStr`` is a :ref:`constrained type variable ` defined as ``AnyStr = TypeVar('AnyStr', str, bytes)``. It is meant to be used for functions that may accept any kind of string @@ -2112,7 +2114,7 @@ Other concrete types Python 2 is no longer supported, and most type checkers also no longer support type checking Python 2 code. Removal of the alias is not currently planned, but users are encouraged to use - :class:`str` instead of ``Text`` wherever possible. + :class:`str` instead of ``Text``. Abstract Base Classes --------------------- diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 546c7147bb3b27..3e55b3fa0f4734 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -831,8 +831,8 @@ Pending Removal in Python 3.14 For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. (Contributed by Shantanu Jain in :gh:`91896`.) -* :class:`typing.ByteString`, deprecated since Python 3.9, now causes an - :exc:`DeprecationWarning` to be emitted when it is used or accessed. +* :class:`typing.ByteString`, deprecated since Python 3.9, now causes a + :exc:`DeprecationWarning` to be emitted when it is used. * Creating immutable types (:data:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable bases using the C API. @@ -1204,6 +1204,8 @@ Build Changes (Contributed by Zhang Na in :gh:`90656`.) +* ``PYTHON_FOR_REGEN`` now require Python 3.10 or newer. + C API Changes ============= diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index bbf9cad6bc7f86..488e17d8bccd5b 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -244,7 +244,8 @@ def abort(self): called with None as its argument. """ self._closed = True - self._ssl_protocol._abort() + if self._ssl_protocol is not None: + self._ssl_protocol._abort() def _force_close(self, exc): self._closed = True diff --git a/Lib/collections/abc.py b/Lib/collections/abc.py index 60b1eb60fa6ae1..86ca8b8a8414b3 100644 --- a/Lib/collections/abc.py +++ b/Lib/collections/abc.py @@ -1,12 +1,3 @@ from _collections_abc import * from _collections_abc import __all__ from _collections_abc import _CallableGenericAlias - -_deprecated_ByteString = globals().pop("ByteString") - -def __getattr__(attr): - if attr == "ByteString": - import warnings - warnings._deprecated("collections.abc.ByteString", remove=(3, 14)) - return _deprecated_ByteString - raise AttributeError(f"module 'collections.abc' has no attribute {attr!r}") diff --git a/Lib/http/server.py b/Lib/http/server.py index a245ffb307860a..ca6240d9a921e6 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -300,6 +300,10 @@ def parse_request(self): # - Leading zeros MUST be ignored by recipients. if len(version_number) != 2: raise ValueError + if any(not component.isdigit() for component in version_number): + raise ValueError("non digit in http version") + if any(len(component) > 10 for component in version_number): + raise ValueError("unreasonable length http version") version_number = int(version_number[0]), int(version_number[1]) except (ValueError, IndexError): self.send_error( diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index e64e96f75e6cfc..e97e3ca01ef30c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,9 +1,20 @@ +What's New in IDLE 3.12.0 +(since 3.11.0) +Released on 2023-10-02 +========================= + + +gh-88496 Fix IDLE test hang on macOS. + +gh-103314 Support sys.last_exc after exceptions in Shell. +Patch by Irit Katriel. + + What's New in IDLE 3.11.0 (since 3.10.0) -Released on 2022-10-03 +Released on 2022-10-24 ========================= - gh-97527: Fix a bug in the previous bugfix that caused IDLE to not start when run with 3.10.8, 3.12.0a1, and at least Microsoft Python 3.10.2288.0 installed without the Lib/test package. 3.11.0 was never diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 505815502600b1..21402ad7139173 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -446,6 +446,26 @@ def set_line_and_column(self, event=None): self.status_bar.set_label('column', 'Col: %s' % column) self.status_bar.set_label('line', 'Ln: %s' % line) + + """ Menu definitions and functions. + * self.menubar - the always visible horizontal menu bar. + * mainmenu.menudefs - a list of tuples, one for each menubar item. + Each tuple pairs a lower-case name and list of dropdown items. + Each item is a name, virtual event pair or None for separator. + * mainmenu.default_keydefs - maps events to keys. + * text.keydefs - same. + * cls.menu_specs - menubar name, titlecase display form pairs + with Alt-hotkey indicator. A subset of menudefs items. + * self.menudict - map menu name to dropdown menu. + * self.recent_files_menu - 2nd level cascade in the file cascade. + * self.wmenu_end - set in __init__ (purpose unclear). + + createmenubar, postwindowsmenu, update_menu_label, update_menu_state, + ApplyKeybings (2nd part), reset_help_menu_entries, + _extra_help_callback, update_recent_files_list, + apply_bindings, fill_menus, (other functions?) + """ + menu_specs = [ ("file", "_File"), ("edit", "_Edit"), @@ -456,8 +476,22 @@ def set_line_and_column(self, event=None): ("help", "_Help"), ] - def createmenubar(self): + """Populate the menu bar widget for the editor window. + + Each option on the menubar is itself a cascade-type Menu widget + with the menubar as the parent. The names, labels, and menu + shortcuts for the menubar items are stored in menu_specs. Each + submenu is subsequently populated in fill_menus(), except for + 'Recent Files' which is added to the File menu here. + + Instance variables: + menubar: Menu widget containing first level menu items. + menudict: Dictionary of {menuname: Menu instance} items. The keys + represent the valid menu items for this window and may be a + subset of all the menudefs available. + recent_files_menu: Menu widget contained within the 'file' menudict. + """ mbar = self.menubar self.menudict = menudict = {} for name, label in self.menu_specs: @@ -480,7 +514,10 @@ def createmenubar(self): self.reset_help_menu_entries() def postwindowsmenu(self): - # Only called when Window menu exists + """Callback to register window. + + Only called when Window menu exists. + """ menu = self.menudict['window'] end = menu.index("end") if end is None: @@ -859,8 +896,11 @@ def ResetFont(self): self.set_width() def RemoveKeybindings(self): - "Remove the keybindings before they are changed." - # Called from configdialog.py + """Remove the virtual, configurable keybindings. + + Leaves the default Tk Text keybindings. + """ + # Called from configdialog.deactivate_current_config. self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() for event, keylist in keydefs.items(): self.text.event_delete(event, *keylist) @@ -871,15 +911,19 @@ def RemoveKeybindings(self): self.text.event_delete(event, *keylist) def ApplyKeybindings(self): - "Update the keybindings after they are changed" - # Called from configdialog.py + """Apply the virtual, configurable keybindings. + + Alse update hotkeys to current keyset. + """ + # Called from configdialog.activate_config_changes. self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() self.apply_bindings() for extensionName in self.get_standard_extension_names(): xkeydefs = idleConf.GetExtensionBindings(extensionName) if xkeydefs: self.apply_bindings(xkeydefs) - #update menu accelerators + + # Update menu accelerators. menuEventDict = {} for menu in self.mainmenu.menudefs: menuEventDict[menu[0]] = {} @@ -914,25 +958,25 @@ def set_notabs_indentwidth(self): type='int') def reset_help_menu_entries(self): - "Update the additional help entries on the Help menu" + """Update the additional help entries on the Help menu.""" help_list = idleConf.GetAllExtraHelpSourcesList() helpmenu = self.menudict['help'] - # first delete the extra help entries, if any + # First delete the extra help entries, if any. helpmenu_length = helpmenu.index(END) if helpmenu_length > self.base_helpmenu_length: helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length) - # then rebuild them + # Then rebuild them. if help_list: helpmenu.add_separator() for entry in help_list: - cmd = self.__extra_help_callback(entry[1]) + cmd = self._extra_help_callback(entry[1]) helpmenu.add_command(label=entry[0], command=cmd) - # and update the menu dictionary + # And update the menu dictionary. self.menudict['help'] = helpmenu - def __extra_help_callback(self, helpfile): - "Create a callback with the helpfile value frozen at definition time" - def display_extra_help(helpfile=helpfile): + def _extra_help_callback(self, resource): + """Return a callback that loads resource (file or web page).""" + def display_extra_help(helpfile=resource): if not helpfile.startswith(('www', 'http')): helpfile = os.path.normpath(helpfile) if sys.platform[:3] == 'win': @@ -1158,6 +1202,7 @@ def load_extension(self, name): self.text.bind(vevent, getattr(ins, methodname)) def apply_bindings(self, keydefs=None): + """Add events with keys to self.text.""" if keydefs is None: keydefs = self.mainmenu.default_keydefs text = self.text @@ -1167,9 +1212,10 @@ def apply_bindings(self, keydefs=None): text.event_add(event, *keylist) def fill_menus(self, menudefs=None, keydefs=None): - """Add appropriate entries to the menus and submenus + """Fill in dropdown menus used by this window. - Menus that are absent or None in self.menudict are ignored. + Items whose name begins with '!' become checkbuttons. + Other names indicate commands. None becomes a separator. """ if menudefs is None: menudefs = self.mainmenu.menudefs @@ -1182,7 +1228,7 @@ def fill_menus(self, menudefs=None, keydefs=None): if not menu: continue for entry in entrylist: - if not entry: + if entry is None: menu.add_separator() else: label, eventname = entry @@ -1218,11 +1264,13 @@ def setvar(self, name, value, vartype=None): else: raise NameError(name) - def get_var_obj(self, name, vartype=None): - var = self.tkinter_vars.get(name) + def get_var_obj(self, eventname, vartype=None): + """Return a tkinter variable instance for the event. + """ + var = self.tkinter_vars.get(eventname) if not var and vartype: - # create a Tkinter variable object with self.text as master: - self.tkinter_vars[name] = var = vartype(self.text) + # Create a Tkinter variable object. + self.tkinter_vars[eventname] = var = vartype(self.text) return var # Tk implementations of "virtual text methods" -- each platform @@ -1613,8 +1661,16 @@ def run(self): ### end autoindent code ### def prepstr(s): - # Helper to extract the underscore from a string, e.g. - # prepstr("Co_py") returns (2, "Copy"). + """Extract the underscore from a string. + + For example, prepstr("Co_py") returns (2, "Copy"). + + Args: + s: String with underscore. + + Returns: + Tuple of (position of underscore, string without underscore). + """ i = s.find('_') if i >= 0: s = s[:i] + s[i+1:] @@ -1628,6 +1684,18 @@ def prepstr(s): } def get_accelerator(keydefs, eventname): + """Return a formatted string for the keybinding of an event. + + Convert the first keybinding for a given event to a form that + can be displayed as an accelerator on the menu. + + Args: + keydefs: Dictionary of valid events to keybindings. + eventname: Event to retrieve keybinding for. + + Returns: + Formatted string of the keybinding. + """ keylist = keydefs.get(eventname) # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 # if not keylist: @@ -1637,14 +1705,23 @@ def get_accelerator(keydefs, eventname): "<>"}): return "" s = keylist[0] + # Convert strings of the form -singlelowercase to -singleuppercase. s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s) + # Convert certain keynames to their symbol. s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s) + # Remove Key- from string. s = re.sub("Key-", "", s) - s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu + # Convert Cancel to Ctrl-Break. + s = re.sub("Cancel", "Ctrl-Break", s) # dscherer@cmu.edu + # Convert Control to Ctrl-. s = re.sub("Control-", "Ctrl-", s) + # Change - to +. s = re.sub("-", "+", s) + # Change >< to space. s = re.sub("><", " ", s) + # Remove <. s = re.sub("<", "", s) + # Remove >. s = re.sub(">", "", s) return s diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt index 566bfd179fdf1b..cacd06db873d03 100644 --- a/Lib/idlelib/idle_test/README.txt +++ b/Lib/idlelib/idle_test/README.txt @@ -146,14 +146,17 @@ python -m unittest -v idlelib.idle_test python -m test -v -ugui test_idle python -m test.test_idle -The idle tests are 'discovered' by -idlelib.idle_test.__init__.load_tests, which is also imported into -test.test_idle. Normally, neither file should be changed when working on -individual test modules. The third command runs unittest indirectly -through regrtest. The same happens when the entire test suite is run -with 'python -m test'. So that command must work for buildbots to stay -green. Idle tests must not disturb the environment in a way that makes -other tests fail (issue 18081). +IDLE tests are 'discovered' by idlelib.idle_test.__init__.load_tests +when this is imported into test.test_idle. Normally, neither file +should be changed when working on individual test modules. The third +command runs unittest indirectly through regrtest. The same happens when +the entire test suite is run with 'python -m test'. So that command must +work for buildbots to stay green. IDLE tests must not disturb the +environment in a way that makes other tests fail (GH-62281). + +To test subsets of modules, see idlelib.idle_test.__init__. This +can be used to find refleaks or possible sources of "Theme changed" +tcl messages (GH-71383). To run an individual Testcase or test method, extend the dotted name given to unittest on the command line or use the test -m option. The diff --git a/Lib/idlelib/idle_test/__init__.py b/Lib/idlelib/idle_test/__init__.py index ad067b405cab67..79b5d102dd7da5 100644 --- a/Lib/idlelib/idle_test/__init__.py +++ b/Lib/idlelib/idle_test/__init__.py @@ -1,17 +1,27 @@ -'''idlelib.idle_test is a private implementation of test.test_idle, -which tests the IDLE application as part of the stdlib test suite. -Run IDLE tests alone with "python -m test.test_idle". -Starting with Python 3.6, IDLE requires tcl/tk 8.5 or later. +"""idlelib.idle_test implements test.test_idle, which tests the IDLE +application as part of the stdlib test suite. +Run IDLE tests alone with "python -m test.test_idle (-v)". This package and its contained modules are subject to change and any direct use is at your own risk. -''' +""" from os.path import dirname +# test_idle imports load_tests for test discovery (default all). +# To run subsets of idlelib module tests, insert '[]' after '_'. +# Example: insert '[ac]' for modules beginning with 'a' or 'c'. +# Additional .discover/.addTest pairs with separate inserts work. +# Example: pairs with 'c' and 'g' test c* files and grep. + def load_tests(loader, standard_tests, pattern): this_dir = dirname(__file__) top_dir = dirname(dirname(this_dir)) - package_tests = loader.discover(start_dir=this_dir, pattern='test*.py', + module_tests = loader.discover(start_dir=this_dir, + pattern='test_*.py', # Insert here. top_level_dir=top_dir) - standard_tests.addTests(package_tests) + standard_tests.addTests(module_tests) +## module_tests = loader.discover(start_dir=this_dir, +## pattern='test_*.py', # Insert here. +## top_level_dir=top_dir) +## standard_tests.addTests(module_tests) return standard_tests diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 776a9e9b587d32..cd11d385591f80 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -48,13 +48,11 @@ def dash_R(ns, test_name, test_func): else: zdc = zipimport._zip_directory_cache.copy() abcs = {} - # catch and ignore collections.abc.ByteString deprecation - with warnings.catch_warnings(action='ignore', category=DeprecationWarning): - for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: - if not isabstract(abc): - continue - for obj in abc.__subclasses__() + [abc]: - abcs[obj] = _get_dump(obj)[0] + for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: + if not isabstract(abc): + continue + for obj in abc.__subclasses__() + [abc]: + abcs[obj] = _get_dump(obj)[0] # bpo-31217: Integer pool to get a single integer object for the same # value. The pool is used to prevent false alarm when checking for memory @@ -176,8 +174,7 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs): # Clear ABC registries, restoring previously saved ABC registries. # ignore deprecation warning for collections.abc.ByteString - with warnings.catch_warnings(action='ignore', category=DeprecationWarning): - abs_classes = [getattr(collections.abc, a) for a in collections.abc.__all__] + abs_classes = [getattr(collections.abc, a) for a in collections.abc.__all__] abs_classes = filter(isabstract, abs_classes) for abc in abs_classes: for obj in abc.__subclasses__() + [abc]: diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 3fc2c07f933061..0ef0b5d8b65803 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -1748,28 +1748,80 @@ class Subclass(BaseException, self.module.StateAccessType): class Test_Pep523API(unittest.TestCase): - def do_test(self, func): - calls = [] + def do_test(self, func, names): + actual_calls = [] start = SUFFICIENT_TO_DEOPT_AND_SPECIALIZE count = start + SUFFICIENT_TO_DEOPT_AND_SPECIALIZE - for i in range(count): - if i == start: - _testinternalcapi.set_eval_frame_record(calls) - func() - _testinternalcapi.set_eval_frame_default() - self.assertEqual(len(calls), SUFFICIENT_TO_DEOPT_AND_SPECIALIZE) - for name in calls: - self.assertEqual(name, func.__name__) - - def test_pep523_with_specialization_simple(self): - def func1(): - pass - self.do_test(func1) + try: + for i in range(count): + if i == start: + _testinternalcapi.set_eval_frame_record(actual_calls) + func() + finally: + _testinternalcapi.set_eval_frame_default() + expected_calls = names * SUFFICIENT_TO_DEOPT_AND_SPECIALIZE + self.assertEqual(len(expected_calls), len(actual_calls)) + for expected, actual in zip(expected_calls, actual_calls, strict=True): + self.assertEqual(expected, actual) + + def test_inlined_binary_subscr(self): + class C: + def __getitem__(self, other): + return None + def func(): + C()[42] + names = ["func", "__getitem__"] + self.do_test(func, names) - def test_pep523_with_specialization_with_default(self): - def func2(x=None): + def test_inlined_call(self): + def inner(x=42): + pass + def func(): + inner() + inner(42) + names = ["func", "inner", "inner"] + self.do_test(func, names) + + def test_inlined_call_function_ex(self): + def inner(x): pass - self.do_test(func2) + def func(): + inner(*[42]) + names = ["func", "inner"] + self.do_test(func, names) + + def test_inlined_for_iter(self): + def gen(): + yield 42 + def func(): + for _ in gen(): + pass + names = ["func", "gen", "gen", "gen"] + self.do_test(func, names) + + def test_inlined_load_attr(self): + class C: + @property + def a(self): + return 42 + class D: + def __getattribute__(self, name): + return 42 + def func(): + C().a + D().a + names = ["func", "a", "__getattribute__"] + self.do_test(func, names) + + def test_inlined_send(self): + def inner(): + yield 42 + def outer(): + yield from inner() + def func(): + list(outer()) + names = ["func", "outer", "outer", "inner", "inner", "outer", "inner"] + self.do_test(func, names) if __name__ == "__main__": diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index f0736b8081feac..bb8b352518ef3e 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -11,7 +11,6 @@ import string import sys from test import support -from test.support.import_helper import import_fresh_module import types import unittest @@ -26,7 +25,7 @@ from collections.abc import Set, MutableSet from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView from collections.abc import Sequence, MutableSequence -from collections.abc import Buffer +from collections.abc import ByteString, Buffer class TestUserObjects(unittest.TestCase): @@ -1940,8 +1939,6 @@ def assert_index_same(seq1, seq2, index_args): nativeseq, seqseq, (letter, start, stop)) def test_ByteString(self): - with self.assertWarns(DeprecationWarning): - from collections.abc import ByteString for sample in [bytes, bytearray]: with self.assertWarns(DeprecationWarning): self.assertIsInstance(sample(), ByteString) @@ -1963,11 +1960,6 @@ class X(ByteString): pass # No metaclass conflict class Z(ByteString, Awaitable): pass - def test_ByteString_attribute_access(self): - collections_abc = import_fresh_module("collections.abc") - with self.assertWarns(DeprecationWarning): - collections_abc.ByteString - def test_Buffer(self): for sample in [bytes, bytearray, memoryview]: self.assertIsInstance(sample(b"x"), Buffer) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 4ef7decfbc263e..f3554f1c4bb3f3 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -417,45 +417,45 @@ def testAttributes(self): # test that exception attributes are happy exceptionList = [ - (BaseException, (), {'args' : ()}), - (BaseException, (1, ), {'args' : (1,)}), - (BaseException, ('foo',), + (BaseException, (), {}, {'args' : ()}), + (BaseException, (1, ), {}, {'args' : (1,)}), + (BaseException, ('foo',), {}, {'args' : ('foo',)}), - (BaseException, ('foo', 1), + (BaseException, ('foo', 1), {}, {'args' : ('foo', 1)}), - (SystemExit, ('foo',), + (SystemExit, ('foo',), {}, {'args' : ('foo',), 'code' : 'foo'}), - (OSError, ('foo',), + (OSError, ('foo',), {}, {'args' : ('foo',), 'filename' : None, 'filename2' : None, 'errno' : None, 'strerror' : None}), - (OSError, ('foo', 'bar'), + (OSError, ('foo', 'bar'), {}, {'args' : ('foo', 'bar'), 'filename' : None, 'filename2' : None, 'errno' : 'foo', 'strerror' : 'bar'}), - (OSError, ('foo', 'bar', 'baz'), + (OSError, ('foo', 'bar', 'baz'), {}, {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2' : None, 'errno' : 'foo', 'strerror' : 'bar'}), - (OSError, ('foo', 'bar', 'baz', None, 'quux'), + (OSError, ('foo', 'bar', 'baz', None, 'quux'), {}, {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), - (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), + (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), {}, {'args' : ('errnoStr', 'strErrorStr'), 'strerror' : 'strErrorStr', 'errno' : 'errnoStr', 'filename' : 'filenameStr'}), - (OSError, (1, 'strErrorStr', 'filenameStr'), + (OSError, (1, 'strErrorStr', 'filenameStr'), {}, {'args' : (1, 'strErrorStr'), 'errno' : 1, 'strerror' : 'strErrorStr', 'filename' : 'filenameStr', 'filename2' : None}), - (SyntaxError, (), {'msg' : None, 'text' : None, + (SyntaxError, (), {}, {'msg' : None, 'text' : None, 'filename' : None, 'lineno' : None, 'offset' : None, 'end_offset': None, 'print_file_and_line' : None}), - (SyntaxError, ('msgStr',), + (SyntaxError, ('msgStr',), {}, {'args' : ('msgStr',), 'text' : None, 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None, 'end_offset': None}), (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', - 'textStr', 'endLinenoStr', 'endOffsetStr')), + 'textStr', 'endLinenoStr', 'endOffsetStr')), {}, {'offset' : 'offsetStr', 'text' : 'textStr', 'args' : ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', 'textStr', @@ -465,7 +465,7 @@ def testAttributes(self): 'end_lineno': 'endLinenoStr', 'end_offset': 'endOffsetStr'}), (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 'textStr', 'endLinenoStr', 'endOffsetStr', - 'print_file_and_lineStr'), + 'print_file_and_lineStr'), {}, {'text' : None, 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 'textStr', 'endLinenoStr', 'endOffsetStr', @@ -473,38 +473,40 @@ def testAttributes(self): 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None, 'end_lineno': None, 'end_offset': None}), - (UnicodeError, (), {'args' : (),}), + (UnicodeError, (), {}, {'args' : (),}), (UnicodeEncodeError, ('ascii', 'a', 0, 1, - 'ordinal not in range'), + 'ordinal not in range'), {}, {'args' : ('ascii', 'a', 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : 'a', 'start' : 0, 'reason' : 'ordinal not in range'}), (UnicodeDecodeError, ('ascii', bytearray(b'\xff'), 0, 1, - 'ordinal not in range'), + 'ordinal not in range'), {}, {'args' : ('ascii', bytearray(b'\xff'), 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : b'\xff', 'start' : 0, 'reason' : 'ordinal not in range'}), (UnicodeDecodeError, ('ascii', b'\xff', 0, 1, - 'ordinal not in range'), + 'ordinal not in range'), {}, {'args' : ('ascii', b'\xff', 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : b'\xff', 'start' : 0, 'reason' : 'ordinal not in range'}), - (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), + (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), {}, {'args' : ('\u3042', 0, 1, 'ouch'), 'object' : '\u3042', 'reason' : 'ouch', 'start' : 0, 'end' : 1}), - (NaiveException, ('foo',), + (NaiveException, ('foo',), {}, {'args': ('foo',), 'x': 'foo'}), - (SlottedNaiveException, ('foo',), + (SlottedNaiveException, ('foo',), {}, {'args': ('foo',), 'x': 'foo'}), + (AttributeError, ('foo',), dict(name='name', obj='obj'), + dict(args=('foo',), name='name', obj='obj')), ] try: # More tests are in test_WindowsError exceptionList.append( - (WindowsError, (1, 'strErrorStr', 'filenameStr'), + (WindowsError, (1, 'strErrorStr', 'filenameStr'), {}, {'args' : (1, 'strErrorStr'), 'strerror' : 'strErrorStr', 'winerror' : None, 'errno' : 1, @@ -513,11 +515,11 @@ def testAttributes(self): except NameError: pass - for exc, args, expected in exceptionList: + for exc, args, kwargs, expected in exceptionList: try: - e = exc(*args) + e = exc(*args, **kwargs) except: - print("\nexc=%r, args=%r" % (exc, args), file=sys.stderr) + print(f"\nexc={exc!r}, args={args!r}", file=sys.stderr) # raise else: # Verify module name @@ -540,7 +542,12 @@ def testAttributes(self): new = p.loads(s) for checkArgName in expected: got = repr(getattr(new, checkArgName)) - want = repr(expected[checkArgName]) + if exc == AttributeError and checkArgName == 'obj': + # See GH-103352, we're not pickling + # obj at this point. So verify it's None. + want = repr(None) + else: + want = repr(expected[checkArgName]) self.assertEqual(got, want, 'pickled "%r", attribute "%s' % (e, checkArgName)) diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 0382b5ec448d57..cdd1bea754a020 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -164,6 +164,27 @@ def test_version_digits(self): res = self.con.getresponse() self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + def test_version_signs_and_underscores(self): + self.con._http_vsn_str = 'HTTP/-9_9_9.+9_9_9' + self.con.putrequest('GET', '/') + self.con.endheaders() + res = self.con.getresponse() + self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + + def test_major_version_number_too_long(self): + self.con._http_vsn_str = 'HTTP/909876543210.0' + self.con.putrequest('GET', '/') + self.con.endheaders() + res = self.con.getresponse() + self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + + def test_minor_version_number_too_long(self): + self.con._http_vsn_str = 'HTTP/1.909876543210' + self.con.putrequest('GET', '/') + self.con.endheaders() + res = self.con.getresponse() + self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + def test_version_none_get(self): self.con._http_vsn_str = '' self.con.putrequest('GET', '/') diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index 90cff9002b75b2..ebb1e8eb823b51 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -5,12 +5,8 @@ if check_sanitizer(address=True, memory=True): raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") -# Skip test_idle if _tkinter wasn't built, if tkinter is missing, -# if tcl/tk is not the 8.5+ needed for ttk widgets, -# or if idlelib is missing (not installed). +# Skip test_idle if _tkinter, tkinter, or idlelib are missing. tk = import_module('tkinter') # Also imports _tkinter. -if tk.TkVersion < 8.5: - raise unittest.SkipTest("IDLE requires tk 8.5 or later.") idlelib = import_module('idlelib') # Before importing and executing more of idlelib, diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 9bcc92a40c61df..cc16804fe21829 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -4242,6 +4242,7 @@ def test_warn_on_dealloc_fd(self): def test_pickling(self): # Pickling file objects is forbidden + msg = "cannot pickle" for kwargs in [ {"mode": "w"}, {"mode": "wb"}, @@ -4256,8 +4257,10 @@ def test_pickling(self): if "b" not in kwargs["mode"]: kwargs["encoding"] = "utf-8" for protocol in range(pickle.HIGHEST_PROTOCOL + 1): - with self.open(os_helper.TESTFN, **kwargs) as f: - self.assertRaises(TypeError, pickle.dumps, f, protocol) + with self.subTest(protocol=protocol, kwargs=kwargs): + with self.open(os_helper.TESTFN, **kwargs) as f: + with self.assertRaisesRegex(TypeError, msg): + pickle.dumps(f, protocol) @unittest.skipIf( support.is_emscripten, "fstat() of a pipe fd is not supported" diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index b2a3b7ea3e49b6..23e1b8c1ce3193 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -338,6 +338,14 @@ def test_nested_3(self): outputs = {"y": [1, 3, 5]} self._check_in_scopes(code, outputs) + def test_nested_4(self): + code = """ + items = [([lambda: x for x in range(2)], lambda: x) for x in range(3)] + out = [([fn() for fn in fns], fn()) for fns, fn in items] + """ + outputs = {"out": [([1, 1], 2), ([1, 1], 2), ([1, 1], 2)]} + self._check_in_scopes(code, outputs) + def test_nameerror(self): code = """ [x for x in [1]] diff --git a/Lib/test/test_tkinter/test_geometry_managers.py b/Lib/test/test_tkinter/test_geometry_managers.py index 3663048a145ab1..59fe592b492adc 100644 --- a/Lib/test/test_tkinter/test_geometry_managers.py +++ b/Lib/test/test_tkinter/test_geometry_managers.py @@ -108,8 +108,8 @@ def test_pack_configure_in(self): a.pack_configure(in_=c) self.assertEqual(pack.pack_slaves(), [b, c, d]) self.assertEqual(c.pack_slaves(), [a]) - with self.assertRaisesRegex(TclError, - 'can\'t pack %s inside itself' % (a,)): + with self.assertRaisesRegex( + TclError, """can't pack "?%s"? inside itself""" % (a,)): a.pack_configure(in_=a) with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): a.pack_configure(in_='.foo') @@ -292,8 +292,10 @@ def create2(self): def test_place_configure_in(self): t, f, f2 = self.create2() self.assertEqual(f2.winfo_manager(), '') - with self.assertRaisesRegex(TclError, "can't place %s relative to " - "itself" % re.escape(str(f2))): + with self.assertRaisesRegex( + TclError, + """can't place "?%s"? relative to itself""" + % re.escape(str(f2))): f2.place_configure(in_=f2) self.assertEqual(f2.winfo_manager(), '') with self.assertRaisesRegex(TclError, 'bad window path name'): diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 3422dc1ed3f5f8..e1c6a8a7f376eb 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -8,7 +8,6 @@ import re import sys import warnings -from test.support.import_helper import import_fresh_module from unittest import TestCase, main, skipUnless, skip from unittest.mock import patch from copy import copy, deepcopy @@ -3909,14 +3908,7 @@ class MyChain(typing.ChainMap[str, T]): ... self.assertEqual(MyChain[int]().__orig_class__, MyChain[int]) def test_all_repr_eq_any(self): - typing = import_fresh_module("typing") - with warnings.catch_warnings(record=True) as wlog: - warnings.filterwarnings('always', '', DeprecationWarning) - objs = [getattr(typing, el) for el in typing.__all__] - self.assertEqual( - [str(w.message) for w in wlog], - ["'typing.ByteString' is deprecated and slated for removal in Python 3.14"] - ) + objs = (getattr(typing, el) for el in typing.__all__) for obj in objs: self.assertNotEqual(repr(obj), '') self.assertEqual(obj, obj) @@ -6005,15 +5997,13 @@ def test_mutablesequence(self): def test_bytestring(self): with self.assertWarns(DeprecationWarning): - from typing import ByteString + self.assertIsInstance(b'', typing.ByteString) with self.assertWarns(DeprecationWarning): - self.assertIsInstance(b'', ByteString) + self.assertIsInstance(bytearray(b''), typing.ByteString) with self.assertWarns(DeprecationWarning): - self.assertIsInstance(bytearray(b''), ByteString) + class Foo(typing.ByteString): ... with self.assertWarns(DeprecationWarning): - class Foo(ByteString): ... - with self.assertWarns(DeprecationWarning): - class Bar(ByteString, typing.Awaitable): ... + class Bar(typing.ByteString, typing.Awaitable): ... def test_list(self): self.assertIsSubclass(list, typing.List) @@ -8309,10 +8299,6 @@ def test_no_isinstance(self): class SpecialAttrsTests(BaseTestCase): def test_special_attrs(self): - with warnings.catch_warnings( - action='ignore', category=DeprecationWarning - ): - typing_ByteString = typing.ByteString cls_to_check = { # ABC classes typing.AbstractSet: 'AbstractSet', @@ -8321,7 +8307,7 @@ def test_special_attrs(self): typing.AsyncIterable: 'AsyncIterable', typing.AsyncIterator: 'AsyncIterator', typing.Awaitable: 'Awaitable', - typing_ByteString: 'ByteString', + typing.ByteString: 'ByteString', typing.Callable: 'Callable', typing.ChainMap: 'ChainMap', typing.Collection: 'Collection', @@ -8646,8 +8632,6 @@ def test_all_exported_names(self): getattr(v, '__module__', None) == typing.__name__ ) } - # Deprecated; added dynamically via module __getattr__ - computed_all.add("ByteString") self.assertSetEqual(computed_all, actual_all) diff --git a/Lib/typing.py b/Lib/typing.py index 513d4d96dd6e1d..61aed0980ac2eb 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -2772,6 +2772,9 @@ class Other(Leaf): # Error reported by type checker MutableMapping = _alias(collections.abc.MutableMapping, 2) Sequence = _alias(collections.abc.Sequence, 1) MutableSequence = _alias(collections.abc.MutableSequence, 1) +ByteString = _DeprecatedGenericAlias( + collections.abc.ByteString, 0, removal_version=(3, 14) # Not generic. +) # Tuple accepts variable number of parameters. Tuple = _TupleType(tuple, -1, inst=False, name='Tuple') Tuple.__doc__ = \ @@ -3571,27 +3574,3 @@ def method(self) -> None: # read-only property, TypeError if it's a builtin class. pass return method - - -def __getattr__(attr): - if attr == "ByteString": - import warnings - warnings._deprecated("typing.ByteString", remove=(3, 14)) - with warnings.catch_warnings( - action="ignore", category=DeprecationWarning - ): - # Not generic - ByteString = globals()["ByteString"] = _DeprecatedGenericAlias( - collections.abc.ByteString, 0, removal_version=(3, 14) - ) - return ByteString - raise AttributeError(f"module 'typing' has no attribute {attr!r}") - - -def _remove_cached_ByteString_from_globals(): - try: - del globals()["ByteString"] - except KeyError: - pass - -_cleanups.append(_remove_cached_ByteString_from_globals) diff --git a/Makefile.pre.in b/Makefile.pre.in index 329466580b9cb0..7c44b7be5dbe67 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -603,12 +603,21 @@ LIBHACL_SHA2_HEADERS= \ # Default target all: @DEF_MAKE_ALL_RULE@ + +# First target in Makefile is implicit default. So .PHONY needs to come after +# all. +.PHONY: all + +.PHONY: build_all build_all: check-clean-src $(BUILDPYTHON) platform sharedmods \ gdbhooks Programs/_testembed scripts checksharedmods rundsymutil + +.PHONY: build_wasm build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \ python-config checksharedmods # Check that the source is clean when building out of source. +.PHONY: check-clean-src check-clean-src: @if test -n "$(VPATH)" -a \( \ -f "$(srcdir)/Programs/python.o" \ @@ -652,23 +661,28 @@ profile-run-stamp: # to record its completion and avoid re-running it. touch $@ +.PHONY: build_all_generate_profile build_all_generate_profile: $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)" +.PHONY: run_profile_task run_profile_task: @ # FIXME: can't run for a cross build $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true +.PHONY: build_all_merge_profile build_all_merge_profile: $(LLVM_PROF_MERGER) # Compile Python binary with profile guided optimization. # To force re-running of the profile task, remove the profile-run-stamp file. +.PHONY: profile-opt profile-opt: profile-run-stamp @echo "Rebuilding with profile guided optimizations:" -rm -f profile-clean-stamp $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)" +.PHONY: bolt-opt bolt-opt: @PREBOLT_RULE@ rm -f *.fdata @if $(READELF) -p .note.bolt_info $(BUILDPYTHON) | grep BOLT > /dev/null; then\ @@ -685,12 +699,13 @@ bolt-opt: @PREBOLT_RULE@ # Compile and run with gcov -.PHONY=coverage coverage-lcov coverage-report +.PHONY: coverage coverage: @echo "Building with support for coverage checking:" $(MAKE) clean $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg --coverage" LDFLAGS="$(LDFLAGS) --coverage" +.PHONY: coverage-lcov coverage-lcov: @echo "Creating Coverage HTML report with LCOV:" @rm -f $(COVERAGE_INFO) @@ -722,6 +737,7 @@ coverage-lcov: @echo # Force regeneration of parser and frozen modules +.PHONY: coverage-report coverage-report: regen-token regen-frozen @ # build with coverage info $(MAKE) coverage @@ -731,7 +747,7 @@ coverage-report: regen-token regen-frozen $(MAKE) coverage-lcov # Run "Argument Clinic" over all source files -.PHONY=clinic +.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/build/generate_global_objects.py @@ -796,6 +812,7 @@ Modules/python.exp: $(LIBRARY) # # Distributors are likely to want to install this somewhere else e.g. relative # to the stripped DWARF data for the shared library. +.PHONY: gdbhooks gdbhooks: $(BUILDPYTHON)-gdb.py SRC_GDB_HOOKS=$(srcdir)/Tools/gdb/libpython.py @@ -936,6 +953,7 @@ $(LIBHACL_SHA2_A): $(LIBHACL_SHA2_OBJS) # create relative links from build/lib.platform/egg.so to Modules/egg.so # pybuilddir.txt is created too late. We cannot use it in Makefile # targets. ln --relative is not portable. +.PHONY: sharedmods sharedmods: $(SHAREDMODS) pybuilddir.txt @target=`cat pybuilddir.txt`; \ $(MKDIR_P) $$target; \ @@ -946,9 +964,11 @@ sharedmods: $(SHAREDMODS) pybuilddir.txt done # dependency on BUILDPYTHON ensures that the target is run last +.PHONY: checksharedmods checksharedmods: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) @$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/check_extension_modules.py +.PHONY: rundsymutil rundsymutil: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) @if [ ! -z $(DSYMUTIL) ] ; then \ echo $(DSYMUTIL_PATH) $(BUILDPYTHON); \ @@ -1252,20 +1272,24 @@ regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py ############################################################################ # ABI +.PHONY: regen-abidump regen-abidump: all @$(MKDIR_P) $(srcdir)/Doc/data/ abidw "libpython$(LDVERSION).so" --no-architecture --out-file $(srcdir)/Doc/data/python$(LDVERSION).abi.new @$(UPDATE_FILE) --create $(srcdir)/Doc/data/python$(LDVERSION).abi $(srcdir)/Doc/data/python$(LDVERSION).abi.new +.PHONY: check-abidump check-abidump: all abidiff $(srcdir)/Doc/data/python$(LDVERSION).abi "libpython$(LDVERSION).so" --drop-private-types --no-architecture --no-added-syms +.PHONY: regen-limited-abi regen-limited-abi: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.toml ############################################################################ # Regenerate all generated files +.PHONY: regen-all regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \ regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ @@ -1351,7 +1375,7 @@ regen-pegen: -o $(srcdir)/Parser/parser.new.c $(UPDATE_FILE) $(srcdir)/Parser/parser.c $(srcdir)/Parser/parser.new.c -.PHONY=regen-ast +.PHONY: regen-ast regen-ast: # Regenerate 3 files using using Parser/asdl_c.py: # - Include/internal/pycore_ast.h @@ -1424,6 +1448,7 @@ regen-stdlib-module-names: all Programs/_testembed > $(srcdir)/Python/stdlib_module_names.h.new $(UPDATE_FILE) $(srcdir)/Python/stdlib_module_names.h $(srcdir)/Python/stdlib_module_names.h.new +.PHONY: regen-sre regen-sre: # Regenerate Modules/_sre/sre_constants.h and Modules/_sre/sre_targets.h # from Lib/re/_constants.py using Tools/build/generate_sre_constants.py @@ -1762,15 +1787,15 @@ TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS) TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py TESTTIMEOUT= 1200 -.PHONY: test testall testuniversal buildbottest pythoninfo - # Remove "test_python_*" directories of previous failed test jobs. # Pass TESTOPTS options because it can contain --tempdir option. +.PHONY: cleantest cleantest: all $(TESTRUNNER) $(TESTOPTS) --cleanup # Run a basic set of regression tests. # This excludes some tests that are particularly resource-intensive. +.PHONY: test test: all $(TESTRUNNER) $(TESTOPTS) @@ -1781,6 +1806,7 @@ test: all # the bytecode read from a .pyc file had the bug, sometimes the directly # generated bytecode. This is sometimes a very shy bug needing a lot of # sample data. +.PHONY: testall testall: all -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f $(TESTPYTHON) -E $(srcdir)/Lib/compileall.py @@ -1790,6 +1816,7 @@ testall: all # Run the test suite for both architectures in a Universal build on OSX. # Must be run on an Intel box. +.PHONY: testuniversal testuniversal: all @if [ `arch` != 'i386' ]; then \ echo "This can only be used on OSX/i386" ;\ @@ -1801,6 +1828,7 @@ testuniversal: all # Like testall, but with only one pass and without multiple processes. # Run an optional script to include information about the build environment. +.PHONY: buildbottest buildbottest: all -@if which pybuildbot.identify >/dev/null 2>&1; then \ pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ @@ -1808,9 +1836,11 @@ buildbottest: all $(TESTRUNNER) -j 1 -u all -W --slowest --fail-env-changed --timeout=$(TESTTIMEOUT) $(TESTOPTS) # Like testall, but run Python tests with HOSTRUNNER directly. +.PHONY: hostrunnertest hostrunnertest: all $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test -u all $(TESTOPTS) +.PHONY: pythoninfo pythoninfo: all $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo @@ -1820,14 +1850,17 @@ QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multiprocessing_forkserver \ test_mailbox test_nntplib test_socket test_poll \ test_select test_zipfile test_concurrent_futures + +.PHONY: quicktest quicktest: all $(TESTRUNNER) $(QUICKTESTOPTS) # SSL tests -.PHONY: multisslcompile multissltest +.PHONY: multisslcompile multisslcompile: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py --steps=modules +.PHONY: multissltest multissltest: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py @@ -1835,6 +1868,7 @@ multissltest: all # prevent race conditions with PGO builds. PGO builds use recursive make, # which can lead to two parallel `./python setup.py build` processes that # step on each others toes. +.PHONY: install install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKINSTALLLAST@ if test "x$(ENSUREPIP)" != "xno" ; then \ case $(ENSUREPIP) in \ @@ -1845,6 +1879,7 @@ install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKI $$ensurepip --root=$(DESTDIR)/ ; \ fi +.PHONY: altinstall altinstall: commoninstall if test "x$(ENSUREPIP)" != "xno" ; then \ case $(ENSUREPIP) in \ @@ -1855,6 +1890,7 @@ altinstall: commoninstall $$ensurepip --root=$(DESTDIR)/ ; \ fi +.PHONY: commoninstall commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ altbininstall libinstall inclinstall libainstall \ sharedinstall altmaninstall \ @@ -1863,6 +1899,7 @@ commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) +.PHONY: sharedinstall sharedinstall: all @for i in $(DESTDIRS); \ do \ @@ -1885,6 +1922,7 @@ sharedinstall: all # Install the interpreter with $(VERSION) affixed # This goes into $(exec_prefix) +.PHONY: altbininstall altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ @for i in $(BINDIR) $(LIBDIR); \ do \ @@ -1950,7 +1988,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ fi \ fi - +.PHONY: bininstall bininstall: altbininstall if test ! -d $(DESTDIR)$(LIBPC); then \ echo "Creating directory $(LIBPC)"; \ @@ -1991,6 +2029,7 @@ bininstall: altbininstall fi # Install the versioned manual page +.PHONY: altmaninstall altmaninstall: @for i in $(MANDIR) $(MANDIR)/man1; \ do \ @@ -2004,6 +2043,7 @@ altmaninstall: $(DESTDIR)$(MANDIR)/man1/python$(VERSION).1 # Install the unversioned manual page +.PHONY: maninstall maninstall: altmaninstall -rm -f $(DESTDIR)$(MANDIR)/man1/python3.1 (cd $(DESTDIR)$(MANDIR)/man1; $(LN) -s python$(VERSION).1 python3.1) @@ -2060,6 +2100,7 @@ TESTSUBDIRS= idlelib/idle_test \ test/sndhdrdata \ test/subprocessdata \ test/support \ + test/support/_hypothesis_stubs \ test/test_asyncio \ test/test_capi \ test/test_ctypes \ @@ -2161,6 +2202,8 @@ TESTSUBDIRS= idlelib/idle_test \ COMPILEALL_OPTS=-j0 TEST_MODULES=@TEST_MODULES@ + +.PHONY: libinstall libinstall: all $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ @@ -2281,10 +2324,13 @@ $(SCRIPT_PYDOC): $(srcdir)/Tools/scripts/pydoc3 sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/pydoc3 > $@ @chmod +x $@ +.PHONY: scripts scripts: $(SCRIPT_2TO3) $(SCRIPT_IDLE) $(SCRIPT_PYDOC) python-config # Install the include files INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY) + +.PHONY: inclinstall inclinstall: @for i in $(INCLDIRSTOMAKE); \ do \ @@ -2328,6 +2374,7 @@ LIBPL= @LIBPL@ # pkgconfig directory LIBPC= $(LIBDIR)/pkgconfig +.PHONY: libainstall libainstall: all scripts @for i in $(LIBDIR) $(LIBPL) $(LIBPC) $(BINDIR); \ do \ @@ -2391,6 +2438,7 @@ libainstall: all scripts # # This target is here for backward compatibility, previous versions of Python # hadn't integrated framework installation in the normal install process. +.PHONY: frameworkinstall frameworkinstall: install # On install, we re-make the framework @@ -2399,8 +2447,10 @@ frameworkinstall: install # automatically set prefix to the location deep down in the framework, so we # only have to cater for the structural bits of the framework. +.PHONY: frameworkinstallframework frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib +.PHONY: frameworkinstallstructure frameworkinstallstructure: $(LDLIBRARY) @if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ echo Not configured with --enable-framework; \ @@ -2425,6 +2475,7 @@ frameworkinstallstructure: $(LDLIBRARY) # This installs Mac/Lib into the framework # Install a number of symlinks to keep software that expects a normal unix # install (which includes python-config) happy. +.PHONY: frameworkinstallmaclib frameworkinstallmaclib: $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).a" $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).dylib" @@ -2434,25 +2485,30 @@ frameworkinstallmaclib: $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" # This installs the IDE, the Launcher and other apps into /Applications +.PHONY: frameworkinstallapps frameworkinstallapps: cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)" # Build the bootstrap executable that will spawn the interpreter inside # an app bundle within the framework. This allows the interpreter to # run OS X GUI APIs. +.PHONY: frameworkpythonw frameworkpythonw: cd Mac && $(MAKE) pythonw # This installs the python* and other bin symlinks in $prefix/bin or in # a bin directory relative to the framework root +.PHONY: frameworkinstallunixtools frameworkinstallunixtools: cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)" +.PHONY: frameworkaltinstallunixtools frameworkaltinstallunixtools: cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)" # This installs the Tools into the applications directory. # It is not part of a normal frameworkinstall +.PHONY: frameworkinstallextras frameworkinstallextras: cd Mac && $(MAKE) installextras DESTDIR="$(DESTDIR)" @@ -2482,11 +2538,13 @@ Python/dtoa.o: Python/dtoa.c $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_ALIASING) -o $@ $< # Run reindent on the library +.PHONY: reindent reindent: ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/reindent.py -r $(srcdir)/Lib # Rerun configure with the same options as it was run last time, # provided the config.status script exists +.PHONY: recheck recheck: ./config.status --recheck ./config.status @@ -2523,10 +2581,12 @@ TAGS:: # Sanitation targets -- clean leaves libraries, executables and tags # files, which clobber removes as well +.PHONY: pycremoval pycremoval: -find $(srcdir) -depth -name '__pycache__' -exec rm -rf {} ';' -find $(srcdir) -name '*.py[co]' -exec rm -f {} ';' +.PHONY: rmtestturds rmtestturds: -rm -f *BAD *GOOD *SKIPPED -rm -rf OUT @@ -2534,11 +2594,13 @@ rmtestturds: -rm -f *.txt -rm -f gb-18030-2000.xml +.PHONY: docclean docclean: $(MAKE) -C $(srcdir)/Doc clean # like the 'clean' target but retain the profile guided optimization (PGO) # data. The PGO data is only valid if source code remains unchanged. +.PHONY: clean-retain-profile clean-retain-profile: pycremoval find . -name '*.[oa]' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' @@ -2562,6 +2624,7 @@ clean-retain-profile: pycremoval -rm -f Include/pydtrace_probes.h -rm -f profile-gen-stamp +.PHONY: profile-removal profile-removal: find . -name '*.gc??' -exec rm -f {} ';' find . -name '*.profclang?' -exec rm -f {} ';' @@ -2570,12 +2633,14 @@ profile-removal: rm -rf $(COVERAGE_REPORT) rm -f profile-run-stamp +.PHONY: clean clean: clean-retain-profile @if test @DEF_MAKE_ALL_RULE@ = profile-opt; then \ rm -f profile-gen-stamp profile-clean-stamp; \ $(MAKE) profile-removal; \ fi +.PHONY: clobber clobber: clean -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \ tags TAGS \ @@ -2587,6 +2652,7 @@ clobber: clean # Make things extra clean, before making a distribution: # remove all generated files, even Makefile[.pre] # Keep configure and Python-ast.[ch], it's possible they can't be generated +.PHONY: distclean distclean: clobber docclean for file in $(srcdir)/Lib/test/data/* ; do \ if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \ @@ -2607,16 +2673,19 @@ distclean: clobber docclean -exec rm -f {} ';' # Check that all symbols exported by libpython start with "Py" or "_Py" +.PHONY: smelly smelly: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/smelly.py # Check if any unsupported C global variables have been added. +.PHONY: check-c-globals check-c-globals: $(PYTHON_FOR_REGEN) $(srcdir)/Tools/c-analyzer/check-c-globals.py \ --format summary \ --traceback # Find files with funny names +.PHONY: funny funny: find $(SUBDIRS) $(SUBDIRSTOO) \ -type d \ @@ -2648,9 +2717,11 @@ funny: -o -print # Perform some verification checks on any modified files. +.PHONY: patchcheck patchcheck: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/patchcheck.py +.PHONY: check-limited-abi check-limited-abi: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --all $(srcdir)/Misc/stable_abi.toml @@ -2664,19 +2735,6 @@ update-config: 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 rundsymutil -.PHONY: install altinstall sharedinstall bininstall altbininstall -.PHONY: maninstall libinstall inclinstall libainstall -.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure -.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools -.PHONY: frameworkaltinstallunixtools recheck clean clobber distclean -.PHONY: smelly funny patchcheck touch altmaninstall commoninstall -.PHONY: clean-retain-profile profile-removal run_profile_task -.PHONY: build_all_generate_profile build_all_merge_profile -.PHONY: gdbhooks scripts - ########################################################################## # Module dependencies and platform-specific files diff --git a/Misc/NEWS.d/next/Build/2023-05-14-19-00-19.gh-issue-104490.1tA4AF.rst b/Misc/NEWS.d/next/Build/2023-05-14-19-00-19.gh-issue-104490.1tA4AF.rst new file mode 100644 index 00000000000000..1315b5cb3c1969 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-05-14-19-00-19.gh-issue-104490.1tA4AF.rst @@ -0,0 +1 @@ +Define ``.PHONY`` / virtual make targets consistently and properly. diff --git a/Misc/NEWS.d/next/Build/2023-05-15-09-34-08.gh-issue-99017.nToOQu.rst b/Misc/NEWS.d/next/Build/2023-05-15-09-34-08.gh-issue-99017.nToOQu.rst new file mode 100644 index 00000000000000..a3517ac0204b1d --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-05-15-09-34-08.gh-issue-99017.nToOQu.rst @@ -0,0 +1 @@ +``PYTHON_FOR_REGEN`` now require Python 3.10 or newer. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-09-04-30-02.gh-issue-103333.gKOetS.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-09-04-30-02.gh-issue-103333.gKOetS.rst new file mode 100644 index 00000000000000..793f02c2afdcff --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-09-04-30-02.gh-issue-103333.gKOetS.rst @@ -0,0 +1 @@ +:exc:`AttributeError` now retains the ``name`` attribute when pickled and unpickled. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-11-15-56-07.gh-issue-104405.tXV5fn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-11-15-56-07.gh-issue-104405.tXV5fn.rst new file mode 100644 index 00000000000000..06ec5d7b0f0cc9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-05-11-15-56-07.gh-issue-104405.tXV5fn.rst @@ -0,0 +1,2 @@ +Fix an issue where some :term:`bytecode` instructions could ignore +:pep:`523` when "inlining" calls. diff --git a/Misc/NEWS.d/next/Documentation/2023-05-14-12-11-28.gh-issue-67056.nVC2Rf.rst b/Misc/NEWS.d/next/Documentation/2023-05-14-12-11-28.gh-issue-67056.nVC2Rf.rst new file mode 100644 index 00000000000000..2c6ef17810723d --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2023-05-14-12-11-28.gh-issue-67056.nVC2Rf.rst @@ -0,0 +1,2 @@ +Document that the effect of registering or unregistering an :mod:`atexit` +cleanup function from within a registered cleanup function is undefined. diff --git a/Misc/NEWS.d/next/Library/2023-03-14-11-20-19.gh-issue-101819.0-h0it.rst b/Misc/NEWS.d/next/Library/2023-03-14-11-20-19.gh-issue-101819.0-h0it.rst new file mode 100644 index 00000000000000..4a73bbf32b370e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-03-14-11-20-19.gh-issue-101819.0-h0it.rst @@ -0,0 +1,2 @@ +Isolate the :mod:`io` extension module by applying :pep:`687`. Patch by +Kumar Aditya, Victor Stinner, and Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2023-04-02-23-05-22.gh-issue-103204.bbDmu0.rst b/Misc/NEWS.d/next/Library/2023-04-02-23-05-22.gh-issue-103204.bbDmu0.rst new file mode 100644 index 00000000000000..f8b3aa5151b622 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-02-23-05-22.gh-issue-103204.bbDmu0.rst @@ -0,0 +1,3 @@ +Fixes :mod:`http.server` accepting HTTP requests with HTTP version numbers +preceded by '+', or '-', or with digit-separating '_' characters. The length +of the version numbers is also constrained. diff --git a/Misc/NEWS.d/next/Library/2023-05-12-19-29-28.gh-issue-103857.0IzSxr.rst b/Misc/NEWS.d/next/Library/2023-05-12-19-29-28.gh-issue-103857.0IzSxr.rst new file mode 100644 index 00000000000000..6e8162d9ecc286 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-05-12-19-29-28.gh-issue-103857.0IzSxr.rst @@ -0,0 +1 @@ +Update datetime deprecations' stracktrace to point to the calling line diff --git a/Misc/NEWS.d/next/Tests/2023-05-15-02-22-44.gh-issue-104494.Bkrbfn.rst b/Misc/NEWS.d/next/Tests/2023-05-15-02-22-44.gh-issue-104494.Bkrbfn.rst new file mode 100644 index 00000000000000..a320c48428b58b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-05-15-02-22-44.gh-issue-104494.Bkrbfn.rst @@ -0,0 +1,2 @@ +Update ``test_pack_configure_in`` and ``test_place_configure_in`` +for changes to error message formatting in Tk 8.7. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index f6cda45eaeac27..534ef8c1d6cf8f 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5476,11 +5476,17 @@ comerror_init(PyObject *self, PyObject *args, PyObject *kwds) return 0; } +static int +comerror_clear(PyObject *self) +{ + return ((PyTypeObject *)PyExc_BaseException)->tp_clear(self); +} + static int comerror_traverse(PyObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); - return 0; + return ((PyTypeObject *)PyExc_BaseException)->tp_traverse(self, visit, arg); } static void @@ -5488,6 +5494,7 @@ comerror_dealloc(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); + (void)comerror_clear(self); tp->tp_free(self); Py_DECREF(tp); } @@ -5497,6 +5504,7 @@ static PyType_Slot comerror_slots[] = { {Py_tp_init, comerror_init}, {Py_tp_traverse, comerror_traverse}, {Py_tp_dealloc, comerror_dealloc}, + {Py_tp_clear, comerror_clear}, {0, NULL}, }; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 8f86fc91966205..8b417bdd0fb5b6 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -5147,7 +5147,7 @@ datetime_utcnow(PyObject *cls, PyObject *dummy) if (PyErr_WarnEx(PyExc_DeprecationWarning, "datetime.utcnow() is deprecated and scheduled for removal in a " "future version. Use timezone-aware objects to represent datetimes " - "in UTC: datetime.now(datetime.UTC).", 2)) + "in UTC: datetime.now(datetime.UTC).", 1)) { return NULL; } @@ -5190,7 +5190,7 @@ datetime_utcfromtimestamp(PyObject *cls, PyObject *args) if (PyErr_WarnEx(PyExc_DeprecationWarning, "datetime.utcfromtimestamp() is deprecated and scheduled for removal " "in a future version. Use timezone-aware objects to represent " - "datetimes in UTC: datetime.now(datetime.UTC).", 2)) + "datetimes in UTC: datetime.now(datetime.UTC).", 1)) { return NULL; } diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 2457cb124036fe..7b06c1bee5a832 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -561,25 +561,9 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err) return result; } -_PyIO_State * -_PyIO_get_module_state(void) -{ - PyObject *mod = PyState_FindModule(&_PyIO_Module); - _PyIO_State *state; - if (mod == NULL || (state = get_io_state(mod)) == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "could not find io module state " - "(interpreter shutdown?)"); - return NULL; - } - return state; -} - static int iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = get_io_state(mod); - if (!state->initialized) - return 0; Py_VISIT(state->unsupported_operation); Py_VISIT(state->PyIOBase_Type); @@ -606,8 +590,6 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { static int iomodule_clear(PyObject *mod) { _PyIO_State *state = get_io_state(mod); - if (!state->initialized) - return 0; Py_CLEAR(state->unsupported_operation); Py_CLEAR(state->PyIOBase_Type); @@ -652,115 +634,57 @@ static PyMethodDef module_methods[] = { {NULL, NULL} }; -struct PyModuleDef _PyIO_Module = { - PyModuleDef_HEAD_INIT, - "io", - module_doc, - sizeof(_PyIO_State), - module_methods, - NULL, - iomodule_traverse, - iomodule_clear, - (freefunc)iomodule_free, -}; - - -static PyTypeObject* static_types[] = { - // Base classes - &PyIOBase_Type, - - // PyIOBase_Type subclasses - &PyBufferedIOBase_Type, - &PyRawIOBase_Type, - &PyTextIOBase_Type, -}; - - -PyStatus -_PyIO_InitTypes(PyInterpreterState *interp) -{ - for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { - PyTypeObject *type = static_types[i]; - if (_PyStaticType_InitBuiltin(interp, type) < 0) { - return _PyStatus_ERR("Can't initialize builtin type"); - } - } - - return _PyStatus_OK(); -} - -void -_PyIO_FiniTypes(PyInterpreterState *interp) -{ - // Deallocate types in the reverse order to deallocate subclasses before - // their base classes. - for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) { - PyTypeObject *type = static_types[i]; - _PyStaticType_Dealloc(interp, type); - } -} - #define ADD_TYPE(module, type, spec, base) \ do { \ type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, \ (PyObject *)base); \ if (type == NULL) { \ - goto fail; \ + return -1; \ } \ if (PyModule_AddType(module, type) < 0) { \ - goto fail; \ + return -1; \ } \ } while (0) -PyMODINIT_FUNC -PyInit__io(void) +static int +iomodule_exec(PyObject *m) { - PyObject *m = PyModule_Create(&_PyIO_Module); - _PyIO_State *state = NULL; - if (m == NULL) - return NULL; - state = get_io_state(m); - state->initialized = 0; + _PyIO_State *state = get_io_state(m); /* DEFAULT_BUFFER_SIZE */ if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) - goto fail; + return -1; /* UnsupportedOperation inherits from ValueError and OSError */ state->unsupported_operation = PyObject_CallFunction( (PyObject *)&PyType_Type, "s(OO){}", "UnsupportedOperation", PyExc_OSError, PyExc_ValueError); if (state->unsupported_operation == NULL) - goto fail; + return -1; if (PyModule_AddObjectRef(m, "UnsupportedOperation", state->unsupported_operation) < 0) { - goto fail; + return -1; } /* BlockingIOError, for compatibility */ if (PyModule_AddObjectRef(m, "BlockingIOError", (PyObject *) PyExc_BlockingIOError) < 0) { - goto fail; - } - - // Add types - for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { - PyTypeObject *type = static_types[i]; - if (PyModule_AddType(m, type) < 0) { - goto fail; - } + return -1; } // Base classes - state->PyIOBase_Type = (PyTypeObject *)Py_NewRef(&PyIOBase_Type); ADD_TYPE(m, state->PyIncrementalNewlineDecoder_Type, &nldecoder_spec, NULL); ADD_TYPE(m, state->PyBytesIOBuffer_Type, &bytesiobuf_spec, NULL); + ADD_TYPE(m, state->PyIOBase_Type, &iobase_spec, NULL); // PyIOBase_Type subclasses - state->PyRawIOBase_Type = (PyTypeObject *)Py_NewRef(&PyRawIOBase_Type); - state->PyBufferedIOBase_Type = (PyTypeObject *)Py_NewRef(&PyBufferedIOBase_Type); - state->PyTextIOBase_Type = (PyTypeObject *)Py_NewRef(&PyTextIOBase_Type); + ADD_TYPE(m, state->PyTextIOBase_Type, &textiobase_spec, + state->PyIOBase_Type); + ADD_TYPE(m, state->PyBufferedIOBase_Type, &bufferediobase_spec, + state->PyIOBase_Type); + ADD_TYPE(m, state->PyRawIOBase_Type, &rawiobase_spec, + state->PyIOBase_Type); // PyBufferedIOBase_Type(PyIOBase_Type) subclasses ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, state->PyBufferedIOBase_Type); @@ -775,6 +699,7 @@ PyInit__io(void) // PyRawIOBase_Type(PyIOBase_Type) subclasses ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, state->PyRawIOBase_Type); + #ifdef HAVE_WINDOWS_CONSOLE_IO ADD_TYPE(m, state->PyWindowsConsoleIO_Type, &winconsoleio_spec, state->PyRawIOBase_Type); @@ -785,11 +710,30 @@ PyInit__io(void) ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec, state->PyTextIOBase_Type); - state->initialized = 1; +#undef ADD_TYPE + return 0; +} - return m; +static struct PyModuleDef_Slot iomodule_slots[] = { + {Py_mod_exec, iomodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; - fail: - Py_DECREF(m); - return NULL; +struct PyModuleDef _PyIO_Module = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "io", + .m_doc = module_doc, + .m_size = sizeof(_PyIO_State), + .m_methods = module_methods, + .m_traverse = iomodule_traverse, + .m_clear = iomodule_clear, + .m_free = iomodule_free, + .m_slots = iomodule_slots, +}; + +PyMODINIT_FUNC +PyInit__io(void) +{ + return PyModuleDef_Init(&_PyIO_Module); } diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index ae06fecc48b450..afd638a120ba08 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -8,13 +8,8 @@ #include "pycore_typeobject.h" // _PyType_GetModuleState() #include "structmember.h" -/* ABCs */ -extern PyTypeObject PyIOBase_Type; -extern PyTypeObject PyRawIOBase_Type; -extern PyTypeObject PyBufferedIOBase_Type; -extern PyTypeObject PyTextIOBase_Type; - /* Type specs */ +extern PyType_Spec bufferediobase_spec; extern PyType_Spec bufferedrandom_spec; extern PyType_Spec bufferedreader_spec; extern PyType_Spec bufferedrwpair_spec; @@ -22,8 +17,11 @@ extern PyType_Spec bufferedwriter_spec; extern PyType_Spec bytesio_spec; extern PyType_Spec bytesiobuf_spec; extern PyType_Spec fileio_spec; +extern PyType_Spec iobase_spec; extern PyType_Spec nldecoder_spec; +extern PyType_Spec rawiobase_spec; extern PyType_Spec stringio_spec; +extern PyType_Spec textiobase_spec; extern PyType_Spec textiowrapper_spec; #ifdef HAVE_WINDOWS_CONSOLE_IO @@ -168,9 +166,6 @@ struct _io_state { #endif }; -#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE() _PyIO_get_module_state() - static inline _PyIO_State * get_io_state(PyObject *module) { @@ -195,7 +190,7 @@ find_io_state_by_def(PyTypeObject *type) return get_io_state(mod); } -extern _PyIO_State *_PyIO_get_module_state(void); +extern PyObject *_PyIOBase_cannot_pickle(PyObject *self, PyObject *args); #ifdef HAVE_WINDOWS_CONSOLE_IO extern char _PyIO_get_console_type(PyObject *); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 00e228bca4375b..6f291c34496064 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -16,14 +16,14 @@ /*[clinic input] module _io -class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type" -class _io._Buffered "buffered *" "&PyBufferedIOBase_Type" +class _io._BufferedIOBase "PyObject *" "clinic_state()->PyBufferedIOBase_Type" +class _io._Buffered "buffered *" "clinic_state()->PyBufferedIOBase_Type" class _io.BufferedReader "buffered *" "clinic_state()->PyBufferedReader_Type" class _io.BufferedWriter "buffered *" "clinic_state()->PyBufferedWriter_Type" class _io.BufferedRWPair "rwpair *" "clinic_state()->PyBufferedRWPair_Type" class _io.BufferedRandom "buffered *" "clinic_state()->PyBufferedRandom_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=abd685b9d94b9888]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3b3ef9cbbbad4590]*/ /* * BufferedIOBase class, inherits from IOBase. @@ -128,7 +128,7 @@ static PyObject * _io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls) /*[clinic end generated code: output=b87b135d67cd4448 input=0b61a7b4357c1ea7]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return bufferediobase_unsupported(state, "detach"); } @@ -136,15 +136,15 @@ _io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls) _io._BufferedIOBase.read cls: defining_class + size: int(unused=True) = -1 / - *args: object Read and return up to n bytes. -If the argument is omitted, None, or negative, read and +If the size argument is omitted, None, or negative, read and return all data until EOF. -If the argument is positive, and the underlying raw stream is +If the size argument is positive, and the underlying raw stream is not 'interactive', multiple raw reads may be issued to satisfy the byte count (unless EOF is reached first). However, for interactive raw streams (as well as sockets and pipes), @@ -159,10 +159,10 @@ mode and no data is available at the moment. static PyObject * _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, - PyObject *args) -/*[clinic end generated code: output=4521b30940fd7b67 input=390205758adc8510]*/ + int Py_UNUSED(size)) +/*[clinic end generated code: output=aceb2765587b0a29 input=824f6f910465e61a]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return bufferediobase_unsupported(state, "read"); } @@ -170,10 +170,10 @@ _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, _io._BufferedIOBase.read1 cls: defining_class + size: int(unused=True) = -1 / - *args: object -Read and return up to n bytes, with at most one read() call to the underlying raw stream. +Read and return up to size bytes, with at most one read() call to the underlying raw stream. Return an empty bytes object on EOF. A short result does not imply that EOF is imminent. @@ -181,10 +181,10 @@ A short result does not imply that EOF is imminent. static PyObject * _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, - PyObject *args) -/*[clinic end generated code: output=636fd241c21e050a input=ef546a1238c5b41c]*/ + int Py_UNUSED(size)) +/*[clinic end generated code: output=2e7fc62972487eaa input=af76380e020fd9e6]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return bufferediobase_unsupported(state, "read1"); } @@ -192,10 +192,10 @@ _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, _io._BufferedIOBase.write cls: defining_class + b: object(unused=True) / - *args: object -Write the given buffer to the IO stream. +Write buffer b to the IO stream. Return the number of bytes written, which is always the length of b in bytes. @@ -206,10 +206,10 @@ underlying raw stream cannot accept more data at the moment. static PyObject * _io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls, - PyObject *args) -/*[clinic end generated code: output=d51feea4bcac9892 input=f79b72c4dccb3dc2]*/ + PyObject *Py_UNUSED(b)) +/*[clinic end generated code: output=712c635246bf2306 input=9793f5c8f71029ad]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return bufferediobase_unsupported(state, "write"); } @@ -394,6 +394,15 @@ _enter_buffered_busy(buffered *self) (self->buffer_size * (size / self->buffer_size))) +static int +buffered_clear(buffered *self) +{ + self->ok = 0; + Py_CLEAR(self->raw); + Py_CLEAR(self->dict); + return 0; +} + static void buffered_dealloc(buffered *self) { @@ -405,7 +414,6 @@ buffered_dealloc(buffered *self) self->ok = 0; if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->raw); if (self->buffer) { PyMem_Free(self->buffer); self->buffer = NULL; @@ -414,7 +422,7 @@ buffered_dealloc(buffered *self) PyThread_free_lock(self->lock); self->lock = NULL; } - Py_CLEAR(self->dict); + (void)buffered_clear(self); tp->tp_free((PyObject *)self); Py_DECREF(tp); } @@ -443,15 +451,6 @@ buffered_traverse(buffered *self, visitproc visit, void *arg) return 0; } -static int -buffered_clear(buffered *self) -{ - self->ok = 0; - Py_CLEAR(self->raw); - Py_CLEAR(self->dict); - return 0; -} - /* Because this can call arbitrary code, it shouldn't be called when the refcount is 0 (that is, not directly from tp_dealloc unless the refcount has been temporarily re-incremented). */ @@ -2220,6 +2219,8 @@ bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); + Py_VISIT(self->reader); + Py_VISIT(self->writer); return 0; } @@ -2239,9 +2240,7 @@ bufferedrwpair_dealloc(rwpair *self) _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); + (void)bufferedrwpair_clear(self); tp->tp_free((PyObject *) self); Py_DECREF(tp); } @@ -2424,6 +2423,12 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, #include "clinic/bufferedio.c.h" #undef clinic_state +static int +bufferediobase_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} static PyMethodDef bufferediobase_methods[] = { _IO__BUFFEREDIOBASE_DETACH_METHODDEF @@ -2435,57 +2440,19 @@ static PyMethodDef bufferediobase_methods[] = { {NULL, NULL} }; -PyTypeObject PyBufferedIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BufferedIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - bufferediobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferediobase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot bufferediobase_slots[] = { + {Py_tp_doc, (void *)bufferediobase_doc}, + {Py_tp_methods, bufferediobase_methods}, + {Py_tp_traverse, bufferediobase_traverse}, + {0, NULL}, }; +PyType_Spec bufferediobase_spec = { + .name = "_io._BufferedIOBase", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bufferediobase_slots, +}; static PyMethodDef bufferedreader_methods[] = { /* BufferedIOMixin methods */ @@ -2508,6 +2475,9 @@ static PyMethodDef bufferedreader_methods[] = { _IO__BUFFERED_TELL_METHODDEF _IO__BUFFERED_TRUNCATE_METHODDEF _IO__BUFFERED___SIZEOF___METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; @@ -2565,6 +2535,9 @@ static PyMethodDef bufferedwriter_methods[] = { _IO__BUFFERED_SEEK_METHODDEF _IO__BUFFERED_TELL_METHODDEF _IO__BUFFERED___SIZEOF___METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; @@ -2680,6 +2653,9 @@ static PyMethodDef bufferedrandom_methods[] = { _IO__BUFFERED_PEEK_METHODDEF _IO_BUFFEREDWRITER_WRITE_METHODDEF _IO__BUFFERED___SIZEOF___METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 3fddfc2ed0bc9c..80773058693259 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -979,6 +979,7 @@ bytesio_traverse(bytesio *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); + Py_VISIT(self->buf); return 0; } @@ -986,6 +987,7 @@ static int bytesio_clear(bytesio *self) { Py_CLEAR(self->dict); + Py_CLEAR(self->buf); return 0; } diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index e2ac90c54a10f0..4f40fdadf8ec85 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -108,15 +108,15 @@ _io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *a } PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, -"read($self, /, *args)\n" +"read($self, size=-1, /)\n" "--\n" "\n" "Read and return up to n bytes.\n" "\n" -"If the argument is omitted, None, or negative, read and\n" +"If the size argument is omitted, None, or negative, read and\n" "return all data until EOF.\n" "\n" -"If the argument is positive, and the underlying raw stream is\n" +"If the size argument is positive, and the underlying raw stream is\n" "not \'interactive\', multiple raw reads may be issued to satisfy\n" "the byte count (unless EOF is reached first).\n" "However, for interactive raw streams (as well as sockets and pipes),\n" @@ -133,7 +133,7 @@ PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, static PyObject * _io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, - PyObject *args); + int Py_UNUSED(size)); static PyObject * _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -145,7 +145,7 @@ _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *arg # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "read", @@ -153,25 +153,31 @@ _io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *arg }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + int size = -1; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__BufferedIOBase_read_impl(self, cls, __clinic_args); + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__BufferedIOBase_read_impl(self, cls, size); exit: - Py_XDECREF(__clinic_args); return return_value; } PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, -"read1($self, /, *args)\n" +"read1($self, size=-1, /)\n" "--\n" "\n" -"Read and return up to n bytes, with at most one read() call to the underlying raw stream.\n" +"Read and return up to size bytes, with at most one read() call to the underlying raw stream.\n" "\n" "Return an empty bytes object on EOF.\n" "A short result does not imply that EOF is imminent."); @@ -181,7 +187,7 @@ PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, static PyObject * _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, - PyObject *args); + int Py_UNUSED(size)); static PyObject * _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -193,7 +199,7 @@ _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *ar # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "read1", @@ -201,25 +207,31 @@ _io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *ar }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + int size = -1; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__BufferedIOBase_read1_impl(self, cls, __clinic_args); + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__BufferedIOBase_read1_impl(self, cls, size); exit: - Py_XDECREF(__clinic_args); return return_value; } PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, -"write($self, /, *args)\n" +"write($self, b, /)\n" "--\n" "\n" -"Write the given buffer to the IO stream.\n" +"Write buffer b to the IO stream.\n" "\n" "Return the number of bytes written, which is always\n" "the length of b in bytes.\n" @@ -232,7 +244,7 @@ PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, static PyObject * _io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls, - PyObject *args); + PyObject *Py_UNUSED(b)); static PyObject * _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -244,7 +256,7 @@ _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *ar # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "write", @@ -252,17 +264,16 @@ _io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *ar }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + PyObject *b; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__BufferedIOBase_write_impl(self, cls, __clinic_args); + b = args[0]; + return_value = _io__BufferedIOBase_write_impl(self, cls, b); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -1087,4 +1098,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=d770e392e8702e12 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7ddf84a5bc2bf34 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 7e6b3b5b78e8f6..773e0010477053 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -9,7 +9,7 @@ preserve PyDoc_STRVAR(_io__IOBase_seek__doc__, -"seek($self, /, *args)\n" +"seek($self, offset, whence=os.SEEK_SET, /)\n" "--\n" "\n" "Change the stream position to the given byte offset.\n" @@ -17,9 +17,9 @@ PyDoc_STRVAR(_io__IOBase_seek__doc__, "The offset is interpreted relative to the position indicated by whence.\n" "Values for whence are:\n" "\n" -"* 0 -- start of stream (the default); offset should be zero or positive\n" -"* 1 -- current stream position; offset may be negative\n" -"* 2 -- end of stream; offset is usually negative\n" +"* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive\n" +"* os.SEEK_CUR or 1 -- current stream position; offset may be negative\n" +"* os.SEEK_END or 2 -- end of stream; offset is usually negative\n" "\n" "Return the new absolute position."); @@ -27,7 +27,8 @@ PyDoc_STRVAR(_io__IOBase_seek__doc__, {"seek", _PyCFunction_CAST(_io__IOBase_seek), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_seek__doc__}, static PyObject * -_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, PyObject *args); +_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(offset), int Py_UNUSED(whence)); static PyObject * _io__IOBase_seek(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -39,25 +40,36 @@ _io__IOBase_seek(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ss # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", "", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "seek", .kwtuple = KWTUPLE, }; #undef KWTUPLE - PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + PyObject *argsbuf[2]; + int offset; + int whence = 0; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__IOBase_seek_impl(self, cls, __clinic_args); + offset = _PyLong_AsInt(args[0]); + if (offset == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional_posonly; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__IOBase_seek_impl(self, cls, offset, whence); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -80,7 +92,7 @@ _io__IOBase_tell(PyObject *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_io__IOBase_truncate__doc__, -"truncate($self, /, *args)\n" +"truncate($self, size=None, /)\n" "--\n" "\n" "Truncate file to size bytes.\n" @@ -92,7 +104,8 @@ PyDoc_STRVAR(_io__IOBase_truncate__doc__, {"truncate", _PyCFunction_CAST(_io__IOBase_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_truncate__doc__}, static PyObject * -_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, PyObject *args); +_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, + PyObject *Py_UNUSED(size)); static PyObject * _io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -104,7 +117,7 @@ _io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, P # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "truncate", @@ -112,17 +125,20 @@ _io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, P }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + PyObject *size = Py_None; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__IOBase_truncate_impl(self, cls, __clinic_args); + if (nargs < 1) { + goto skip_optional_posonly; + } + size = args[0]; +skip_optional_posonly: + return_value = _io__IOBase_truncate_impl(self, cls, size); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -420,4 +436,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=63bc25a5bfcecaf0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=301b22f8f75ce3dc input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 01965013ec6abc..33fc23bd4c0c69 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -33,7 +33,7 @@ _io__TextIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, } PyDoc_STRVAR(_io__TextIOBase_read__doc__, -"read($self, /, *args)\n" +"read($self, size=-1, /)\n" "--\n" "\n" "Read at most size characters from stream.\n" @@ -45,7 +45,8 @@ PyDoc_STRVAR(_io__TextIOBase_read__doc__, {"read", _PyCFunction_CAST(_io__TextIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_read__doc__}, static PyObject * -_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args); +_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)); static PyObject * _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -57,7 +58,7 @@ _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, P # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "read", @@ -65,34 +66,41 @@ _io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, P }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + int size = -1; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__TextIOBase_read_impl(self, cls, __clinic_args); + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__TextIOBase_read_impl(self, cls, size); exit: - Py_XDECREF(__clinic_args); return return_value; } PyDoc_STRVAR(_io__TextIOBase_readline__doc__, -"readline($self, /, *args)\n" +"readline($self, size=-1, /)\n" "--\n" "\n" "Read until newline or EOF.\n" "\n" -"Return an empty string if EOF is hit immediately."); +"Return an empty string if EOF is hit immediately.\n" +"If size is specified, at most size characters will be read."); #define _IO__TEXTIOBASE_READLINE_METHODDEF \ {"readline", _PyCFunction_CAST(_io__TextIOBase_readline), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_readline__doc__}, static PyObject * _io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls, - PyObject *args); + int Py_UNUSED(size)); static PyObject * _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -104,7 +112,7 @@ _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *arg # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "readline", @@ -112,25 +120,31 @@ _io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *arg }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + int size = -1; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__TextIOBase_readline_impl(self, cls, __clinic_args); + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__TextIOBase_readline_impl(self, cls, size); exit: - Py_XDECREF(__clinic_args); return return_value; } PyDoc_STRVAR(_io__TextIOBase_write__doc__, -"write($self, /, *args)\n" +"write($self, s, /)\n" "--\n" "\n" -"Write string to stream.\n" +"Write string s to stream.\n" "\n" "Return the number of characters written\n" "(which is always equal to the length of the string)."); @@ -139,7 +153,8 @@ PyDoc_STRVAR(_io__TextIOBase_write__doc__, {"write", _PyCFunction_CAST(_io__TextIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_write__doc__}, static PyObject * -_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, PyObject *args); +_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, + const char *Py_UNUSED(s)); static PyObject * _io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -151,7 +166,7 @@ _io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, # define KWTUPLE NULL #endif - static const char * const _keywords[] = { NULL}; + static const char * const _keywords[] = {"", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "write", @@ -159,17 +174,28 @@ _io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *__clinic_args = NULL; + const char *s; - args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - __clinic_args = args[0]; - return_value = _io__TextIOBase_write_impl(self, cls, __clinic_args); + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("write", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t s_length; + s = PyUnicode_AsUTF8AndSize(args[0], &s_length); + if (s == NULL) { + goto exit; + } + if (strlen(s) != (size_t)s_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _io__TextIOBase_write_impl(self, cls, s); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -934,4 +960,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=d800e5a8a50d6720 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=42f592331302973f input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 473f0a8a6befcb..30944fc56bf70e 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -536,7 +536,7 @@ fileio_dealloc(fileio *self) _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); + (void)fileio_clear(self); tp->tp_free((PyObject *)self); Py_DECREF(tp); } @@ -1166,6 +1166,8 @@ static PyMethodDef fileio_methods[] = { _IO_FILEIO_FILENO_METHODDEF _IO_FILEIO_ISATTY_METHODDEF {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 26f2a3155bda62..14d48813aefe83 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -17,10 +17,10 @@ /*[clinic input] module _io -class _io._IOBase "PyObject *" "&PyIOBase_Type" -class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" +class _io._IOBase "PyObject *" "clinic_state()->PyIOBase_Type" +class _io._RawIOBase "PyObject *" "clinic_state()->PyRawIOBase_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9006b7802ab8ea85]*/ /* * IOBase class, an abstract class @@ -82,26 +82,28 @@ iobase_unsupported(_PyIO_State *state, const char *message) /*[clinic input] _io._IOBase.seek cls: defining_class + offset: int(unused=True) + whence: int(unused=True, c_default='0') = os.SEEK_SET / - *args: object Change the stream position to the given byte offset. The offset is interpreted relative to the position indicated by whence. Values for whence are: -* 0 -- start of stream (the default); offset should be zero or positive -* 1 -- current stream position; offset may be negative -* 2 -- end of stream; offset is usually negative +* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive +* os.SEEK_CUR or 1 -- current stream position; offset may be negative +* os.SEEK_END or 2 -- end of stream; offset is usually negative Return the new absolute position. [clinic start generated code]*/ static PyObject * -_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, PyObject *args) -/*[clinic end generated code: output=1dd694ac9de260fa input=ebb5476eb22fc5d4]*/ +_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(offset), int Py_UNUSED(whence)) +/*[clinic end generated code: output=8bd74ea6538ded53 input=8d4e6adcd08292f2]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return iobase_unsupported(state, "seek"); } @@ -121,8 +123,8 @@ _io__IOBase_tell_impl(PyObject *self) /*[clinic input] _io._IOBase.truncate cls: defining_class + size: object(unused=True) = None / - *args: object Truncate file to size bytes. @@ -131,10 +133,11 @@ as reported by tell(). Return the new size. [clinic start generated code]*/ static PyObject * -_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, PyObject *args) -/*[clinic end generated code: output=b7eed4649cbe22c1 input=ad90582a1d8b5cc9]*/ +_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, + PyObject *Py_UNUSED(size)) +/*[clinic end generated code: output=2013179bff1fe8ef input=660ac20936612c27]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return iobase_unsupported(state, "truncate"); } @@ -220,24 +223,32 @@ _PyIOBase_check_closed(PyObject *self, PyObject *args) static PyObject * iobase_check_seekable(PyObject *self, PyObject *args) { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); return _PyIOBase_check_seekable(state, self, args); } static PyObject * iobase_check_readable(PyObject *self, PyObject *args) { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); return _PyIOBase_check_readable(state, self, args); } static PyObject * iobase_check_writable(PyObject *self, PyObject *args) { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); return _PyIOBase_check_writable(state, self, args); } +PyObject * +_PyIOBase_cannot_pickle(PyObject *self, PyObject *args) +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); + return NULL; +} + /* XXX: IOBase thinks it has to maintain its own internal state in `__IOBase_closed` and call flush() by itself, but it is redundant with whatever behaviour a non-trivial derived class will implement. */ @@ -351,6 +362,7 @@ _PyIOBase_finalize(PyObject *self) static int iobase_traverse(iobase *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); return 0; } @@ -380,11 +392,13 @@ iobase_dealloc(iobase *self) } return; } + PyTypeObject *tp = Py_TYPE(self); _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } /* Inquiry methods */ @@ -523,7 +537,7 @@ static PyObject * _io__IOBase_fileno_impl(PyObject *self, PyTypeObject *cls) /*[clinic end generated code: output=7caaa32a6f4ada3d input=1927c8bea5c85099]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return iobase_unsupported(state, "fileno"); } @@ -821,7 +835,9 @@ _io__IOBase_writelines(PyObject *self, PyObject *lines) Py_RETURN_NONE; } +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/iobase.c.h" +#undef clinic_state static PyMethodDef iobase_methods[] = { _IO__IOBASE_SEEK_METHODDEF @@ -858,59 +874,34 @@ static PyGetSetDef iobase_getset[] = { {NULL} }; +static struct PyMemberDef iobase_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(iobase, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(iobase, dict), READONLY}, + {NULL}, +}; + -PyTypeObject PyIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._IOBase", /*tp_name*/ - sizeof(iobase), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)iobase_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - iobase_doc, /* tp_doc */ - (traverseproc)iobase_traverse, /* tp_traverse */ - (inquiry)iobase_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(iobase, weakreflist), /* tp_weaklistoffset */ - iobase_iter, /* tp_iter */ - iobase_iternext, /* tp_iternext */ - iobase_methods, /* tp_methods */ - 0, /* tp_members */ - iobase_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(iobase, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - iobase_finalize, /* tp_finalize */ +static PyType_Slot iobase_slots[] = { + {Py_tp_dealloc, iobase_dealloc}, + {Py_tp_doc, (void *)iobase_doc}, + {Py_tp_traverse, iobase_traverse}, + {Py_tp_clear, iobase_clear}, + {Py_tp_iter, iobase_iter}, + {Py_tp_iternext, iobase_iternext}, + {Py_tp_methods, iobase_methods}, + {Py_tp_members, iobase_members}, + {Py_tp_getset, iobase_getset}, + {Py_tp_finalize, iobase_finalize}, + {0, NULL}, }; +PyType_Spec iobase_spec = { + .name = "_io._IOBase", + .basicsize = sizeof(iobase), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = iobase_slots, +}; /* * RawIOBase class, Inherits from IOBase. @@ -1045,6 +1036,13 @@ rawiobase_write(PyObject *self, PyObject *args) return NULL; } +static int +rawiobase_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static PyMethodDef rawiobase_methods[] = { _IO__RAWIOBASE_READ_METHODDEF _IO__RAWIOBASE_READALL_METHODDEF @@ -1053,53 +1051,16 @@ static PyMethodDef rawiobase_methods[] = { {NULL, NULL} }; -PyTypeObject PyRawIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._RawIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - rawiobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - rawiobase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot rawiobase_slots[] = { + {Py_tp_doc, (void *)rawiobase_doc}, + {Py_tp_methods, rawiobase_methods}, + {Py_tp_traverse, rawiobase_traverse}, + {0, NULL}, +}; + +PyType_Spec rawiobase_spec = { + .name = "_io._RawIOBase", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = rawiobase_slots, }; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 13d3b870b39a81..3eb25704b4aa55 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -583,6 +583,9 @@ static int stringio_traverse(stringio *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->readnl); + Py_VISIT(self->writenl); + Py_VISIT(self->decoder); Py_VISIT(self->dict); return 0; } @@ -590,6 +593,9 @@ stringio_traverse(stringio *self, visitproc visit, void *arg) static int stringio_clear(stringio *self) { + Py_CLEAR(self->readnl); + Py_CLEAR(self->writenl); + Py_CLEAR(self->decoder); Py_CLEAR(self->dict); return 0; } @@ -605,10 +611,7 @@ stringio_dealloc(stringio *self) self->buf = NULL; } _PyUnicodeWriter_Dealloc(&self->writer); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - Py_CLEAR(self->dict); + (void)stringio_clear(self); if (self->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 3cc292cc35102e..e858a1fb498f82 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -62,15 +62,15 @@ static PyObject * _io__TextIOBase_detach_impl(PyObject *self, PyTypeObject *cls) /*[clinic end generated code: output=50915f40c609eaa4 input=987ca3640d0a3776]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return _unsupported(state, "detach"); } /*[clinic input] _io._TextIOBase.read cls: defining_class + size: int(unused=True) = -1 / - *args: object Read at most size characters from stream. @@ -79,50 +79,53 @@ If size is negative or omitted, read until EOF. [clinic start generated code]*/ static PyObject * -_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, PyObject *args) -/*[clinic end generated code: output=3adf28998831f461 input=cee1e84664a20de0]*/ +_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)) +/*[clinic end generated code: output=51a5178a309ce647 input=f5e37720f9fc563f]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return _unsupported(state, "read"); } /*[clinic input] _io._TextIOBase.readline cls: defining_class + size: int(unused=True) = -1 / - *args: object Read until newline or EOF. Return an empty string if EOF is hit immediately. +If size is specified, at most size characters will be read. [clinic start generated code]*/ static PyObject * _io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls, - PyObject *args) -/*[clinic end generated code: output=3073a948d02319f3 input=58f801259f7ff3ef]*/ + int Py_UNUSED(size)) +/*[clinic end generated code: output=3f47d7966d6d074e input=42eafec94107fa27]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return _unsupported(state, "readline"); } /*[clinic input] _io._TextIOBase.write cls: defining_class + s: str(unused=True) / - *args: object -Write string to stream. +Write string s to stream. Return the number of characters written (which is always equal to the length of the string). [clinic start generated code]*/ static PyObject * -_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, PyObject *args) -/*[clinic end generated code: output=5d985eb529472bc4 input=21b6961b5cba9496]*/ +_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, + const char *Py_UNUSED(s)) +/*[clinic end generated code: output=18b28231460275de input=e9cabaa5f6732b07]*/ { - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = get_io_state_by_cls(cls); return _unsupported(state, "write"); } @@ -164,6 +167,12 @@ textiobase_errors_get(PyObject *self, void *context) Py_RETURN_NONE; } +static int +textiobase_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} static PyMethodDef textiobase_methods[] = { _IO__TEXTIOBASE_DETACH_METHODDEF @@ -180,57 +189,20 @@ static PyGetSetDef textiobase_getset[] = { {NULL} }; -PyTypeObject PyTextIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._TextIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - textiobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - textiobase_methods, /* tp_methods */ - 0, /* tp_members */ - textiobase_getset, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot textiobase_slots[] = { + {Py_tp_doc, (void *)textiobase_doc}, + {Py_tp_methods, textiobase_methods}, + {Py_tp_getset, textiobase_getset}, + {Py_tp_traverse, textiobase_traverse}, + {0, NULL}, }; +PyType_Spec textiobase_spec = { + .name = "_io._TextIOBase", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = textiobase_slots, +}; /* IncrementalNewlineDecoder */ @@ -1456,7 +1428,7 @@ textiowrapper_dealloc(textio *self) _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - textiowrapper_clear(self); + (void)textiowrapper_clear(self); tp->tp_free((PyObject *)self); Py_DECREF(tp); } @@ -3267,6 +3239,9 @@ static PyMethodDef textiowrapper_methods[] = { _IO_TEXTIOWRAPPER_SEEK_METHODDEF _IO_TEXTIOWRAPPER_TELL_METHODDEF _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index d65e247737a071..15f3053957da61 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -1096,7 +1096,7 @@ _io__WindowsConsoleIO_isatty_impl(winconsoleio *self) Py_RETURN_TRUE; } -#define clinic_state() (IO_STATE()) +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/winconsoleio.c.h" #undef clinic_state diff --git a/Modules/_testcapi/clinic/float.c.h b/Modules/_testcapi/clinic/float.c.h new file mode 100644 index 00000000000000..c1dff2a9ac5789 --- /dev/null +++ b/Modules/_testcapi/clinic/float.c.h @@ -0,0 +1,88 @@ +/*[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(_testcapi_float_pack__doc__, +"float_pack($module, size, d, le, /)\n" +"--\n" +"\n" +"Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()"); + +#define _TESTCAPI_FLOAT_PACK_METHODDEF \ + {"float_pack", _PyCFunction_CAST(_testcapi_float_pack), METH_FASTCALL, _testcapi_float_pack__doc__}, + +static PyObject * +_testcapi_float_pack_impl(PyObject *module, int size, double d, int le); + +static PyObject * +_testcapi_float_pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int size; + double d; + int le; + + if (!_PyArg_CheckPositional("float_pack", nargs, 3, 3)) { + goto exit; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_CheckExact(args[1])) { + d = PyFloat_AS_DOUBLE(args[1]); + } + else + { + d = PyFloat_AsDouble(args[1]); + if (d == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + le = _PyLong_AsInt(args[2]); + if (le == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _testcapi_float_pack_impl(module, size, d, le); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_float_unpack__doc__, +"float_unpack($module, data, le, /)\n" +"--\n" +"\n" +"Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8()"); + +#define _TESTCAPI_FLOAT_UNPACK_METHODDEF \ + {"float_unpack", _PyCFunction_CAST(_testcapi_float_unpack), METH_FASTCALL, _testcapi_float_unpack__doc__}, + +static PyObject * +_testcapi_float_unpack_impl(PyObject *module, const char *data, + Py_ssize_t data_length, int le); + +static PyObject * +_testcapi_float_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *data; + Py_ssize_t data_length; + int le; + + if (!_PyArg_ParseStack(args, nargs, "y#i:float_unpack", + &data, &data_length, &le)) { + goto exit; + } + return_value = _testcapi_float_unpack_impl(module, data, data_length, le); + +exit: + return return_value; +} +/*[clinic end generated code: output=083e5df26cd5fbeb input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/float.c b/Modules/_testcapi/float.c index 26d99d990e0042..33cbda83a81af7 100644 --- a/Modules/_testcapi/float.c +++ b/Modules/_testcapi/float.c @@ -1,18 +1,29 @@ #define PY_SSIZE_T_CLEAN #include "parts.h" +#include "clinic/float.c.h" -// Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() +/*[clinic input] +module _testcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ + +/*[clinic input] +_testcapi.float_pack + + size: int + d: double + le: int + / + +Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() +[clinic start generated code]*/ + static PyObject * -test_float_pack(PyObject *self, PyObject *args) +_testcapi_float_pack_impl(PyObject *module, int size, double d, int le) +/*[clinic end generated code: output=7899bd98f8b6cb04 input=52c9115121999c98]*/ { - int size; - double d; - int le; - if (!PyArg_ParseTuple(args, "idi", &size, &d, &le)) { - return NULL; - } switch (size) { case 2: @@ -47,19 +58,24 @@ test_float_pack(PyObject *self, PyObject *args) } -// Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() +/*[clinic input] +_testcapi.float_unpack + + data: str(accept={robuffer}, zeroes=True) + le: int + / + +Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() +[clinic start generated code]*/ + static PyObject * -test_float_unpack(PyObject *self, PyObject *args) +_testcapi_float_unpack_impl(PyObject *module, const char *data, + Py_ssize_t data_length, int le) +/*[clinic end generated code: output=617059f889ddbfe4 input=c095e4bb75a696cd]*/ { assert(!PyErr_Occurred()); - const char *data; - Py_ssize_t size; - int le; - if (!PyArg_ParseTuple(args, "y#i", &data, &size, &le)) { - return NULL; - } double d; - switch (size) + switch (data_length) { case 2: d = PyFloat_Unpack2(data, le); @@ -82,8 +98,8 @@ test_float_unpack(PyObject *self, PyObject *args) } static PyMethodDef test_methods[] = { - {"float_pack", test_float_pack, METH_VARARGS, NULL}, - {"float_unpack", test_float_unpack, METH_VARARGS, NULL}, + _TESTCAPI_FLOAT_PACK_METHODDEF + _TESTCAPI_FLOAT_UNPACK_METHODDEF {NULL}, }; diff --git a/Objects/exceptions.c b/Objects/exceptions.c index ba5ee291f08b0c..a8d4e3a696ce8e 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2287,6 +2287,48 @@ AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } +/* Pickling support */ +static PyObject * +AttributeError_getstate(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *dict = ((PyAttributeErrorObject *)self)->dict; + if (self->name || self->args) { + dict = dict ? PyDict_Copy(dict) : PyDict_New(); + if (dict == NULL) { + return NULL; + } + if (self->name && PyDict_SetItemString(dict, "name", self->name) < 0) { + Py_DECREF(dict); + return NULL; + } + /* We specifically are not pickling the obj attribute since there are many + cases where it is unlikely to be picklable. See GH-103352. + */ + if (self->args && PyDict_SetItemString(dict, "args", self->args) < 0) { + Py_DECREF(dict); + return NULL; + } + return dict; + } + else if (dict) { + return Py_NewRef(dict); + } + Py_RETURN_NONE; +} + +static PyObject * +AttributeError_reduce(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *state = AttributeError_getstate(self, NULL); + if (state == NULL) { + return NULL; + } + + PyObject *return_value = PyTuple_Pack(3, Py_TYPE(self), self->args, state); + Py_DECREF(state); + return return_value; +} + static PyMemberDef AttributeError_members[] = { {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")}, {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")}, @@ -2294,7 +2336,9 @@ static PyMemberDef AttributeError_members[] = { }; static PyMethodDef AttributeError_methods[] = { - {NULL} /* Sentinel */ + {"__getstate__", (PyCFunction)AttributeError_getstate, METH_NOARGS}, + {"__reduce__", (PyCFunction)AttributeError_reduce, METH_NOARGS }, + {NULL} }; ComplexExtendsException(PyExc_Exception, AttributeError, diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index de62aeb04461fa..090129fe8653f2 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -882,7 +882,7 @@ _Py_GetGlobalAllocatedBlocks(void) /* Return a pointer to a bottom tree node, return NULL if it doesn't exist or * it cannot be created */ -static Py_ALWAYS_INLINE arena_map_bot_t * +static inline Py_ALWAYS_INLINE arena_map_bot_t * arena_map_get(OMState *state, pymem_block *p, int create) { #ifdef USE_INTERIOR_NODES diff --git a/Python/assemble.c b/Python/assemble.c index 6889831ae3fe0c..8789d8ef978c22 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -128,7 +128,7 @@ assemble_emit_exception_table_entry(struct assembler *a, int start, int end, assert(end > start); int target = handler->h_offset; int depth = handler->h_startdepth - 1; - if (handler->h_preserve_lasti) { + if (handler->h_preserve_lasti > 0) { depth -= 1; } assert(depth >= 0); @@ -146,6 +146,7 @@ assemble_exception_table(struct assembler *a, instr_sequence *instrs) int ioffset = 0; _PyCompile_ExceptHandlerInfo handler; handler.h_offset = -1; + handler.h_preserve_lasti = -1; int start = -1; for (int i = 0; i < instrs->s_used; i++) { instruction *instr = &instrs->s_instrs[i]; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index bdfd963dfb7579..d5100281baf285 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -494,6 +494,7 @@ dummy_func( } inst(BINARY_SUBSCR_GETITEM, (unused/1, container, sub -- unused)) { + DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); PyTypeObject *tp = Py_TYPE(container); DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR); PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; @@ -830,8 +831,9 @@ dummy_func( DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ assert(frame != &entry_frame); - if ((Py_TYPE(receiver) == &PyGen_Type || - Py_TYPE(receiver) == &PyCoro_Type) && ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) + if ((tstate->interp->eval_frame == NULL) && + (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && + ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) { PyGenObject *gen = (PyGenObject *)receiver; _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; @@ -867,6 +869,7 @@ dummy_func( } inst(SEND_GEN, (unused/1, receiver, v -- receiver, unused)) { + DEOPT_IF(tstate->interp->eval_frame, SEND); PyGenObject *gen = (PyGenObject *)receiver; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); @@ -2363,6 +2366,7 @@ dummy_func( } inst(FOR_ITER_GEN, (unused/1, iter -- iter, unused)) { + DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index f5515d0d32dedf..e92ff0bd6fba6f 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -105,6 +105,7 @@ #define DISPATCH_INLINED(NEW_FRAME) \ do { \ + assert(tstate->interp->eval_frame == NULL); \ _PyFrame_SetStackPointer(frame, stack_pointer); \ frame->prev_instr = next_instr - 1; \ (NEW_FRAME)->previous = frame; \ diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7d47ca0b9ca980..7eeca446bd4027 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -708,6 +708,7 @@ PyObject *sub = stack_pointer[-1]; PyObject *container = stack_pointer[-2]; #line 497 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); PyTypeObject *tp = Py_TYPE(container); DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR); PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; @@ -729,15 +730,15 @@ JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 733 "Python/generated_cases.c.h" + #line 734 "Python/generated_cases.c.h" } TARGET(LIST_APPEND) { PyObject *v = stack_pointer[-1]; PyObject *list = stack_pointer[-(2 + (oparg-1))]; - #line 521 "Python/bytecodes.c" + #line 522 "Python/bytecodes.c" if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error; - #line 741 "Python/generated_cases.c.h" + #line 742 "Python/generated_cases.c.h" STACK_SHRINK(1); PREDICT(JUMP_BACKWARD); DISPATCH(); @@ -746,13 +747,13 @@ TARGET(SET_ADD) { PyObject *v = stack_pointer[-1]; PyObject *set = stack_pointer[-(2 + (oparg-1))]; - #line 526 "Python/bytecodes.c" + #line 527 "Python/bytecodes.c" int err = PySet_Add(set, v); - #line 752 "Python/generated_cases.c.h" + #line 753 "Python/generated_cases.c.h" Py_DECREF(v); - #line 528 "Python/bytecodes.c" + #line 529 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 756 "Python/generated_cases.c.h" + #line 757 "Python/generated_cases.c.h" STACK_SHRINK(1); PREDICT(JUMP_BACKWARD); DISPATCH(); @@ -765,7 +766,7 @@ PyObject *container = stack_pointer[-2]; PyObject *v = stack_pointer[-3]; uint16_t counter = read_u16(&next_instr[0].cache); - #line 539 "Python/bytecodes.c" + #line 540 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { next_instr--; @@ -780,13 +781,13 @@ #endif /* ENABLE_SPECIALIZATION */ /* container[sub] = v */ int err = PyObject_SetItem(container, sub, v); - #line 784 "Python/generated_cases.c.h" + #line 785 "Python/generated_cases.c.h" Py_DECREF(v); Py_DECREF(container); Py_DECREF(sub); - #line 554 "Python/bytecodes.c" + #line 555 "Python/bytecodes.c" if (err) goto pop_3_error; - #line 790 "Python/generated_cases.c.h" + #line 791 "Python/generated_cases.c.h" STACK_SHRINK(3); next_instr += 1; DISPATCH(); @@ -796,7 +797,7 @@ PyObject *sub = stack_pointer[-1]; PyObject *list = stack_pointer[-2]; PyObject *value = stack_pointer[-3]; - #line 558 "Python/bytecodes.c" + #line 559 "Python/bytecodes.c" DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); @@ -813,7 +814,7 @@ Py_DECREF(old_value); _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(list); - #line 817 "Python/generated_cases.c.h" + #line 818 "Python/generated_cases.c.h" STACK_SHRINK(3); next_instr += 1; DISPATCH(); @@ -823,13 +824,13 @@ PyObject *sub = stack_pointer[-1]; PyObject *dict = stack_pointer[-2]; PyObject *value = stack_pointer[-3]; - #line 577 "Python/bytecodes.c" + #line 578 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); STAT_INC(STORE_SUBSCR, hit); int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); Py_DECREF(dict); if (err) goto pop_3_error; - #line 833 "Python/generated_cases.c.h" + #line 834 "Python/generated_cases.c.h" STACK_SHRINK(3); next_instr += 1; DISPATCH(); @@ -838,15 +839,15 @@ TARGET(DELETE_SUBSCR) { PyObject *sub = stack_pointer[-1]; PyObject *container = stack_pointer[-2]; - #line 585 "Python/bytecodes.c" + #line 586 "Python/bytecodes.c" /* del container[sub] */ int err = PyObject_DelItem(container, sub); - #line 845 "Python/generated_cases.c.h" + #line 846 "Python/generated_cases.c.h" Py_DECREF(container); Py_DECREF(sub); - #line 588 "Python/bytecodes.c" + #line 589 "Python/bytecodes.c" if (err) goto pop_2_error; - #line 850 "Python/generated_cases.c.h" + #line 851 "Python/generated_cases.c.h" STACK_SHRINK(2); DISPATCH(); } @@ -854,14 +855,14 @@ TARGET(CALL_INTRINSIC_1) { PyObject *value = stack_pointer[-1]; PyObject *res; - #line 592 "Python/bytecodes.c" + #line 593 "Python/bytecodes.c" assert(oparg <= MAX_INTRINSIC_1); res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); - #line 861 "Python/generated_cases.c.h" + #line 862 "Python/generated_cases.c.h" Py_DECREF(value); - #line 595 "Python/bytecodes.c" + #line 596 "Python/bytecodes.c" if (res == NULL) goto pop_1_error; - #line 865 "Python/generated_cases.c.h" + #line 866 "Python/generated_cases.c.h" stack_pointer[-1] = res; DISPATCH(); } @@ -870,15 +871,15 @@ PyObject *value1 = stack_pointer[-1]; PyObject *value2 = stack_pointer[-2]; PyObject *res; - #line 599 "Python/bytecodes.c" + #line 600 "Python/bytecodes.c" assert(oparg <= MAX_INTRINSIC_2); res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1); - #line 877 "Python/generated_cases.c.h" + #line 878 "Python/generated_cases.c.h" Py_DECREF(value2); Py_DECREF(value1); - #line 602 "Python/bytecodes.c" + #line 603 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 882 "Python/generated_cases.c.h" + #line 883 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -886,7 +887,7 @@ TARGET(RAISE_VARARGS) { PyObject **args = (stack_pointer - oparg); - #line 606 "Python/bytecodes.c" + #line 607 "Python/bytecodes.c" PyObject *cause = NULL, *exc = NULL; switch (oparg) { case 2: @@ -904,12 +905,12 @@ break; } if (true) { STACK_SHRINK(oparg); goto error; } - #line 908 "Python/generated_cases.c.h" + #line 909 "Python/generated_cases.c.h" } TARGET(INTERPRETER_EXIT) { PyObject *retval = stack_pointer[-1]; - #line 626 "Python/bytecodes.c" + #line 627 "Python/bytecodes.c" assert(frame == &entry_frame); assert(_PyFrame_IsIncomplete(frame)); STACK_SHRINK(1); // Since we're not going to DISPATCH() @@ -920,12 +921,12 @@ assert(!_PyErr_Occurred(tstate)); _Py_LeaveRecursiveCallTstate(tstate); return retval; - #line 924 "Python/generated_cases.c.h" + #line 925 "Python/generated_cases.c.h" } TARGET(RETURN_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 639 "Python/bytecodes.c" + #line 640 "Python/bytecodes.c" STACK_SHRINK(1); assert(EMPTY()); _PyFrame_SetStackPointer(frame, stack_pointer); @@ -938,12 +939,12 @@ frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 942 "Python/generated_cases.c.h" + #line 943 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_RETURN_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 654 "Python/bytecodes.c" + #line 655 "Python/bytecodes.c" int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, frame, next_instr-1, retval); @@ -960,11 +961,11 @@ frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 964 "Python/generated_cases.c.h" + #line 965 "Python/generated_cases.c.h" } TARGET(RETURN_CONST) { - #line 673 "Python/bytecodes.c" + #line 674 "Python/bytecodes.c" PyObject *retval = GETITEM(frame->f_code->co_consts, oparg); Py_INCREF(retval); assert(EMPTY()); @@ -978,11 +979,11 @@ frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 982 "Python/generated_cases.c.h" + #line 983 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_RETURN_CONST) { - #line 689 "Python/bytecodes.c" + #line 690 "Python/bytecodes.c" PyObject *retval = GETITEM(frame->f_code->co_consts, oparg); int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, @@ -1000,13 +1001,13 @@ frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1004 "Python/generated_cases.c.h" + #line 1005 "Python/generated_cases.c.h" } TARGET(GET_AITER) { PyObject *obj = stack_pointer[-1]; PyObject *iter; - #line 709 "Python/bytecodes.c" + #line 710 "Python/bytecodes.c" unaryfunc getter = NULL; PyTypeObject *type = Py_TYPE(obj); @@ -1019,16 +1020,16 @@ "'async for' requires an object with " "__aiter__ method, got %.100s", type->tp_name); - #line 1023 "Python/generated_cases.c.h" + #line 1024 "Python/generated_cases.c.h" Py_DECREF(obj); - #line 722 "Python/bytecodes.c" + #line 723 "Python/bytecodes.c" if (true) goto pop_1_error; } iter = (*getter)(obj); - #line 1030 "Python/generated_cases.c.h" + #line 1031 "Python/generated_cases.c.h" Py_DECREF(obj); - #line 727 "Python/bytecodes.c" + #line 728 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; if (Py_TYPE(iter)->tp_as_async == NULL || @@ -1041,7 +1042,7 @@ Py_DECREF(iter); if (true) goto pop_1_error; } - #line 1045 "Python/generated_cases.c.h" + #line 1046 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -1049,7 +1050,7 @@ TARGET(GET_ANEXT) { PyObject *aiter = stack_pointer[-1]; PyObject *awaitable; - #line 742 "Python/bytecodes.c" + #line 743 "Python/bytecodes.c" unaryfunc getter = NULL; PyObject *next_iter = NULL; PyTypeObject *type = Py_TYPE(aiter); @@ -1093,7 +1094,7 @@ } } - #line 1097 "Python/generated_cases.c.h" + #line 1098 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = awaitable; PREDICT(LOAD_CONST); @@ -1104,16 +1105,16 @@ PREDICTED(GET_AWAITABLE); PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 789 "Python/bytecodes.c" + #line 790 "Python/bytecodes.c" iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { format_awaitable_error(tstate, Py_TYPE(iterable), oparg); } - #line 1115 "Python/generated_cases.c.h" + #line 1116 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 796 "Python/bytecodes.c" + #line 797 "Python/bytecodes.c" if (iter != NULL && PyCoro_CheckExact(iter)) { PyObject *yf = _PyGen_yf((PyGenObject*)iter); @@ -1131,7 +1132,7 @@ if (iter == NULL) goto pop_1_error; - #line 1135 "Python/generated_cases.c.h" + #line 1136 "Python/generated_cases.c.h" stack_pointer[-1] = iter; PREDICT(LOAD_CONST); DISPATCH(); @@ -1143,7 +1144,7 @@ PyObject *v = stack_pointer[-1]; PyObject *receiver = stack_pointer[-2]; PyObject *retval; - #line 822 "Python/bytecodes.c" + #line 823 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PySendCache *cache = (_PySendCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1155,8 +1156,9 @@ DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ assert(frame != &entry_frame); - if ((Py_TYPE(receiver) == &PyGen_Type || - Py_TYPE(receiver) == &PyCoro_Type) && ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) + if ((tstate->interp->eval_frame == NULL) && + (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && + ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) { PyGenObject *gen = (PyGenObject *)receiver; _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; @@ -1189,7 +1191,7 @@ } } Py_DECREF(v); - #line 1193 "Python/generated_cases.c.h" + #line 1195 "Python/generated_cases.c.h" stack_pointer[-1] = retval; next_instr += 1; DISPATCH(); @@ -1198,7 +1200,8 @@ TARGET(SEND_GEN) { PyObject *v = stack_pointer[-1]; PyObject *receiver = stack_pointer[-2]; - #line 870 "Python/bytecodes.c" + #line 872 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, SEND); PyGenObject *gen = (PyGenObject *)receiver; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); @@ -1213,12 +1216,12 @@ tstate->exc_info = &gen->gi_exc_state; JUMPBY(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); - #line 1217 "Python/generated_cases.c.h" + #line 1220 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_YIELD_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 887 "Python/bytecodes.c" + #line 890 "Python/bytecodes.c" assert(frame != &entry_frame); PyGenObject *gen = _PyFrame_GetGenerator(frame); gen->gi_frame_state = FRAME_SUSPENDED; @@ -1235,12 +1238,12 @@ gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1239 "Python/generated_cases.c.h" + #line 1242 "Python/generated_cases.c.h" } TARGET(YIELD_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 906 "Python/bytecodes.c" + #line 909 "Python/bytecodes.c" // 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. @@ -1256,15 +1259,15 @@ gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1260 "Python/generated_cases.c.h" + #line 1263 "Python/generated_cases.c.h" } TARGET(POP_EXCEPT) { PyObject *exc_value = stack_pointer[-1]; - #line 924 "Python/bytecodes.c" + #line 927 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; Py_XSETREF(exc_info->exc_value, exc_value); - #line 1268 "Python/generated_cases.c.h" + #line 1271 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -1272,7 +1275,7 @@ TARGET(RERAISE) { PyObject *exc = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); - #line 929 "Python/bytecodes.c" + #line 932 "Python/bytecodes.c" assert(oparg >= 0 && oparg <= 2); if (oparg) { PyObject *lasti = values[0]; @@ -1290,26 +1293,26 @@ Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); goto exception_unwind; - #line 1294 "Python/generated_cases.c.h" + #line 1297 "Python/generated_cases.c.h" } TARGET(END_ASYNC_FOR) { PyObject *exc = stack_pointer[-1]; PyObject *awaitable = stack_pointer[-2]; - #line 949 "Python/bytecodes.c" + #line 952 "Python/bytecodes.c" assert(exc && PyExceptionInstance_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { - #line 1303 "Python/generated_cases.c.h" + #line 1306 "Python/generated_cases.c.h" Py_DECREF(awaitable); Py_DECREF(exc); - #line 952 "Python/bytecodes.c" + #line 955 "Python/bytecodes.c" } else { Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); goto exception_unwind; } - #line 1313 "Python/generated_cases.c.h" + #line 1316 "Python/generated_cases.c.h" STACK_SHRINK(2); DISPATCH(); } @@ -1320,23 +1323,23 @@ PyObject *sub_iter = stack_pointer[-3]; PyObject *none; PyObject *value; - #line 961 "Python/bytecodes.c" + #line 964 "Python/bytecodes.c" assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); - #line 1329 "Python/generated_cases.c.h" + #line 1332 "Python/generated_cases.c.h" Py_DECREF(sub_iter); Py_DECREF(last_sent_val); Py_DECREF(exc_value); - #line 966 "Python/bytecodes.c" + #line 969 "Python/bytecodes.c" none = Py_NewRef(Py_None); } else { _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); goto exception_unwind; } - #line 1340 "Python/generated_cases.c.h" + #line 1343 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = value; stack_pointer[-2] = none; @@ -1345,9 +1348,9 @@ TARGET(LOAD_ASSERTION_ERROR) { PyObject *value; - #line 975 "Python/bytecodes.c" + #line 978 "Python/bytecodes.c" value = Py_NewRef(PyExc_AssertionError); - #line 1351 "Python/generated_cases.c.h" + #line 1354 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1355,7 +1358,7 @@ TARGET(LOAD_BUILD_CLASS) { PyObject *bc; - #line 979 "Python/bytecodes.c" + #line 982 "Python/bytecodes.c" if (PyDict_CheckExact(BUILTINS())) { bc = _PyDict_GetItemWithError(BUILTINS(), &_Py_ID(__build_class__)); @@ -1377,7 +1380,7 @@ if (true) goto error; } } - #line 1381 "Python/generated_cases.c.h" + #line 1384 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = bc; DISPATCH(); @@ -1385,33 +1388,33 @@ TARGET(STORE_NAME) { PyObject *v = stack_pointer[-1]; - #line 1003 "Python/bytecodes.c" + #line 1006 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *ns = LOCALS(); int err; if (ns == NULL) { _PyErr_Format(tstate, PyExc_SystemError, "no locals found when storing %R", name); - #line 1396 "Python/generated_cases.c.h" + #line 1399 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1010 "Python/bytecodes.c" + #line 1013 "Python/bytecodes.c" if (true) goto pop_1_error; } if (PyDict_CheckExact(ns)) err = PyDict_SetItem(ns, name, v); else err = PyObject_SetItem(ns, name, v); - #line 1405 "Python/generated_cases.c.h" + #line 1408 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1017 "Python/bytecodes.c" + #line 1020 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1409 "Python/generated_cases.c.h" + #line 1412 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(DELETE_NAME) { - #line 1021 "Python/bytecodes.c" + #line 1024 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *ns = LOCALS(); int err; @@ -1428,7 +1431,7 @@ name); goto error; } - #line 1432 "Python/generated_cases.c.h" + #line 1435 "Python/generated_cases.c.h" DISPATCH(); } @@ -1436,7 +1439,7 @@ PREDICTED(UNPACK_SEQUENCE); static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); PyObject *seq = stack_pointer[-1]; - #line 1047 "Python/bytecodes.c" + #line 1050 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1449,11 +1452,11 @@ #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; int res = unpack_iterable(tstate, seq, oparg, -1, top); - #line 1453 "Python/generated_cases.c.h" + #line 1456 "Python/generated_cases.c.h" Py_DECREF(seq); - #line 1060 "Python/bytecodes.c" + #line 1063 "Python/bytecodes.c" if (res == 0) goto pop_1_error; - #line 1457 "Python/generated_cases.c.h" + #line 1460 "Python/generated_cases.c.h" STACK_SHRINK(1); STACK_GROW(oparg); next_instr += 1; @@ -1463,14 +1466,14 @@ TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1064 "Python/bytecodes.c" + #line 1067 "Python/bytecodes.c" DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); assert(oparg == 2); STAT_INC(UNPACK_SEQUENCE, hit); values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); - #line 1474 "Python/generated_cases.c.h" + #line 1477 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1481,7 +1484,7 @@ TARGET(UNPACK_SEQUENCE_TUPLE) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1074 "Python/bytecodes.c" + #line 1077 "Python/bytecodes.c" DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1489,7 +1492,7 @@ for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - #line 1493 "Python/generated_cases.c.h" + #line 1496 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1500,7 +1503,7 @@ TARGET(UNPACK_SEQUENCE_LIST) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1085 "Python/bytecodes.c" + #line 1088 "Python/bytecodes.c" DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1508,7 +1511,7 @@ for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - #line 1512 "Python/generated_cases.c.h" + #line 1515 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1518,15 +1521,15 @@ TARGET(UNPACK_EX) { PyObject *seq = stack_pointer[-1]; - #line 1096 "Python/bytecodes.c" + #line 1099 "Python/bytecodes.c" int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); - #line 1526 "Python/generated_cases.c.h" + #line 1529 "Python/generated_cases.c.h" Py_DECREF(seq); - #line 1100 "Python/bytecodes.c" + #line 1103 "Python/bytecodes.c" if (res == 0) goto pop_1_error; - #line 1530 "Python/generated_cases.c.h" + #line 1533 "Python/generated_cases.c.h" STACK_GROW((oparg & 0xFF) + (oparg >> 8)); DISPATCH(); } @@ -1537,7 +1540,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *v = stack_pointer[-2]; uint16_t counter = read_u16(&next_instr[0].cache); - #line 1111 "Python/bytecodes.c" + #line 1114 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { PyObject *name = GETITEM(frame->f_code->co_names, oparg); @@ -1553,12 +1556,12 @@ #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, v); - #line 1557 "Python/generated_cases.c.h" + #line 1560 "Python/generated_cases.c.h" Py_DECREF(v); Py_DECREF(owner); - #line 1127 "Python/bytecodes.c" + #line 1130 "Python/bytecodes.c" if (err) goto pop_2_error; - #line 1562 "Python/generated_cases.c.h" + #line 1565 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -1566,34 +1569,34 @@ TARGET(DELETE_ATTR) { PyObject *owner = stack_pointer[-1]; - #line 1131 "Python/bytecodes.c" + #line 1134 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - #line 1573 "Python/generated_cases.c.h" + #line 1576 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1134 "Python/bytecodes.c" + #line 1137 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1577 "Python/generated_cases.c.h" + #line 1580 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(STORE_GLOBAL) { PyObject *v = stack_pointer[-1]; - #line 1138 "Python/bytecodes.c" + #line 1141 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); - #line 1587 "Python/generated_cases.c.h" + #line 1590 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1141 "Python/bytecodes.c" + #line 1144 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1591 "Python/generated_cases.c.h" + #line 1594 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(DELETE_GLOBAL) { - #line 1145 "Python/bytecodes.c" + #line 1148 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err; err = PyDict_DelItem(GLOBALS(), name); @@ -1605,13 +1608,13 @@ } goto error; } - #line 1609 "Python/generated_cases.c.h" + #line 1612 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_NAME) { PyObject *v; - #line 1159 "Python/bytecodes.c" + #line 1162 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *locals = LOCALS(); if (locals == NULL) { @@ -1670,7 +1673,7 @@ } } } - #line 1674 "Python/generated_cases.c.h" + #line 1677 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = v; DISPATCH(); @@ -1681,7 +1684,7 @@ static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); PyObject *null = NULL; PyObject *v; - #line 1226 "Python/bytecodes.c" + #line 1229 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1733,7 +1736,7 @@ } } null = NULL; - #line 1737 "Python/generated_cases.c.h" + #line 1740 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = v; @@ -1747,7 +1750,7 @@ PyObject *res; uint16_t index = read_u16(&next_instr[1].cache); uint16_t version = read_u16(&next_instr[2].cache); - #line 1280 "Python/bytecodes.c" + #line 1283 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); @@ -1758,7 +1761,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1762 "Python/generated_cases.c.h" + #line 1765 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1773,7 +1776,7 @@ uint16_t index = read_u16(&next_instr[1].cache); uint16_t mod_version = read_u16(&next_instr[2].cache); uint16_t bltn_version = read_u16(&next_instr[3].cache); - #line 1293 "Python/bytecodes.c" + #line 1296 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); @@ -1788,7 +1791,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1792 "Python/generated_cases.c.h" + #line 1795 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1798,16 +1801,16 @@ } TARGET(DELETE_FAST) { - #line 1310 "Python/bytecodes.c" + #line 1313 "Python/bytecodes.c" PyObject *v = GETLOCAL(oparg); if (v == NULL) goto unbound_local_error; SETLOCAL(oparg, NULL); - #line 1806 "Python/generated_cases.c.h" + #line 1809 "Python/generated_cases.c.h" DISPATCH(); } TARGET(MAKE_CELL) { - #line 1316 "Python/bytecodes.c" + #line 1319 "Python/bytecodes.c" // "initial" is probably NULL but not if it's an arg (or set // via PyFrame_LocalsToFast() before MAKE_CELL has run). PyObject *initial = GETLOCAL(oparg); @@ -1816,12 +1819,12 @@ goto resume_with_error; } SETLOCAL(oparg, cell); - #line 1820 "Python/generated_cases.c.h" + #line 1823 "Python/generated_cases.c.h" DISPATCH(); } TARGET(DELETE_DEREF) { - #line 1327 "Python/bytecodes.c" + #line 1330 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); // Can't use ERROR_IF here. @@ -1832,13 +1835,13 @@ } PyCell_SET(cell, NULL); Py_DECREF(oldobj); - #line 1836 "Python/generated_cases.c.h" + #line 1839 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_CLASSDEREF) { PyObject *value; - #line 1340 "Python/bytecodes.c" + #line 1343 "Python/bytecodes.c" PyObject *name, *locals = LOCALS(); assert(locals); assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); @@ -1870,7 +1873,7 @@ } Py_INCREF(value); } - #line 1874 "Python/generated_cases.c.h" + #line 1877 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1878,7 +1881,7 @@ TARGET(LOAD_DEREF) { PyObject *value; - #line 1374 "Python/bytecodes.c" + #line 1377 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { @@ -1886,7 +1889,7 @@ if (true) goto error; } Py_INCREF(value); - #line 1890 "Python/generated_cases.c.h" + #line 1893 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1894,18 +1897,18 @@ TARGET(STORE_DEREF) { PyObject *v = stack_pointer[-1]; - #line 1384 "Python/bytecodes.c" + #line 1387 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); Py_XDECREF(oldobj); - #line 1903 "Python/generated_cases.c.h" + #line 1906 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(COPY_FREE_VARS) { - #line 1391 "Python/bytecodes.c" + #line 1394 "Python/bytecodes.c" /* Copy closure variables to free variables */ PyCodeObject *co = frame->f_code; assert(PyFunction_Check(frame->f_funcobj)); @@ -1916,22 +1919,22 @@ PyObject *o = PyTuple_GET_ITEM(closure, i); frame->localsplus[offset + i] = Py_NewRef(o); } - #line 1920 "Python/generated_cases.c.h" + #line 1923 "Python/generated_cases.c.h" DISPATCH(); } TARGET(BUILD_STRING) { PyObject **pieces = (stack_pointer - oparg); PyObject *str; - #line 1404 "Python/bytecodes.c" + #line 1407 "Python/bytecodes.c" str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); - #line 1929 "Python/generated_cases.c.h" + #line 1932 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); } - #line 1406 "Python/bytecodes.c" + #line 1409 "Python/bytecodes.c" if (str == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1935 "Python/generated_cases.c.h" + #line 1938 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = str; @@ -1941,10 +1944,10 @@ TARGET(BUILD_TUPLE) { PyObject **values = (stack_pointer - oparg); PyObject *tup; - #line 1410 "Python/bytecodes.c" + #line 1413 "Python/bytecodes.c" tup = _PyTuple_FromArraySteal(values, oparg); if (tup == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1948 "Python/generated_cases.c.h" + #line 1951 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = tup; @@ -1954,10 +1957,10 @@ TARGET(BUILD_LIST) { PyObject **values = (stack_pointer - oparg); PyObject *list; - #line 1415 "Python/bytecodes.c" + #line 1418 "Python/bytecodes.c" list = _PyList_FromArraySteal(values, oparg); if (list == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1961 "Python/generated_cases.c.h" + #line 1964 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = list; @@ -1967,7 +1970,7 @@ TARGET(LIST_EXTEND) { PyObject *iterable = stack_pointer[-1]; PyObject *list = stack_pointer[-(2 + (oparg-1))]; - #line 1420 "Python/bytecodes.c" + #line 1423 "Python/bytecodes.c" PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && @@ -1978,13 +1981,13 @@ "Value after * must be an iterable, not %.200s", Py_TYPE(iterable)->tp_name); } - #line 1982 "Python/generated_cases.c.h" + #line 1985 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1431 "Python/bytecodes.c" + #line 1434 "Python/bytecodes.c" if (true) goto pop_1_error; } Py_DECREF(none_val); - #line 1988 "Python/generated_cases.c.h" + #line 1991 "Python/generated_cases.c.h" Py_DECREF(iterable); STACK_SHRINK(1); DISPATCH(); @@ -1993,13 +1996,13 @@ TARGET(SET_UPDATE) { PyObject *iterable = stack_pointer[-1]; PyObject *set = stack_pointer[-(2 + (oparg-1))]; - #line 1438 "Python/bytecodes.c" + #line 1441 "Python/bytecodes.c" int err = _PySet_Update(set, iterable); - #line 1999 "Python/generated_cases.c.h" + #line 2002 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1440 "Python/bytecodes.c" + #line 1443 "Python/bytecodes.c" if (err < 0) goto pop_1_error; - #line 2003 "Python/generated_cases.c.h" + #line 2006 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -2007,7 +2010,7 @@ TARGET(BUILD_SET) { PyObject **values = (stack_pointer - oparg); PyObject *set; - #line 1444 "Python/bytecodes.c" + #line 1447 "Python/bytecodes.c" set = PySet_New(NULL); if (set == NULL) goto error; @@ -2022,7 +2025,7 @@ Py_DECREF(set); if (true) { STACK_SHRINK(oparg); goto error; } } - #line 2026 "Python/generated_cases.c.h" + #line 2029 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = set; @@ -2032,7 +2035,7 @@ TARGET(BUILD_MAP) { PyObject **values = (stack_pointer - oparg*2); PyObject *map; - #line 1461 "Python/bytecodes.c" + #line 1464 "Python/bytecodes.c" map = _PyDict_FromItems( values, 2, values+1, 2, @@ -2040,13 +2043,13 @@ if (map == NULL) goto error; - #line 2044 "Python/generated_cases.c.h" + #line 2047 "Python/generated_cases.c.h" for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } - #line 1469 "Python/bytecodes.c" + #line 1472 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } - #line 2050 "Python/generated_cases.c.h" + #line 2053 "Python/generated_cases.c.h" STACK_SHRINK(oparg*2); STACK_GROW(1); stack_pointer[-1] = map; @@ -2054,7 +2057,7 @@ } TARGET(SETUP_ANNOTATIONS) { - #line 1473 "Python/bytecodes.c" + #line 1476 "Python/bytecodes.c" int err; PyObject *ann_dict; if (LOCALS() == NULL) { @@ -2094,7 +2097,7 @@ Py_DECREF(ann_dict); } } - #line 2098 "Python/generated_cases.c.h" + #line 2101 "Python/generated_cases.c.h" DISPATCH(); } @@ -2102,7 +2105,7 @@ PyObject *keys = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); PyObject *map; - #line 1515 "Python/bytecodes.c" + #line 1518 "Python/bytecodes.c" if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -2112,14 +2115,14 @@ map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, values, 1, oparg); - #line 2116 "Python/generated_cases.c.h" + #line 2119 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(values[_i]); } Py_DECREF(keys); - #line 1525 "Python/bytecodes.c" + #line 1528 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } - #line 2123 "Python/generated_cases.c.h" + #line 2126 "Python/generated_cases.c.h" STACK_SHRINK(oparg); stack_pointer[-1] = map; DISPATCH(); @@ -2127,7 +2130,7 @@ TARGET(DICT_UPDATE) { PyObject *update = stack_pointer[-1]; - #line 1529 "Python/bytecodes.c" + #line 1532 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { @@ -2135,12 +2138,12 @@ "'%.200s' object is not a mapping", Py_TYPE(update)->tp_name); } - #line 2139 "Python/generated_cases.c.h" + #line 2142 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1537 "Python/bytecodes.c" + #line 1540 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2144 "Python/generated_cases.c.h" + #line 2147 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); DISPATCH(); @@ -2148,17 +2151,17 @@ TARGET(DICT_MERGE) { PyObject *update = stack_pointer[-1]; - #line 1543 "Python/bytecodes.c" + #line 1546 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (_PyDict_MergeEx(dict, update, 2) < 0) { format_kwargs_error(tstate, PEEK(3 + oparg), update); - #line 2157 "Python/generated_cases.c.h" + #line 2160 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1548 "Python/bytecodes.c" + #line 1551 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2162 "Python/generated_cases.c.h" + #line 2165 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); PREDICT(CALL_FUNCTION_EX); @@ -2168,26 +2171,26 @@ TARGET(MAP_ADD) { PyObject *value = stack_pointer[-1]; PyObject *key = stack_pointer[-2]; - #line 1555 "Python/bytecodes.c" + #line 1558 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; - #line 2178 "Python/generated_cases.c.h" + #line 2181 "Python/generated_cases.c.h" STACK_SHRINK(2); PREDICT(JUMP_BACKWARD); DISPATCH(); } TARGET(INSTRUMENTED_LOAD_SUPER_ATTR) { - #line 1564 "Python/bytecodes.c" + #line 1567 "Python/bytecodes.c" _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we // don't want to specialize instrumented instructions INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); - #line 2191 "Python/generated_cases.c.h" + #line 2194 "Python/generated_cases.c.h" } TARGET(LOAD_SUPER_ATTR) { @@ -2198,7 +2201,7 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2 = NULL; PyObject *res; - #line 1578 "Python/bytecodes.c" + #line 1581 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); int load_method = oparg & 1; #if ENABLE_SPECIALIZATION @@ -2240,16 +2243,16 @@ } } } - #line 2244 "Python/generated_cases.c.h" + #line 2247 "Python/generated_cases.c.h" Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - #line 1620 "Python/bytecodes.c" + #line 1623 "Python/bytecodes.c" if (super == NULL) goto pop_3_error; res = PyObject_GetAttr(super, name); Py_DECREF(super); if (res == NULL) goto pop_3_error; - #line 2253 "Python/generated_cases.c.h" + #line 2256 "Python/generated_cases.c.h" STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2264,20 +2267,20 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2 = NULL; PyObject *res; - #line 1627 "Python/bytecodes.c" + #line 1630 "Python/bytecodes.c" assert(!(oparg & 1)); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); - #line 2275 "Python/generated_cases.c.h" + #line 2278 "Python/generated_cases.c.h" Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - #line 1634 "Python/bytecodes.c" + #line 1637 "Python/bytecodes.c" if (res == NULL) goto pop_3_error; - #line 2281 "Python/generated_cases.c.h" + #line 2284 "Python/generated_cases.c.h" STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2292,7 +2295,7 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2; PyObject *res; - #line 1638 "Python/bytecodes.c" + #line 1641 "Python/bytecodes.c" assert(oparg & 1); DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); @@ -2313,7 +2316,7 @@ res = res2; res2 = NULL; } - #line 2317 "Python/generated_cases.c.h" + #line 2320 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; stack_pointer[-2] = res2; @@ -2327,7 +2330,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *res2 = NULL; PyObject *res; - #line 1675 "Python/bytecodes.c" + #line 1678 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2361,9 +2364,9 @@ NULL | meth | arg1 | ... | argN */ - #line 2365 "Python/generated_cases.c.h" + #line 2368 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1709 "Python/bytecodes.c" + #line 1712 "Python/bytecodes.c" if (meth == NULL) goto pop_1_error; res2 = NULL; res = meth; @@ -2372,12 +2375,12 @@ else { /* Classic, pushes one value. */ res = PyObject_GetAttr(owner, name); - #line 2376 "Python/generated_cases.c.h" + #line 2379 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1718 "Python/bytecodes.c" + #line 1721 "Python/bytecodes.c" if (res == NULL) goto pop_1_error; } - #line 2381 "Python/generated_cases.c.h" + #line 2384 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -2391,7 +2394,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1723 "Python/bytecodes.c" + #line 1726 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2404,7 +2407,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2408 "Python/generated_cases.c.h" + #line 2411 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2419,7 +2422,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1739 "Python/bytecodes.c" + #line 1742 "Python/bytecodes.c" DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict != NULL); @@ -2432,7 +2435,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2436 "Python/generated_cases.c.h" + #line 2439 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2447,7 +2450,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1755 "Python/bytecodes.c" + #line 1758 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2474,7 +2477,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2478 "Python/generated_cases.c.h" + #line 2481 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2489,7 +2492,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1785 "Python/bytecodes.c" + #line 1788 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2499,7 +2502,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2503 "Python/generated_cases.c.h" + #line 2506 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2514,7 +2517,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 1798 "Python/bytecodes.c" + #line 1801 "Python/bytecodes.c" DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, @@ -2526,7 +2529,7 @@ res = descr; assert(res != NULL); Py_INCREF(res); - #line 2530 "Python/generated_cases.c.h" + #line 2533 "Python/generated_cases.c.h" Py_DECREF(cls); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2540,7 +2543,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *fget = read_obj(&next_instr[5].cache); - #line 1813 "Python/bytecodes.c" + #line 1816 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); @@ -2564,7 +2567,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2568 "Python/generated_cases.c.h" + #line 2571 "Python/generated_cases.c.h" } TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { @@ -2572,7 +2575,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *getattribute = read_obj(&next_instr[5].cache); - #line 1839 "Python/bytecodes.c" + #line 1842 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); @@ -2598,7 +2601,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2602 "Python/generated_cases.c.h" + #line 2605 "Python/generated_cases.c.h" } TARGET(STORE_ATTR_INSTANCE_VALUE) { @@ -2606,7 +2609,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1867 "Python/bytecodes.c" + #line 1870 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2624,7 +2627,7 @@ Py_DECREF(old_value); } Py_DECREF(owner); - #line 2628 "Python/generated_cases.c.h" + #line 2631 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2635,7 +2638,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t hint = read_u16(&next_instr[3].cache); - #line 1887 "Python/bytecodes.c" + #line 1890 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2674,7 +2677,7 @@ /* PEP 509 */ dict->ma_version_tag = new_version; Py_DECREF(owner); - #line 2678 "Python/generated_cases.c.h" + #line 2681 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2685,7 +2688,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1928 "Python/bytecodes.c" + #line 1931 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2695,7 +2698,7 @@ *(PyObject **)addr = value; Py_XDECREF(old_value); Py_DECREF(owner); - #line 2699 "Python/generated_cases.c.h" + #line 2702 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2707,7 +2710,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1947 "Python/bytecodes.c" + #line 1950 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2720,12 +2723,12 @@ #endif /* ENABLE_SPECIALIZATION */ assert((oparg >> 4) <= Py_GE); res = PyObject_RichCompare(left, right, oparg>>4); - #line 2724 "Python/generated_cases.c.h" + #line 2727 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1960 "Python/bytecodes.c" + #line 1963 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2729 "Python/generated_cases.c.h" + #line 2732 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2736,7 +2739,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1964 "Python/bytecodes.c" + #line 1967 "Python/bytecodes.c" DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2748,7 +2751,7 @@ _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2752 "Python/generated_cases.c.h" + #line 2755 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2759,7 +2762,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1979 "Python/bytecodes.c" + #line 1982 "Python/bytecodes.c" DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); @@ -2775,7 +2778,7 @@ _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2779 "Python/generated_cases.c.h" + #line 2782 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2786,7 +2789,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1998 "Python/bytecodes.c" + #line 2001 "Python/bytecodes.c" DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2799,7 +2802,7 @@ assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2803 "Python/generated_cases.c.h" + #line 2806 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2810,14 +2813,14 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2013 "Python/bytecodes.c" + #line 2016 "Python/bytecodes.c" int res = Py_Is(left, right) ^ oparg; - #line 2816 "Python/generated_cases.c.h" + #line 2819 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 2015 "Python/bytecodes.c" + #line 2018 "Python/bytecodes.c" b = Py_NewRef(res ? Py_True : Py_False); - #line 2821 "Python/generated_cases.c.h" + #line 2824 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2827,15 +2830,15 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2019 "Python/bytecodes.c" + #line 2022 "Python/bytecodes.c" int res = PySequence_Contains(right, left); - #line 2833 "Python/generated_cases.c.h" + #line 2836 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 2021 "Python/bytecodes.c" + #line 2024 "Python/bytecodes.c" if (res < 0) goto pop_2_error; b = Py_NewRef((res^oparg) ? Py_True : Py_False); - #line 2839 "Python/generated_cases.c.h" + #line 2842 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2846,12 +2849,12 @@ PyObject *exc_value = stack_pointer[-2]; PyObject *rest; PyObject *match; - #line 2026 "Python/bytecodes.c" + #line 2029 "Python/bytecodes.c" if (check_except_star_type_valid(tstate, match_type) < 0) { - #line 2852 "Python/generated_cases.c.h" + #line 2855 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 2028 "Python/bytecodes.c" + #line 2031 "Python/bytecodes.c" if (true) goto pop_2_error; } @@ -2859,10 +2862,10 @@ rest = NULL; int res = exception_group_match(exc_value, match_type, &match, &rest); - #line 2863 "Python/generated_cases.c.h" + #line 2866 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 2036 "Python/bytecodes.c" + #line 2039 "Python/bytecodes.c" if (res < 0) goto pop_2_error; assert((match == NULL) == (rest == NULL)); @@ -2871,7 +2874,7 @@ if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } - #line 2875 "Python/generated_cases.c.h" + #line 2878 "Python/generated_cases.c.h" stack_pointer[-1] = match; stack_pointer[-2] = rest; DISPATCH(); @@ -2881,21 +2884,21 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2047 "Python/bytecodes.c" + #line 2050 "Python/bytecodes.c" assert(PyExceptionInstance_Check(left)); if (check_except_type_valid(tstate, right) < 0) { - #line 2888 "Python/generated_cases.c.h" + #line 2891 "Python/generated_cases.c.h" Py_DECREF(right); - #line 2050 "Python/bytecodes.c" + #line 2053 "Python/bytecodes.c" if (true) goto pop_1_error; } int res = PyErr_GivenExceptionMatches(left, right); - #line 2895 "Python/generated_cases.c.h" + #line 2898 "Python/generated_cases.c.h" Py_DECREF(right); - #line 2055 "Python/bytecodes.c" + #line 2058 "Python/bytecodes.c" b = Py_NewRef(res ? Py_True : Py_False); - #line 2899 "Python/generated_cases.c.h" + #line 2902 "Python/generated_cases.c.h" stack_pointer[-1] = b; DISPATCH(); } @@ -2904,15 +2907,15 @@ PyObject *fromlist = stack_pointer[-1]; PyObject *level = stack_pointer[-2]; PyObject *res; - #line 2059 "Python/bytecodes.c" + #line 2062 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_name(tstate, frame, name, fromlist, level); - #line 2911 "Python/generated_cases.c.h" + #line 2914 "Python/generated_cases.c.h" Py_DECREF(level); Py_DECREF(fromlist); - #line 2062 "Python/bytecodes.c" + #line 2065 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2916 "Python/generated_cases.c.h" + #line 2919 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -2921,29 +2924,29 @@ TARGET(IMPORT_FROM) { PyObject *from = stack_pointer[-1]; PyObject *res; - #line 2066 "Python/bytecodes.c" + #line 2069 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_from(tstate, from, name); if (res == NULL) goto error; - #line 2929 "Python/generated_cases.c.h" + #line 2932 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); } TARGET(JUMP_FORWARD) { - #line 2072 "Python/bytecodes.c" + #line 2075 "Python/bytecodes.c" JUMPBY(oparg); - #line 2938 "Python/generated_cases.c.h" + #line 2941 "Python/generated_cases.c.h" DISPATCH(); } TARGET(JUMP_BACKWARD) { PREDICTED(JUMP_BACKWARD); - #line 2076 "Python/bytecodes.c" + #line 2079 "Python/bytecodes.c" assert(oparg < INSTR_OFFSET()); JUMPBY(-oparg); - #line 2947 "Python/generated_cases.c.h" + #line 2950 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -2951,7 +2954,7 @@ TARGET(POP_JUMP_IF_FALSE) { PREDICTED(POP_JUMP_IF_FALSE); PyObject *cond = stack_pointer[-1]; - #line 2082 "Python/bytecodes.c" + #line 2085 "Python/bytecodes.c" if (Py_IsTrue(cond)) { _Py_DECREF_NO_DEALLOC(cond); } @@ -2961,9 +2964,9 @@ } else { int err = PyObject_IsTrue(cond); - #line 2965 "Python/generated_cases.c.h" + #line 2968 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2092 "Python/bytecodes.c" + #line 2095 "Python/bytecodes.c" if (err == 0) { JUMPBY(oparg); } @@ -2971,14 +2974,14 @@ if (err < 0) goto pop_1_error; } } - #line 2975 "Python/generated_cases.c.h" + #line 2978 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { PyObject *cond = stack_pointer[-1]; - #line 2102 "Python/bytecodes.c" + #line 2105 "Python/bytecodes.c" if (Py_IsFalse(cond)) { _Py_DECREF_NO_DEALLOC(cond); } @@ -2988,9 +2991,9 @@ } else { int err = PyObject_IsTrue(cond); - #line 2992 "Python/generated_cases.c.h" + #line 2995 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2112 "Python/bytecodes.c" + #line 2115 "Python/bytecodes.c" if (err > 0) { JUMPBY(oparg); } @@ -2998,67 +3001,67 @@ if (err < 0) goto pop_1_error; } } - #line 3002 "Python/generated_cases.c.h" + #line 3005 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { PyObject *value = stack_pointer[-1]; - #line 2122 "Python/bytecodes.c" + #line 2125 "Python/bytecodes.c" if (!Py_IsNone(value)) { - #line 3011 "Python/generated_cases.c.h" + #line 3014 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2124 "Python/bytecodes.c" + #line 2127 "Python/bytecodes.c" JUMPBY(oparg); } else { _Py_DECREF_NO_DEALLOC(value); } - #line 3019 "Python/generated_cases.c.h" + #line 3022 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { PyObject *value = stack_pointer[-1]; - #line 2132 "Python/bytecodes.c" + #line 2135 "Python/bytecodes.c" if (Py_IsNone(value)) { _Py_DECREF_NO_DEALLOC(value); JUMPBY(oparg); } else { - #line 3032 "Python/generated_cases.c.h" + #line 3035 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2138 "Python/bytecodes.c" + #line 2141 "Python/bytecodes.c" } - #line 3036 "Python/generated_cases.c.h" + #line 3039 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - #line 2142 "Python/bytecodes.c" + #line 2145 "Python/bytecodes.c" /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ JUMPBY(-oparg); - #line 3049 "Python/generated_cases.c.h" + #line 3052 "Python/generated_cases.c.h" DISPATCH(); } TARGET(GET_LEN) { PyObject *obj = stack_pointer[-1]; PyObject *len_o; - #line 2151 "Python/bytecodes.c" + #line 2154 "Python/bytecodes.c" // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; len_o = PyLong_FromSsize_t(len_i); if (len_o == NULL) goto error; - #line 3062 "Python/generated_cases.c.h" + #line 3065 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = len_o; DISPATCH(); @@ -3069,16 +3072,16 @@ PyObject *type = stack_pointer[-2]; PyObject *subject = stack_pointer[-3]; PyObject *attrs; - #line 2159 "Python/bytecodes.c" + #line 2162 "Python/bytecodes.c" // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); attrs = match_class(tstate, subject, type, oparg, names); - #line 3078 "Python/generated_cases.c.h" + #line 3081 "Python/generated_cases.c.h" Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); - #line 2164 "Python/bytecodes.c" + #line 2167 "Python/bytecodes.c" if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! } @@ -3086,7 +3089,7 @@ if (_PyErr_Occurred(tstate)) goto pop_3_error; attrs = Py_NewRef(Py_None); // Failure! } - #line 3090 "Python/generated_cases.c.h" + #line 3093 "Python/generated_cases.c.h" STACK_SHRINK(2); stack_pointer[-1] = attrs; DISPATCH(); @@ -3095,10 +3098,10 @@ TARGET(MATCH_MAPPING) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2174 "Python/bytecodes.c" + #line 2177 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = Py_NewRef(match ? Py_True : Py_False); - #line 3102 "Python/generated_cases.c.h" + #line 3105 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3108,10 +3111,10 @@ TARGET(MATCH_SEQUENCE) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2180 "Python/bytecodes.c" + #line 2183 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = Py_NewRef(match ? Py_True : Py_False); - #line 3115 "Python/generated_cases.c.h" + #line 3118 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3122,11 +3125,11 @@ PyObject *keys = stack_pointer[-1]; PyObject *subject = stack_pointer[-2]; PyObject *values_or_none; - #line 2186 "Python/bytecodes.c" + #line 2189 "Python/bytecodes.c" // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = match_keys(tstate, subject, keys); if (values_or_none == NULL) goto error; - #line 3130 "Python/generated_cases.c.h" + #line 3133 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = values_or_none; DISPATCH(); @@ -3135,14 +3138,14 @@ TARGET(GET_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2192 "Python/bytecodes.c" + #line 2195 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); - #line 3142 "Python/generated_cases.c.h" + #line 3145 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2195 "Python/bytecodes.c" + #line 2198 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; - #line 3146 "Python/generated_cases.c.h" + #line 3149 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3150,7 +3153,7 @@ TARGET(GET_YIELD_FROM_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2199 "Python/bytecodes.c" + #line 2202 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -3173,11 +3176,11 @@ if (iter == NULL) { goto error; } - #line 3177 "Python/generated_cases.c.h" + #line 3180 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2222 "Python/bytecodes.c" + #line 2225 "Python/bytecodes.c" } - #line 3181 "Python/generated_cases.c.h" + #line 3184 "Python/generated_cases.c.h" stack_pointer[-1] = iter; PREDICT(LOAD_CONST); DISPATCH(); @@ -3188,7 +3191,7 @@ static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2241 "Python/bytecodes.c" + #line 2244 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3219,7 +3222,7 @@ DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3223 "Python/generated_cases.c.h" + #line 3226 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3227,7 +3230,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2274 "Python/bytecodes.c" + #line 2277 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3253,14 +3256,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3257 "Python/generated_cases.c.h" + #line 3260 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2302 "Python/bytecodes.c" + #line 2305 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3280,7 +3283,7 @@ DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3284 "Python/generated_cases.c.h" + #line 3287 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3290,7 +3293,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2324 "Python/bytecodes.c" + #line 2327 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3310,7 +3313,7 @@ DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3314 "Python/generated_cases.c.h" + #line 3317 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3320,7 +3323,7 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2346 "Python/bytecodes.c" + #line 2349 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3338,7 +3341,7 @@ if (next == NULL) { goto error; } - #line 3342 "Python/generated_cases.c.h" + #line 3345 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3347,7 +3350,8 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2366 "Python/bytecodes.c" + #line 2369 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); @@ -3362,14 +3366,14 @@ assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3366 "Python/generated_cases.c.h" + #line 3370 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2383 "Python/bytecodes.c" + #line 2387 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3392,16 +3396,16 @@ Py_DECREF(enter); goto error; } - #line 3396 "Python/generated_cases.c.h" + #line 3400 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2406 "Python/bytecodes.c" + #line 2410 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3405 "Python/generated_cases.c.h" + #line 3409 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3413,7 +3417,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2416 "Python/bytecodes.c" + #line 2420 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3439,16 +3443,16 @@ Py_DECREF(enter); goto error; } - #line 3443 "Python/generated_cases.c.h" + #line 3447 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2442 "Python/bytecodes.c" + #line 2446 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3452 "Python/generated_cases.c.h" + #line 3456 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3460,7 +3464,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2451 "Python/bytecodes.c" + #line 2455 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3481,7 +3485,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3485 "Python/generated_cases.c.h" + #line 3489 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3490,7 +3494,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2474 "Python/bytecodes.c" + #line 2478 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3500,7 +3504,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3504 "Python/generated_cases.c.h" + #line 3508 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3514,7 +3518,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2486 "Python/bytecodes.c" + #line 2490 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3531,7 +3535,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3535 "Python/generated_cases.c.h" + #line 3539 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3545,7 +3549,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2505 "Python/bytecodes.c" + #line 2509 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3555,7 +3559,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3559 "Python/generated_cases.c.h" + #line 3563 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3569,7 +3573,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2517 "Python/bytecodes.c" + #line 2521 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3583,7 +3587,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3587 "Python/generated_cases.c.h" + #line 3591 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3592,16 +3596,16 @@ } TARGET(KW_NAMES) { - #line 2533 "Python/bytecodes.c" + #line 2537 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts)); kwnames = GETITEM(frame->f_code->co_consts, oparg); - #line 3600 "Python/generated_cases.c.h" + #line 3604 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2539 "Python/bytecodes.c" + #line 2543 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3614,7 +3618,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3618 "Python/generated_cases.c.h" + #line 3622 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3624,7 +3628,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2584 "Python/bytecodes.c" + #line 2588 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3706,7 +3710,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3710 "Python/generated_cases.c.h" + #line 3714 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3718,7 +3722,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2672 "Python/bytecodes.c" + #line 2676 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3728,7 +3732,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3732 "Python/generated_cases.c.h" + #line 3736 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3737,7 +3741,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2684 "Python/bytecodes.c" + #line 2688 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3763,7 +3767,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3767 "Python/generated_cases.c.h" + #line 3771 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3771,7 +3775,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2712 "Python/bytecodes.c" + #line 2716 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3807,7 +3811,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3811 "Python/generated_cases.c.h" + #line 3815 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3815,7 +3819,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2750 "Python/bytecodes.c" + #line 2754 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3825,7 +3829,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3829 "Python/generated_cases.c.h" + #line 3833 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3838,7 +3842,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2762 "Python/bytecodes.c" + #line 2766 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3849,7 +3853,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3853 "Python/generated_cases.c.h" + #line 3857 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3863,7 +3867,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2776 "Python/bytecodes.c" + #line 2780 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3874,7 +3878,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3878 "Python/generated_cases.c.h" + #line 3882 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3888,7 +3892,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2790 "Python/bytecodes.c" + #line 2794 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3910,7 +3914,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3914 "Python/generated_cases.c.h" + #line 3918 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3924,7 +3928,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2815 "Python/bytecodes.c" + #line 2819 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -3952,7 +3956,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3956 "Python/generated_cases.c.h" + #line 3960 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3966,7 +3970,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2846 "Python/bytecodes.c" + #line 2850 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -3998,7 +4002,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 4002 "Python/generated_cases.c.h" + #line 4006 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4012,7 +4016,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2881 "Python/bytecodes.c" + #line 2885 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -4044,7 +4048,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4048 "Python/generated_cases.c.h" + #line 4052 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4058,7 +4062,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2916 "Python/bytecodes.c" + #line 2920 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4083,7 +4087,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4087 "Python/generated_cases.c.h" + #line 4091 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4096,7 +4100,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2943 "Python/bytecodes.c" + #line 2947 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4123,7 +4127,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4127 "Python/generated_cases.c.h" + #line 4131 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4135,7 +4139,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2973 "Python/bytecodes.c" + #line 2977 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4153,14 +4157,14 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4157 "Python/generated_cases.c.h" + #line 4161 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2993 "Python/bytecodes.c" + #line 2997 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4191,7 +4195,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4195 "Python/generated_cases.c.h" + #line 4199 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4204,7 +4208,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3027 "Python/bytecodes.c" + #line 3031 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4233,7 +4237,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4237 "Python/generated_cases.c.h" + #line 4241 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4246,7 +4250,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3059 "Python/bytecodes.c" + #line 3063 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4275,7 +4279,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4279 "Python/generated_cases.c.h" + #line 4283 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4288,7 +4292,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3091 "Python/bytecodes.c" + #line 3095 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4316,7 +4320,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4320 "Python/generated_cases.c.h" + #line 4324 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4326,9 +4330,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3122 "Python/bytecodes.c" + #line 3126 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4332 "Python/generated_cases.c.h" + #line 4336 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4337,7 +4341,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3126 "Python/bytecodes.c" + #line 3130 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4399,14 +4403,14 @@ } result = PyObject_Call(func, callargs, kwargs); } - #line 4403 "Python/generated_cases.c.h" + #line 4407 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3188 "Python/bytecodes.c" + #line 3192 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4410 "Python/generated_cases.c.h" + #line 4414 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4421,7 +4425,7 @@ PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL; PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL; PyObject *func; - #line 3198 "Python/bytecodes.c" + #line 3202 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4450,14 +4454,14 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4454 "Python/generated_cases.c.h" + #line 4458 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0)); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3229 "Python/bytecodes.c" + #line 3233 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4478,7 +4482,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4482 "Python/generated_cases.c.h" + #line 4486 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4486,15 +4490,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3252 "Python/bytecodes.c" + #line 3256 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4492 "Python/generated_cases.c.h" + #line 4496 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3254 "Python/bytecodes.c" + #line 3258 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4498 "Python/generated_cases.c.h" + #line 4502 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4505,7 +4509,7 @@ PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL; PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))]; PyObject *result; - #line 3258 "Python/bytecodes.c" + #line 3262 "Python/bytecodes.c" /* Handles f-string value formatting. */ PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; @@ -4540,7 +4544,7 @@ Py_DECREF(value); Py_XDECREF(fmt_spec); if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } - #line 4544 "Python/generated_cases.c.h" + #line 4548 "Python/generated_cases.c.h" STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); stack_pointer[-1] = result; DISPATCH(); @@ -4549,10 +4553,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3295 "Python/bytecodes.c" + #line 3299 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4556 "Python/generated_cases.c.h" + #line 4560 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4564,7 +4568,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3300 "Python/bytecodes.c" + #line 3304 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4579,12 +4583,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4583 "Python/generated_cases.c.h" + #line 4587 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3315 "Python/bytecodes.c" + #line 3319 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4588 "Python/generated_cases.c.h" + #line 4592 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4594,16 +4598,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3320 "Python/bytecodes.c" + #line 3324 "Python/bytecodes.c" assert(oparg >= 2); - #line 4600 "Python/generated_cases.c.h" + #line 4604 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3324 "Python/bytecodes.c" + #line 3328 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4615,26 +4619,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4619 "Python/generated_cases.c.h" + #line 4623 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3338 "Python/bytecodes.c" + #line 3342 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4625 "Python/generated_cases.c.h" + #line 4629 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3342 "Python/bytecodes.c" + #line 3346 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP); - #line 4632 "Python/generated_cases.c.h" + #line 4636 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3347 "Python/bytecodes.c" + #line 3351 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4643,12 +4647,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4647 "Python/generated_cases.c.h" + #line 4651 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3358 "Python/bytecodes.c" + #line 3362 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4657,12 +4661,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4661 "Python/generated_cases.c.h" + #line 4665 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3369 "Python/bytecodes.c" + #line 3373 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4675,12 +4679,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4679 "Python/generated_cases.c.h" + #line 4683 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3384 "Python/bytecodes.c" + #line 3388 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4693,30 +4697,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4697 "Python/generated_cases.c.h" + #line 4701 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3399 "Python/bytecodes.c" + #line 3403 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4708 "Python/generated_cases.c.h" + #line 4712 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3407 "Python/bytecodes.c" + #line 3411 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4715 "Python/generated_cases.c.h" + #line 4719 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3412 "Python/bytecodes.c" + #line 3416 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4722 "Python/generated_cases.c.h" + #line 4726 "Python/generated_cases.c.h" } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 61f87c5eba60ed..c5dc0f44a38068 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -29,9 +29,6 @@ #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() #include "opcode.h" -extern PyStatus _PyIO_InitTypes(PyInterpreterState *interp); -extern void _PyIO_FiniTypes(PyInterpreterState *interp); - #include // setlocale() #include // getenv() @@ -706,11 +703,6 @@ pycore_init_types(PyInterpreterState *interp) return _PyStatus_ERR("failed to initialize an exception type"); } - status = _PyIO_InitTypes(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = _PyExc_InitGlobalObjects(interp); if (_PyStatus_EXCEPTION(status)) { return status; @@ -1667,8 +1659,6 @@ flush_std_files(void) static void finalize_interp_types(PyInterpreterState *interp) { - _PyIO_FiniTypes(interp); - _PyUnicode_FiniTypes(interp); _PySys_FiniTypes(interp); _PyExc_Fini(interp); diff --git a/Python/specialize.c b/Python/specialize.c index 5071d8ef9a495d..f1684913b1bc30 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -783,6 +783,10 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) if (version == 0) { goto fail; } + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); + goto fail; + } write_u32(lm_cache->keys_version, version); assert(type->tp_version_tag != 0); write_u32(lm_cache->type_version, type->tp_version_tag); @@ -845,6 +849,10 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) if (version == 0) { goto fail; } + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); + goto fail; + } write_u32(lm_cache->keys_version, version); /* borrowed */ write_obj(lm_cache->descr, descr); @@ -1371,6 +1379,10 @@ _Py_Specialize_BinarySubscr( SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OTHER); + goto fail; + } PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type; // This pointer is invalidated by PyType_Modified (see the comment on // struct _specialization_cache): @@ -2192,11 +2204,16 @@ _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg) assert(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == END_FOR || instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == INSTRUMENTED_END_FOR ); + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(FOR_ITER, SPEC_FAIL_OTHER); + goto failure; + } instr->op.code = FOR_ITER_GEN; goto success; } SPECIALIZATION_FAIL(FOR_ITER, _PySpecialization_ClassifyIterator(iter)); +failure: STAT_INC(FOR_ITER, failure); instr->op.code = FOR_ITER; cache->counter = adaptive_counter_backoff(cache->counter); @@ -2214,11 +2231,16 @@ _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr) _PySendCache *cache = (_PySendCache *)(instr + 1); PyTypeObject *tp = Py_TYPE(receiver); if (tp == &PyGen_Type || tp == &PyCoro_Type) { + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(SEND, SPEC_FAIL_OTHER); + goto failure; + } instr->op.code = SEND_GEN; goto success; } SPECIALIZATION_FAIL(SEND, _PySpecialization_ClassifyIterator(receiver)); +failure: STAT_INC(SEND, failure); instr->op.code = SEND; cache->counter = adaptive_counter_backoff(cache->counter); diff --git a/Python/symtable.c b/Python/symtable.c index 9361674bf16594..2c29f608413501 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -575,7 +575,8 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key) static int inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, - PyObject *scopes, PyObject *comp_free) + PyObject *scopes, PyObject *comp_free, + PyObject *promote_to_cell) { PyObject *k, *v; Py_ssize_t pos = 0; @@ -611,7 +612,9 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, // cell vars in comprehension that are locals in outer scope // must be promoted to cell so u_cellvars isn't wrong if (scope == CELL && ste->ste_type == FunctionBlock) { - SET_SCOPE(scopes, k, scope); + if (PySet_Add(promote_to_cell, k) < 0) { + return 0; + } } // free vars in comprehension that are locals in outer scope can @@ -638,7 +641,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, */ static int -analyze_cells(PyObject *scopes, PyObject *free) +analyze_cells(PyObject *scopes, PyObject *free, PyObject *promote_to_cell) { PyObject *name, *v, *v_cell; int success = 0; @@ -653,7 +656,7 @@ analyze_cells(PyObject *scopes, PyObject *free) scope = PyLong_AS_LONG(v); if (scope != LOCAL) continue; - if (!PySet_Contains(free, name)) + if (!PySet_Contains(free, name) && !PySet_Contains(promote_to_cell, name)) continue; /* Replace LOCAL with CELL for this name, and remove from free. It is safe to replace the value of name @@ -803,7 +806,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, PyObject *global) { PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL; - PyObject *newglobal = NULL, *newfree = NULL; + PyObject *newglobal = NULL, *newfree = NULL, *promote_to_cell = NULL; PyObject *temp; int success = 0; Py_ssize_t i, pos = 0; @@ -835,6 +838,9 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, newbound = PySet_New(NULL); if (!newbound) goto error; + promote_to_cell = PySet_New(NULL); + if (!promote_to_cell) + goto error; /* Class namespace has no effect on names visible in nested functions, so populate the global and bound @@ -915,7 +921,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, goto error; } if (inline_comp) { - if (!inline_comprehension(ste, entry, scopes, child_free)) { + if (!inline_comprehension(ste, entry, scopes, child_free, promote_to_cell)) { Py_DECREF(child_free); goto error; } @@ -946,7 +952,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, } /* Check if any local variables must be converted to cell variables */ - if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree)) + if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree, promote_to_cell)) goto error; else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree)) goto error; @@ -966,6 +972,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, Py_XDECREF(newbound); Py_XDECREF(newglobal); Py_XDECREF(newfree); + Py_XDECREF(promote_to_cell); if (!success) assert(PyErr_Occurred()); return success; diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 8afa92ef25d376..9863acdade308b 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -317,10 +317,6 @@ Python/instrumentation.c - _PyInstrumentation_MISSING - ##----------------------- ## static types -Modules/_io/bufferedio.c - PyBufferedIOBase_Type - -Modules/_io/iobase.c - PyIOBase_Type - -Modules/_io/iobase.c - PyRawIOBase_Type - -Modules/_io/textio.c - PyTextIOBase_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type - Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type - diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 19c4cd299f0bbb..4270fb3cc56613 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -7,6 +7,7 @@ import abc import ast +import builtins as bltns import collections import contextlib import copy @@ -26,7 +27,9 @@ import traceback import types +from collections.abc import Callable from types import * +from typing import Any, NamedTuple # TODO: # @@ -78,8 +81,13 @@ def __repr__(self): sig_end_marker = '--' +Appender = Callable[[str], None] +Outputter = Callable[[None], str] -_text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output") +class _TextAccumulator(NamedTuple): + text: list[str] + append: Appender + output: Outputter def _text_accumulator(): text = [] @@ -87,10 +95,12 @@ def output(): s = ''.join(text) text.clear() return s - return _text_accumulator_nt(text, text.append, output) + return _TextAccumulator(text, text.append, output) -text_accumulator_nt = collections.namedtuple("text_accumulator", "text append") +class TextAccumulator(NamedTuple): + text: list[str] + append: Appender def text_accumulator(): """ @@ -104,7 +114,7 @@ def text_accumulator(): empties the accumulator. """ text, append, output = _text_accumulator() - return text_accumulator_nt(append, output) + return TextAccumulator(append, output) def warn_or_fail(fail=False, *args, filename=None, line_number=None): @@ -1925,8 +1935,10 @@ def dump(self): # maps strings to Language objects. # "languages" maps the name of the language ("C", "Python"). # "extensions" maps the file extension ("c", "py"). +LangDict = dict[str, Callable[[str], Language]] + languages = { 'C': CLanguage, 'Python': PythonLanguage } -extensions = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } +extensions: LangDict = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } extensions['py'] = PythonLanguage @@ -2558,15 +2570,15 @@ class CConverter(metaclass=CConverterAutoRegister): """ # The C name to use for this variable. - name = None + name: str | None = None # The Python name to use for this variable. - py_name = None + py_name: str | None = None # The C type to use for this variable. # 'type' should be a Python string specifying the type, e.g. "int". # If this is a pointer type, the type string should end with ' *'. - type = None + type: str | None = None # The Python default value for this parameter, as a Python value. # Or the magic value "unspecified" if there is no default. @@ -2577,15 +2589,15 @@ class CConverter(metaclass=CConverterAutoRegister): # If not None, default must be isinstance() of this type. # (You can also specify a tuple of types.) - default_type = None + default_type: bltns.type[Any] | tuple[bltns.type[Any], ...] | None = None # "default" converted into a C value, as a string. # Or None if there is no default. - c_default = None + c_default: str | None = None # "default" converted into a Python value, as a string. # Or None if there is no default. - py_default = None + py_default: str | None = None # The default value used to initialize the C variable when # there is no default, but not specifying a default may @@ -2597,14 +2609,14 @@ class CConverter(metaclass=CConverterAutoRegister): # # This value is specified as a string. # Every non-abstract subclass should supply a valid value. - c_ignored_default = 'NULL' + c_ignored_default: str = 'NULL' # If true, wrap with Py_UNUSED. unused = False # The C converter *function* to be used, if any. # (If this is not None, format_unit must be 'O&'.) - converter = None + converter: str | None = None # Should Argument Clinic add a '&' before the name of # the variable when passing it into the _impl function? @@ -3432,7 +3444,7 @@ class robuffer: pass def str_converter_key(types, encoding, zeroes): return (frozenset(types), bool(encoding), bool(zeroes)) -str_converter_argument_map = {} +str_converter_argument_map: dict[str, str] = {} class str_converter(CConverter): type = 'const char *' diff --git a/Tools/clinic/cpp.py b/Tools/clinic/cpp.py index 77f5f9696a6d84..bc2cc713aac394 100644 --- a/Tools/clinic/cpp.py +++ b/Tools/clinic/cpp.py @@ -1,7 +1,12 @@ import re import sys +from collections.abc import Callable -def negate(condition): + +TokenAndCondition = tuple[str, str] +TokenStack = list[TokenAndCondition] + +def negate(condition: str) -> str: """ Returns a CPP conditional that is the opposite of the conditional passed in. """ @@ -22,17 +27,18 @@ class Monitor: Anyway this implementation seems to work well enough for the CPython sources. """ + is_a_simple_defined: Callable[[str], re.Match[str] | None] is_a_simple_defined = re.compile(r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$').match - def __init__(self, filename=None, *, verbose=False): - self.stack = [] + def __init__(self, filename=None, *, verbose: bool = False): + self.stack: TokenStack = [] self.in_comment = False - self.continuation = None + self.continuation: str | None = None self.line_number = 0 self.filename = filename self.verbose = verbose - def __repr__(self): + def __repr__(self) -> str: return ''.join(( '")) - def status(self): + def status(self) -> str: return str(self.line_number).rjust(4) + ": " + self.condition() - def condition(self): + def condition(self) -> str: """ Returns the current preprocessor state, as a single #if condition. """ @@ -62,15 +68,15 @@ def close(self): if self.stack: self.fail("Ended file while still in a preprocessor conditional block!") - def write(self, s): + def write(self, s: str) -> None: for line in s.split("\n"): self.writeline(line) - def writeline(self, line): + def writeline(self, line: str) -> None: self.line_number += 1 line = line.strip() - def pop_stack(): + def pop_stack() -> TokenAndCondition: if not self.stack: self.fail("#" + token + " without matching #if / #ifdef / #ifndef!") return self.stack.pop() diff --git a/Tools/clinic/mypy.ini b/Tools/clinic/mypy.ini new file mode 100644 index 00000000000000..3c5643e789be37 --- /dev/null +++ b/Tools/clinic/mypy.ini @@ -0,0 +1,11 @@ +[mypy] +# make sure clinic can still be run on Python 3.10 +python_version = 3.10 +pretty = True +enable_error_code = ignore-without-code +disallow_any_generics = True +strict_concatenate = True +warn_redundant_casts = True +warn_unused_ignores = True +warn_unused_configs = True +files = Tools/clinic/ diff --git a/Tools/clinic/requirements-dev.txt b/Tools/clinic/requirements-dev.txt new file mode 100644 index 00000000000000..154934003c31c4 --- /dev/null +++ b/Tools/clinic/requirements-dev.txt @@ -0,0 +1,2 @@ +# Requirements file for external linters and checks we run on Tools/clinic/ in CI +mypy==1.3.0 diff --git a/configure b/configure index c9ea72cf6efacf..7aad4fe89e3cbf 100755 --- a/configure +++ b/configure @@ -883,6 +883,11 @@ CFLAGS_NODIST BASECFLAGS CFLAGS_ALIASING OPT +MERGE_FDATA +LLVM_BOLT +ac_ct_READELF +READELF +PREBOLT_RULE LLVM_PROF_FOUND LLVM_PROFDATA LLVM_PROF_ERR @@ -890,11 +895,6 @@ LLVM_PROF_FILE LLVM_PROF_MERGER PGO_PROF_USE_FLAG PGO_PROF_GEN_FLAG -MERGE_FDATA -LLVM_BOLT -ac_ct_READELF -READELF -PREBOLT_RULE LLVM_AR_FOUND LLVM_AR PROFILE_TASK @@ -3359,7 +3359,7 @@ fi -for ac_prog in python$PACKAGE_VERSION python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3 python +for ac_prog in python$PACKAGE_VERSION python3.12 python3.11 python3.10 python3 python do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -7903,7 +7903,181 @@ fi LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" fi -# Enable bolt flags +# Enable PGO flags. + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-profdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-profdata; 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_PROFDATA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LLVM_PROFDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_PROFDATA="$LLVM_PROFDATA" # 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_PROFDATA="$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_PROFDATA=$ac_cv_path_LLVM_PROFDATA +if test -n "$LLVM_PROFDATA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_PROFDATA" >&5 +$as_echo "$LLVM_PROFDATA" >&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_PROFDATA"; then + ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA + # Extract the first word of "llvm-profdata", so it can be a program name with args. +set dummy llvm-profdata; 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_PROFDATA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_LLVM_PROFDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_PROFDATA="$ac_pt_LLVM_PROFDATA" # 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_PROFDATA="$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_PROFDATA=$ac_cv_path_ac_pt_LLVM_PROFDATA +if test -n "$ac_pt_LLVM_PROFDATA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_PROFDATA" >&5 +$as_echo "$ac_pt_LLVM_PROFDATA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_LLVM_PROFDATA" = x; then + LLVM_PROFDATA="''" + 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_PROFDATA=$ac_pt_LLVM_PROFDATA + fi +else + LLVM_PROFDATA="$ac_cv_path_LLVM_PROFDATA" +fi + + +if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}" +then + LLVM_PROF_FOUND="found" +else + LLVM_PROF_FOUND="not-found" +fi +if test "$ac_sys_system" = "Darwin" -a "${LLVM_PROF_FOUND}" = "not-found" +then + found_llvm_profdata=`/usr/bin/xcrun -find llvm-profdata 2>/dev/null` + if test -n "${found_llvm_profdata}" + then + # llvm-profdata isn't directly in $PATH in some cases. + # https://apple.stackexchange.com/questions/197053/ + LLVM_PROFDATA='/usr/bin/xcrun llvm-profdata' + LLVM_PROF_FOUND=found + { $as_echo "$as_me:${as_lineno-$LINENO}: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&5 +$as_echo "$as_me: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&6;} + fi +fi +LLVM_PROF_ERR=no +case $CC in + *clang*) + # Any changes made here should be reflected in the GCC+Darwin case below + PGO_PROF_GEN_FLAG="-fprofile-instr-generate" + PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd" + LLVM_PROF_MERGER="${LLVM_PROFDATA} merge -output=code.profclangd *.profclangr" + LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\"" + if test $LLVM_PROF_FOUND = not-found + then + LLVM_PROF_ERR=yes + if test "${REQUIRE_PGO}" = "yes" + then + as_fn_error $? "llvm-profdata is required for a --enable-optimizations build but could not be found." "$LINENO" 5 + fi + fi + ;; + *gcc*) + case $ac_sys_system in + Darwin*) + PGO_PROF_GEN_FLAG="-fprofile-instr-generate" + PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd" + LLVM_PROF_MERGER="${LLVM_PROFDATA} merge -output=code.profclangd *.profclangr" + LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\"" + if test "${LLVM_PROF_FOUND}" = "not-found" + then + LLVM_PROF_ERR=yes + if test "${REQUIRE_PGO}" = "yes" + then + as_fn_error $? "llvm-profdata is required for a --enable-optimizations build but could not be found." "$LINENO" 5 + fi + fi + ;; + *) + PGO_PROF_GEN_FLAG="-fprofile-generate" + PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction" + LLVM_PROF_MERGER="true" + LLVM_PROF_FILE="" + ;; + esac + ;; + *icc*) + PGO_PROF_GEN_FLAG="-prof-gen" + PGO_PROF_USE_FLAG="-prof-use" + LLVM_PROF_MERGER="true" + LLVM_PROF_FILE="" + ;; +esac + +# BOLT optimization. Always configured after PGO since it always runs after PGO. Py_BOLT='false' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-bolt" >&5 $as_echo_n "checking for --enable-bolt... " >&6; } @@ -8300,180 +8474,6 @@ $as_echo "\"Found merge-fdata\"" >&6; } fi fi -# Enable PGO flags. - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}llvm-profdata", so it can be a program name with args. -set dummy ${ac_tool_prefix}llvm-profdata; 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_PROFDATA+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $LLVM_PROFDATA in - [\\/]* | ?:[\\/]*) - ac_cv_path_LLVM_PROFDATA="$LLVM_PROFDATA" # 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_PROFDATA="$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_PROFDATA=$ac_cv_path_LLVM_PROFDATA -if test -n "$LLVM_PROFDATA"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_PROFDATA" >&5 -$as_echo "$LLVM_PROFDATA" >&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_PROFDATA"; then - ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA - # Extract the first word of "llvm-profdata", so it can be a program name with args. -set dummy llvm-profdata; 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_PROFDATA+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_LLVM_PROFDATA in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_LLVM_PROFDATA="$ac_pt_LLVM_PROFDATA" # 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_PROFDATA="$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_PROFDATA=$ac_cv_path_ac_pt_LLVM_PROFDATA -if test -n "$ac_pt_LLVM_PROFDATA"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_PROFDATA" >&5 -$as_echo "$ac_pt_LLVM_PROFDATA" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_LLVM_PROFDATA" = x; then - LLVM_PROFDATA="''" - 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_PROFDATA=$ac_pt_LLVM_PROFDATA - fi -else - LLVM_PROFDATA="$ac_cv_path_LLVM_PROFDATA" -fi - - -if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}" -then - LLVM_PROF_FOUND="found" -else - LLVM_PROF_FOUND="not-found" -fi -if test "$ac_sys_system" = "Darwin" -a "${LLVM_PROF_FOUND}" = "not-found" -then - found_llvm_profdata=`/usr/bin/xcrun -find llvm-profdata 2>/dev/null` - if test -n "${found_llvm_profdata}" - then - # llvm-profdata isn't directly in $PATH in some cases. - # https://apple.stackexchange.com/questions/197053/ - LLVM_PROFDATA='/usr/bin/xcrun llvm-profdata' - LLVM_PROF_FOUND=found - { $as_echo "$as_me:${as_lineno-$LINENO}: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&5 -$as_echo "$as_me: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&6;} - fi -fi -LLVM_PROF_ERR=no -case $CC in - *clang*) - # Any changes made here should be reflected in the GCC+Darwin case below - PGO_PROF_GEN_FLAG="-fprofile-instr-generate" - PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd" - LLVM_PROF_MERGER="${LLVM_PROFDATA} merge -output=code.profclangd *.profclangr" - LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\"" - if test $LLVM_PROF_FOUND = not-found - then - LLVM_PROF_ERR=yes - if test "${REQUIRE_PGO}" = "yes" - then - as_fn_error $? "llvm-profdata is required for a --enable-optimizations build but could not be found." "$LINENO" 5 - fi - fi - ;; - *gcc*) - case $ac_sys_system in - Darwin*) - PGO_PROF_GEN_FLAG="-fprofile-instr-generate" - PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd" - LLVM_PROF_MERGER="${LLVM_PROFDATA} merge -output=code.profclangd *.profclangr" - LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\"" - if test "${LLVM_PROF_FOUND}" = "not-found" - then - LLVM_PROF_ERR=yes - if test "${REQUIRE_PGO}" = "yes" - then - as_fn_error $? "llvm-profdata is required for a --enable-optimizations build but could not be found." "$LINENO" 5 - fi - fi - ;; - *) - PGO_PROF_GEN_FLAG="-fprofile-generate" - PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction" - LLVM_PROF_MERGER="true" - LLVM_PROF_FILE="" - ;; - esac - ;; - *icc*) - PGO_PROF_GEN_FLAG="-prof-gen" - PGO_PROF_USE_FLAG="-prof-use" - LLVM_PROF_MERGER="true" - LLVM_PROF_FILE="" - ;; -esac - # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be # merged with this chunk of code? diff --git a/configure.ac b/configure.ac index 10672bd3761da8..115998e0753b26 100644 --- a/configure.ac +++ b/configure.ac @@ -202,7 +202,7 @@ AC_SUBST([FREEZE_MODULE_DEPS]) AC_SUBST([PYTHON_FOR_BUILD_DEPS]) AC_CHECK_PROGS([PYTHON_FOR_REGEN], - [python$PACKAGE_VERSION python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3 python], + [python$PACKAGE_VERSION python3.12 python3.11 python3.10 python3 python], [python3]) AC_SUBST(PYTHON_FOR_REGEN) @@ -1929,68 +1929,6 @@ 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" - - AC_SUBST(READELF) - AC_CHECK_TOOLS(READELF, [readelf], "notfound") - if test "$READELF" == "notfound" - then - AC_MSG_ERROR([readelf is required for a --enable-bolt build but could not be found.]) - fi - - # -fno-reorder-blocks-and-partition is required for bolt to work. - # Possibly GCC only. - AX_CHECK_COMPILE_FLAG([-fno-reorder-blocks-and-partition],[ - CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" - ]) - - # These flags are required for bolt to work: - 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" - 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) @@ -2067,6 +2005,68 @@ case $CC in ;; esac +# BOLT optimization. Always configured after PGO since it always runs after PGO. +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" + + AC_SUBST(READELF) + AC_CHECK_TOOLS(READELF, [readelf], "notfound") + if test "$READELF" == "notfound" + then + AC_MSG_ERROR([readelf is required for a --enable-bolt build but could not be found.]) + fi + + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + AX_CHECK_COMPILE_FLAG([-fno-reorder-blocks-and-partition],[ + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + ]) + + # These flags are required for bolt to work: + 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" + 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 + # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be # merged with this chunk of code?