diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 5ee783b7fae950f..ce65bc961a98a68 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -26,7 +26,7 @@ introduced with RFC 2965. .. note:: The various named parameters found in :mailheader:`Set-Cookie` and - :mailheader:`Set-Cookie2` headers (eg. ``domain`` and ``expires``) are + :mailheader:`Set-Cookie2` headers (for example, ``domain`` and ``expires``) are conventionally referred to as :dfn:`attributes`. To distinguish them from Python attributes, the documentation for this module uses the term :dfn:`cookie-attribute` instead. @@ -85,7 +85,7 @@ The following classes are provided: Constructor arguments should be passed as keyword arguments only. *blocked_domains* is a sequence of domain names that we never accept cookies - from, nor return cookies to. *allowed_domains* if not :const:`None`, this is a + from, nor return cookies to. *allowed_domains* if not ``None``, this is a sequence of the only domains for which we accept and return cookies. *secure_protocols* is a sequence of protocols for which secure cookies can be added to. By default *https* and *wss* (secure websocket) are considered @@ -93,12 +93,12 @@ The following classes are provided: :class:`CookiePolicy` and :class:`DefaultCookiePolicy` objects. :class:`DefaultCookiePolicy` implements the standard accept / reject rules for - Netscape and :rfc:`2965` cookies. By default, :rfc:`2109` cookies (ie. cookies + Netscape and :rfc:`2965` cookies. By default, :rfc:`2109` cookies (that is, cookies received in a :mailheader:`Set-Cookie` header with a version cookie-attribute of 1) are treated according to the RFC 2965 rules. However, if RFC 2965 handling is turned off or :attr:`rfc2109_as_netscape` is ``True``, RFC 2109 cookies are 'downgraded' by the :class:`CookieJar` instance to Netscape cookies, by - setting the :attr:`version` attribute of the :class:`Cookie` instance to 0. + setting the :attr:`~Cookie.version` attribute of the :class:`Cookie` instance to 0. :class:`DefaultCookiePolicy` also provides some parameters to allow some fine-tuning of policy. @@ -107,7 +107,7 @@ The following classes are provided: This class represents Netscape, :rfc:`2109` and :rfc:`2965` cookies. It is not expected that users of :mod:`!http.cookiejar` construct their own :class:`Cookie` - instances. Instead, if necessary, call :meth:`make_cookies` on a + instances. Instead, if necessary, call :meth:`~CookieJar.make_cookies` on a :class:`CookieJar` instance. @@ -141,7 +141,7 @@ The following classes are provided: .. _cookie-jar-objects: -CookieJar and FileCookieJar Objects +CookieJar and FileCookieJar objects ----------------------------------- :class:`CookieJar` objects support the :term:`iterator` protocol for iterating over @@ -154,20 +154,27 @@ contained :class:`Cookie` objects. Add correct :mailheader:`Cookie` header to *request*. - If policy allows (ie. the :attr:`rfc2965` and :attr:`hide_cookie2` attributes of + If policy allows (that is, the :attr:`~CookiePolicy.rfc2965` and + :attr:`~CookiePolicy.hide_cookie2` attributes of the :class:`CookieJar`'s :class:`CookiePolicy` instance are true and false respectively), the :mailheader:`Cookie2` header is also added when appropriate. The *request* object (usually a :class:`urllib.request.Request` instance) - must support the methods :meth:`get_full_url`, :meth:`has_header`, - :meth:`get_header`, :meth:`header_items`, :meth:`add_unredirected_header` - and the attributes :attr:`host`, :attr:`!type`, :attr:`unverifiable` - and :attr:`origin_req_host` as documented by :mod:`urllib.request`. + must support the methods :meth:`~urllib.request.Request.get_full_url`, + :meth:`~urllib.request.Request.has_header`, + :meth:`~urllib.request.Request.get_header`, + :meth:`~urllib.request.Request.header_items`, + :meth:`~urllib.request.Request.add_unredirected_header` + and the attributes :attr:`~urllib.request.Request.host`, + :attr:`~urllib.request.Request.type`, :attr:`~urllib.request.Request.unverifiable` + and :attr:`~urllib.request.Request.origin_req_host` as documented by + :mod:`urllib.request`. .. versionchanged:: 3.3 - *request* object needs :attr:`origin_req_host` attribute. Dependency on a - deprecated method :meth:`get_origin_req_host` has been removed. + *request* object needs :attr:`~urllib.request.Request.origin_req_host` + attribute. Dependency on a deprecated method + :meth:`!get_origin_req_host` has been removed. .. method:: CookieJar.extract_cookies(response, request) @@ -180,20 +187,24 @@ contained :class:`Cookie` objects. as appropriate (subject to the :meth:`CookiePolicy.set_ok` method's approval). The *response* object (usually the result of a call to - :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info` - method, which returns an :class:`email.message.Message` instance. + :meth:`urllib.request.urlopen`, or similar) should support an + :meth:`~http.client.HTTPResponse.info` method, which returns an + :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) - must support the method :meth:`get_full_url` and the attributes - :attr:`host`, :attr:`unverifiable` and :attr:`origin_req_host`, + must support the method :meth:`~urllib.request.Request.get_full_url` and + the attributes :attr:`~urllib.request.Request.host`, + :attr:`~urllib.request.Request.unverifiable` + and :attr:`~urllib.request.Request.origin_req_host`, as documented by :mod:`urllib.request`. The request is used to set default values for cookie-attributes as well as for checking that the cookie is allowed to be set. .. versionchanged:: 3.3 - *request* object needs :attr:`origin_req_host` attribute. Dependency on a - deprecated method :meth:`get_origin_req_host` has been removed. + *request* object needs :attr:`~urllib.request.Request.origin_req_host` + attribute. Dependency on a deprecated method + :meth:`!get_origin_req_host` has been removed. .. method:: CookieJar.set_policy(policy) @@ -236,13 +247,13 @@ contained :class:`Cookie` objects. Discard all session cookies. - Discards all contained cookies that have a true :attr:`discard` attribute + Discards all contained cookies that have a true :attr:`~Cookie.discard` attribute (usually because they had either no ``max-age`` or ``expires`` cookie-attribute, or an explicit ``discard`` cookie-attribute). For interactive browsers, the end of a session usually corresponds to closing the browser window. - Note that the :meth:`save` method won't save session cookies anyway, unless you - ask otherwise by passing a true *ignore_discard* argument. + Note that the :meth:`~FileCookieJar.save` method won't save session cookies + anyway, unless you ask otherwise by passing a true *ignore_discard* argument. :class:`FileCookieJar` implements the following additional methods: @@ -255,8 +266,9 @@ contained :class:`Cookie` objects. method unimplemented. *filename* is the name of file in which to save cookies. If *filename* is not - specified, :attr:`self.filename` is used (whose default is the value passed to - the constructor, if any); if :attr:`self.filename` is :const:`None`, + specified, :attr:`self.filename ` is used (whose + default is the value passed to the constructor, if any); if + :attr:`self.filename ` is ``None``, :exc:`ValueError` is raised. *ignore_discard*: save even cookies set to be discarded. *ignore_expires*: save @@ -349,7 +361,7 @@ writing. .. _cookie-policy-objects: -CookiePolicy Objects +CookiePolicy objects -------------------- Objects implementing the :class:`CookiePolicy` interface have the following @@ -433,7 +445,7 @@ setting and receiving any and all cookies (this is unlikely to be useful). .. _default-cookie-policy-objects: -DefaultCookiePolicy Objects +DefaultCookiePolicy objects --------------------------- Implements the standard rules for accepting and returning cookies. @@ -463,10 +475,10 @@ blocking some benign cookies). A domain blocklist and allowlist is provided (both off by default). Only domains not in the blocklist and present in the allowlist (if the allowlist is active) participate in cookie setting and returning. Use the *blocked_domains* -constructor argument, and :meth:`blocked_domains` and -:meth:`set_blocked_domains` methods (and the corresponding argument and methods -for *allowed_domains*). If you set an allowlist, you can turn it off again by -setting it to :const:`None`. +constructor argument, and :meth:`~DefaultCookiePolicy.blocked_domains` and +:meth:`~DefaultCookiePolicy.set_blocked_domains` methods (and the corresponding +argument and methods for *allowed_domains*). If you set an allowlist, you can +turn it off again by setting it to ``None``. Domains in block or allow lists that do not start with a dot must equal the cookie domain to be matched. For example, ``"example.com"`` matches a blocklist @@ -498,12 +510,12 @@ and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not. .. method:: DefaultCookiePolicy.allowed_domains() - Return :const:`None`, or the sequence of allowed domains (as a tuple). + Return ``None``, or the sequence of allowed domains (as a tuple). .. method:: DefaultCookiePolicy.set_allowed_domains(allowed_domains) - Set the sequence of allowed domains, or :const:`None`. + Set the sequence of allowed domains, or ``None``. .. method:: DefaultCookiePolicy.is_not_allowed(domain) @@ -519,9 +531,9 @@ all be assigned to. .. attribute:: DefaultCookiePolicy.rfc2109_as_netscape If true, request that the :class:`CookieJar` instance downgrade :rfc:`2109` cookies - (ie. cookies received in a :mailheader:`Set-Cookie` header with a version + (that is, cookies received in a :mailheader:`Set-Cookie` header with a version cookie-attribute of 1) to Netscape cookies by setting the version attribute of - the :class:`Cookie` instance to 0. The default value is :const:`None`, in which + the :class:`Cookie` instance to 0. The default value is ``None``, in which case RFC 2109 cookies are downgraded if and only if :rfc:`2965` handling is turned off. Therefore, RFC 2109 cookies are downgraded by default. @@ -574,7 +586,7 @@ both flags are set). .. attribute:: DefaultCookiePolicy.DomainStrictNoDots - When setting cookies, the 'host prefix' must not contain a dot (eg. + When setting cookies, the 'host prefix' must not contain a dot (for example, ``www.foo.bar.com`` can't set a cookie for ``.bar.com``, because ``www.foo`` contains a dot). @@ -582,7 +594,7 @@ both flags are set). .. attribute:: DefaultCookiePolicy.DomainStrictNonDomain Cookies that did not explicitly specify a ``domain`` cookie-attribute can only - be returned to a domain equal to the domain that set the cookie (eg. + be returned to a domain equal to the domain that set the cookie (for example, ``spam.example.com`` won't be returned cookies from ``example.com`` that had no ``domain`` cookie-attribute). @@ -597,7 +609,7 @@ combinations of the above flags: .. attribute:: DefaultCookiePolicy.DomainLiberal - Equivalent to 0 (ie. all of the above Netscape domain strictness flags switched + Equivalent to 0 (that is, all of the above Netscape domain strictness flags switched off). @@ -606,7 +618,7 @@ combinations of the above flags: Equivalent to ``DomainStrictNoDots|DomainStrictNonDomain``. -Cookie Objects +Cookie objects -------------- :class:`Cookie` instances have Python attributes roughly corresponding to the @@ -624,7 +636,7 @@ internal consistency, so you should know what you're doing if you do that. .. attribute:: Cookie.version - Integer or :const:`None`. Netscape cookies have :attr:`version` 0. :rfc:`2965` and + Integer or ``None``. Netscape cookies have :attr:`version` 0. :rfc:`2965` and :rfc:`2109` cookies have a ``version`` cookie-attribute of 1. However, note that :mod:`!http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which case :attr:`version` is 0. @@ -637,13 +649,13 @@ internal consistency, so you should know what you're doing if you do that. .. attribute:: Cookie.value - Cookie value (a string), or :const:`None`. + Cookie value (a string), or ``None``. .. attribute:: Cookie.port - String representing a port or a set of ports (eg. '80', or '80,8080'), or - :const:`None`. + String representing a port or a set of ports (for example, '80', or '80,8080'), or + ``None``. .. attribute:: Cookie.domain @@ -653,7 +665,7 @@ internal consistency, so you should know what you're doing if you do that. .. attribute:: Cookie.path - Cookie path (a string, eg. ``'/acme/rocket_launchers'``). + Cookie path (a string, for example, ``'/acme/rocket_launchers'``). .. attribute:: Cookie.secure @@ -663,7 +675,7 @@ internal consistency, so you should know what you're doing if you do that. .. attribute:: Cookie.expires - Integer expiry date in seconds since epoch, or :const:`None`. See also the + Integer expiry date in seconds since epoch, or ``None``. See also the :meth:`is_expired` method. @@ -675,18 +687,18 @@ internal consistency, so you should know what you're doing if you do that. .. attribute:: Cookie.comment String comment from the server explaining the function of this cookie, or - :const:`None`. + ``None``. .. attribute:: Cookie.comment_url URL linking to a comment from the server explaining the function of this cookie, - or :const:`None`. + or ``None``. .. attribute:: Cookie.rfc2109 - ``True`` if this cookie was received as an :rfc:`2109` cookie (ie. the cookie + ``True`` if this cookie was received as an :rfc:`2109` cookie (that is, the cookie arrived in a :mailheader:`Set-Cookie` header, and the value of the Version cookie-attribute in that header was 1). This attribute is provided because :mod:`!http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore index 2255c745c003838..7b956f0ef0eb2c4 100644 --- a/Doc/tools/.nitignore +++ b/Doc/tools/.nitignore @@ -9,7 +9,6 @@ Doc/library/ast.rst Doc/library/asyncio-extending.rst Doc/library/email.charset.rst Doc/library/email.parser.rst -Doc/library/http.cookiejar.rst Doc/library/http.server.rst Doc/library/importlib.rst Doc/library/logging.config.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index a8adeb566aaf5d1..221629a6230270d 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -229,8 +229,9 @@ import_name[stmt_ty]: # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS import_from[stmt_ty]: + | invalid_import_from | lazy="lazy"? 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets { - _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), lazy, EXTRA) } + _PyPegen_checked_from_import(p, a, b, c, lazy, EXTRA) } | lazy="lazy"? 'from' a=('.' | '...')+ 'import' b=import_from_targets { _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), lazy ? 1 : 0, EXTRA) } import_from_targets[asdl_alias_seq*]: @@ -1445,6 +1446,11 @@ invalid_import_from_as_name: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use %s as import target", _PyPegen_get_expr_name(a)) } +invalid_import_from: + | 'from' ('.' | '...')* dotted_name a="lazy" 'import' import_from_targets { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, + "use 'lazy from ... ' instead of 'from ... lazy import'") } + invalid_import_from_targets: | import_from_as_names ',' NEWLINE { RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") } diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index e436aa6bf12cb27..c1f9d71e40077c1 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -123,9 +123,11 @@ extern void _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); extern PyObject* _PyErr_NoMemory(PyThreadState *tstate); -extern int _PyErr_EmitSyntaxWarning(PyObject *msg, PyObject *filename, int lineno, int col_offset, - int end_lineno, int end_col_offset, - PyObject *module); +// Export for test_peg_generator +PyAPI_FUNC(int) _PyErr_EmitSyntaxWarning(PyObject *msg, PyObject *filename, + int lineno, int col_offset, + int end_lineno, int end_col_offset, + PyObject *module); extern void _PyErr_RaiseSyntaxError(PyObject *msg, PyObject *filename, int lineno, int col_offset, int end_lineno, int end_col_offset); diff --git a/Lib/_pyrepl/render.py b/Lib/_pyrepl/render.py index b821f35d850825e..b835778e366c539 100644 --- a/Lib/_pyrepl/render.py +++ b/Lib/_pyrepl/render.py @@ -4,8 +4,10 @@ from dataclasses import dataclass, field from typing import Literal, Protocol, Self -from .utils import ANSI_ESCAPE_SEQUENCE, THEME, StyleRef, str_width +from _colorize import ANSIColors + from .types import CursorXY +from .utils import ANSI_ESCAPE_SEQUENCE, THEME, StyleRef, str_width type RenderStyle = StyleRef | str | None type LineUpdateKind = Literal[ @@ -55,7 +57,7 @@ def _style_escape(style: StyleRef) -> str: def _update_terminal_state(state: str, escape: str) -> str: - if escape in {"\x1b[0m", "\x1b[m"}: + if escape in {ANSIColors.RESET, "\x1b[m"}: return "" return state + escape @@ -344,14 +346,14 @@ def render_cells( target_escape += visual_style if target_escape != active_escape: if active_escape: - rendered.append("\x1b[0m") + rendered.append(ANSIColors.RESET) if target_escape: rendered.append(target_escape) active_escape = target_escape rendered.append(cell.text) if active_escape: - rendered.append("\x1b[0m") + rendered.append(ANSIColors.RESET) return "".join(rendered) diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py index 9a4f8e0c623abfa..8edd1c36a7232d7 100644 --- a/Lib/_pyrepl/unix_console.py +++ b/Lib/_pyrepl/unix_console.py @@ -36,6 +36,8 @@ from fcntl import ioctl from typing import TYPE_CHECKING, overload +from _colorize import ANSIColors + from . import terminfo from .console import Console, Event from .fancy_termios import tcgetattr, tcsetattr, TermState @@ -517,6 +519,7 @@ def restore(self) -> None: Restore the console to the default state """ trace("unix.restore") + self.__write(ANSIColors.RESET) self.__disable_bracketed_paste() self.__maybe_write_code(self._rmkx) self.flushoutput() @@ -654,6 +657,7 @@ def finish(self): while y >= 0 and not rendered_lines[y].text: y -= 1 self.__move(0, min(y, self.height + self.__offset - 1)) + self.__write(ANSIColors.RESET) self.__write("\n\r") self.flushoutput() diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py index c1f9a19545d35fd..3768a22ad16f7bb 100644 --- a/Lib/_pyrepl/windows_console.py +++ b/Lib/_pyrepl/windows_console.py @@ -39,6 +39,9 @@ ) from ctypes import Structure, POINTER, Union from typing import TYPE_CHECKING + +from _colorize import ANSIColors + from .console import Event, Console from .render import ( EMPTY_RENDER_LINE, @@ -480,6 +483,7 @@ def prepare(self) -> None: def restore(self) -> None: trace("windows.restore") if self.__vt_support: + self.__write(ANSIColors.RESET) # Recover to original mode before running REPL self._disable_bracketed_paste() if not SetConsoleMode(InHandle, self.__original_input_mode): @@ -647,6 +651,7 @@ def finish(self) -> None: while y >= 0 and not rendered_lines[y].text: y -= 1 self._move_relative(0, min(y, self.height + self.__offset - 1)) + self.__write(ANSIColors.RESET) self.__write("\r\n") def flushoutput(self) -> None: diff --git a/Lib/html/parser.py b/Lib/html/parser.py index 80fb8c3f929f6b6..38ddf9ef442d368 100644 --- a/Lib/html/parser.py +++ b/Lib/html/parser.py @@ -387,9 +387,11 @@ def parse_html_declaration(self, i): def parse_comment(self, i, report=True): rawdata = self.rawdata assert rawdata.startswith('" or "--!>" close. + match = commentabruptclose.match(rawdata, i+4) if not match: - match = commentabruptclose.match(rawdata, i+4) + match = commentclose.search(rawdata, i+4) if not match: return -1 if report: diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index e4eff1ea17a670b..6b7624f11505d92 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -116,6 +116,11 @@ def _run_check(self, source, expected_events, *, collector=None, convert_charrefs=False): if collector is None: collector = self.get_collector(convert_charrefs=convert_charrefs) + if isinstance(source, str): + # Also feed the whole string at once, not just character by + # character (below), to exercise different input buffering. + self._run_check([source], expected_events, + convert_charrefs=convert_charrefs) parser = collector for s in source: parser.feed(s) @@ -593,6 +598,9 @@ def test_comments(self): ' -->' '' '' + # abruptly closed empty comment must not swallow later text + 'x-->' + 'y-->' ) expected = [('comment', " I'm a valid comment "), ('comment', 'me too!'), @@ -613,6 +621,8 @@ def test_comments(self): ('comment', ' '), ('comment', ''), + ('comment', ''), ('data', 'y-->'), ] self._run_check(html, expected) diff --git a/Lib/test/test_pyrepl/test_unix_console.py b/Lib/test/test_pyrepl/test_unix_console.py index 71b2e17e3341510..2fc8398923cbf38 100644 --- a/Lib/test/test_pyrepl/test_unix_console.py +++ b/Lib/test/test_pyrepl/test_unix_console.py @@ -6,6 +6,7 @@ import threading import unittest from functools import partial +from _colorize import ANSIColors from test.support import force_color, os_helper, force_not_colorized_test_class from test.support import threading_helper @@ -147,6 +148,24 @@ def test_no_newline(self, _os_write): self.assertNotIn(call(ANY, b'\n'), _os_write.mock_calls) con.restore() + def test_reset_on_finish(self, _os_write): + # gh-152068: finish() must emit the ANSI reset sequence so any + # active color does not leak past the prompt. + code = "1" + events = code_to_events(code) + _, con = handle_events_unix_console(events) + con.finish() + _os_write.assert_any_call(ANY, ANSIColors.RESET.encode(con.encoding)) + con.restore() + + def test_reset_on_restore(self, _os_write): + # gh-152068: restore() must emit the ANSI reset sequence. + code = "1" + events = code_to_events(code) + _, con = handle_events_unix_console(events) + con.restore() + _os_write.assert_any_call(ANY, ANSIColors.RESET.encode(con.encoding)) + def test_newline(self, _os_write): code = "\n" events = code_to_events(code) diff --git a/Lib/test/test_pyrepl/test_windows_console.py b/Lib/test/test_pyrepl/test_windows_console.py index 2b6075b3274c05c..32c4255aa6b1904 100644 --- a/Lib/test/test_pyrepl/test_windows_console.py +++ b/Lib/test/test_pyrepl/test_windows_console.py @@ -6,6 +6,7 @@ import itertools +from _colorize import ANSIColors from functools import partial from test.support import force_not_colorized_test_class from typing import Iterable @@ -380,6 +381,28 @@ def test_multiline_ctrl_z(self): self.assertEqual(reader.cxy, (2, 3)) con.restore() + def test_reset_on_finish(self): + # gh-152068: finish() must emit the ANSI reset sequence so any + # active color does not leak past the prompt. + code = "1" + events = code_to_events(code) + _, con = self.handle_events(events) + con.finish() + con.out.write.assert_any_call(ANSIColors.RESET.encode(con.encoding)) + con.restore() + + def test_reset_on_restore(self): + # gh-152068: restore() must emit the ANSI reset sequence when VT + # support is enabled. + code = "1" + events = code_to_events(code) + _, con = self.handle_events(events) + con._WindowsConsole__vt_support = True + con._WindowsConsole__original_input_mode = 0 + with patch.object(wc, "SetConsoleMode", return_value=1): + con.restore() + con.out.write.assert_any_call(ANSIColors.RESET.encode(con.encoding)) + @patch.object(WindowsConsole, '__init__', _mock_console_init) class WindowsConsoleGetEventTests(TestCase): diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 04e60c74ce1bea6..013917614178fde 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2872,6 +2872,14 @@ def check_warning(self, code, errtext, filename="", mode="exec"): with self.assertWarnsRegex(SyntaxWarning, errtext): compile(code, filename, mode) + def check_no_warning(self, code, filename="", mode="exec"): + """Check that compiling code does not raise any warnings.""" + import warnings + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + compile(code, filename, mode) + self.assertEqual(caught, []) + def test_return_in_finally(self): source = textwrap.dedent(""" def f(): @@ -2942,6 +2950,75 @@ def test_break_and_continue_in_finally(self): """) self.check_warning(source, f"'{kw}' in a 'finally' block") + def test_from_lazy_imports(self): + # gh-150459 + self.check_warning( + "from . lazy import x", + "did you mean 'lazy from . import'?", + ) + self.check_warning( + "from . lazy import x as y", + "did you mean 'lazy from . import'?", + ) + self.check_warning( + "from . lazy import *", + "did you mean 'lazy from . import'?", + ) + self.check_warning( + "from .. lazy import x", + "did you mean 'lazy from .. import'?", + ) + self.check_warning( + "from ... lazy import x", + "did you mean 'lazy from ... import'?", + ) + self.check_warning( + "from .... lazy import x", + "did you mean 'lazy from .... import'?", + ) + self.check_warning( + "from . \\\n lazy import x", + "did you mean 'lazy from . import'?", + ) + self.check_warning( + "from .\\\nlazy import x", + "did you mean 'lazy from . import'?", + ) + self.check_warning( + "from .\tlazy import x", + "did you mean 'lazy from . import'?", + ) + + def test_not_from_lazy_imports(self): + self.check_no_warning("from .lazy import x") + self.check_no_warning("from .lazy import *") + self.check_no_warning("from ..lazy import x") + self.check_no_warning("from ...lazy import x") + self.check_no_warning("from .lazy.sub import x") + self.check_no_warning("from ..lazy.sub import x") + self.check_no_warning("from ...lazy.sub import x") + self.check_no_warning("from . lazier import x") + self.check_no_warning("from . lazy_module import x") + self.check_no_warning("from . lazy.sub import x") + self.check_no_warning("from . sub.lazy import x") + self.check_no_warning("from lazy import x") + self.check_no_warning("from lazy.sub import x") + self.check_no_warning("lazy from . lazy import x") + self.check_no_warning("from . import lazy") + + def test_from_lazy_imports_as_error(self): + import warnings + with warnings.catch_warnings(): + warnings.simplefilter("error", SyntaxWarning) + with self.assertRaisesRegex( + SyntaxError, + re.escape("did you mean 'lazy from . import'?"), + ) as cm: + compile("from . lazy import x", "", "exec") + self.assertEqual(cm.exception.lineno, 1) + self.assertEqual(cm.exception.offset, 8) + self.assertEqual(cm.exception.end_offset, 12) + class SyntaxErrorTestCase(unittest.TestCase): @@ -3662,6 +3739,22 @@ def inner(): lazy from collections import deque """, "lazy from ... import not allowed inside functions") + self._check_error("""\ +from os lazy import path +""", "use 'lazy from ... ' instead of 'from ... lazy import'") + self._check_error("""\ +from os.path lazy import join +""", "use 'lazy from ... ' instead of 'from ... lazy import'") + self._check_error("""\ +from .mod lazy import join +""", "use 'lazy from ... ' instead of 'from ... lazy import'") + self._check_error("""\ +from ..mod lazy import join +""", "use 'lazy from ... ' instead of 'from ... lazy import'") + self._check_error("""\ +from ...mod lazy import join +""", "use 'lazy from ... ' instead of 'from ... lazy import'") + def test_lazy_import_valid_cases(self): """Test that lazy imports work at module level.""" # These should compile without errors diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-03-21-14-28.gh-issue-150459.qpsCEl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-03-21-14-28.gh-issue-150459.qpsCEl.rst new file mode 100644 index 000000000000000..a3e3e38ddcd1f43 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-03-21-14-28.gh-issue-150459.qpsCEl.rst @@ -0,0 +1,3 @@ +Fix :exc:`SyntaxError` error message for ``from x lazy import y``. +Raise :exc:`SyntaxWarning` on ``from . lazy import x`` +(with whitespace between the dots and a module named ``lazy``). diff --git a/Misc/NEWS.d/next/Library/2026-07-02-19-21-15.gh-issue-152068.ThsmJU.rst b/Misc/NEWS.d/next/Library/2026-07-02-19-21-15.gh-issue-152068.ThsmJU.rst new file mode 100644 index 000000000000000..9ec8413b4ac424c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-02-19-21-15.gh-issue-152068.ThsmJU.rst @@ -0,0 +1 @@ +Fixes a bug when a line was split (particularly on macOS Terminal.app) in the middle of a colorized keyword, causing the ANSI Color Reset sequence (ESC0m) to not be properly printed, causing the output to be colored when it shouldn't diff --git a/Misc/NEWS.d/next/Library/2026-07-04-13-00-00.gh-issue-135661.CIkADG.rst b/Misc/NEWS.d/next/Library/2026-07-04-13-00-00.gh-issue-135661.CIkADG.rst new file mode 100644 index 000000000000000..26a912a6f3a1949 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-04-13-00-00.gh-issue-135661.CIkADG.rst @@ -0,0 +1,3 @@ +Fix :class:`html.parser.HTMLParser`: an abruptly closed empty comment +(```` or ````) no longer extends up to a later ``-->`` in the same +:meth:`~html.parser.HTMLParser.feed` call. diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index 381c173589904ba..809f3c0a7b270e8 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -2,6 +2,7 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_runtime.h" // _PyRuntime #include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal() +#include "pycore_pyerrors.h" // _PyErr_EmitSyntaxWarning() #include "pegen.h" #include "string_parser.h" // _PyPegen_decode_string() @@ -2007,11 +2008,64 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings, col_offset, end_lineno, end_col_offset, arena); } +static int +_warn_relative_import_of_lazy(Parser *p, asdl_seq *dots, expr_ty module) +{ + // Warn about `from . lazy import x`: the whitespace between the dots and + // the module name is insignificant, so this is parsed exactly like + // `from .lazy import x` (an import of the relative module "lazy"), but it + // is most likely a transposition of `lazy from . import x` (PEP 810). + if (p->call_invalid_rules) { + return 0; + } + + // Only fire if there is whitespace between the last dot and the name, + // i.e. not for the common `from .lazy import x` spelling. + Token *last_dot = asdl_seq_GET_UNTYPED(dots, asdl_seq_LEN(dots) - 1); + if ( + last_dot->end_lineno == module->lineno + && last_dot->end_col_offset == module->col_offset + ) { + return 0; + } + + int count = _PyPegen_seq_count_dots(dots); + char *buf = PyMem_RawMalloc(count + 1); + if (buf == NULL) { + PyErr_NoMemory(); + return -1; + } + memset(buf, '.', count); + buf[count] = '\0'; + + PyObject *msg = PyUnicode_FromFormat( + "'from %s lazy import' is the same as 'from %slazy import'; " + "did you mean 'lazy from %s import'?", + buf, buf, buf); + PyMem_RawFree(buf); + if (msg == NULL) { + return -1; + } + + int res = _PyErr_EmitSyntaxWarning(msg, + p->tok->filename, + module->lineno, + module->col_offset + 1, + module->end_lineno, + module->end_col_offset + 1, + p->tok->module); + Py_DECREF(msg); + return res; +} + stmt_ty -_PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq * names, - int level, expr_ty lazy_token, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) { +_PyPegen_checked_from_import(Parser *p, asdl_seq *dots, expr_ty module_name, + asdl_alias_seq *names, expr_ty lazy_token, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) +{ + identifier module = module_name->v.Name.id; + int level = _PyPegen_seq_count_dots(dots); if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) { if (lazy_token) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(lazy_token, @@ -2025,6 +2079,15 @@ _PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq * na } } } + else if ( + level > 0 + && lazy_token == NULL + && PyUnicode_CompareWithASCIIString(module, "lazy") == 0 + ) { + if (_warn_relative_import_of_lazy(p, dots, module_name) < 0) { + return NULL; + } + } return _PyAST_ImportFrom(module, names, level, lazy_token ? 1 : 0, lineno, col_offset, end_lineno, end_col_offset, arena); } diff --git a/Parser/parser.c b/Parser/parser.c index 58b6dd77a38b26d..8f218077a8b9033 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -22,28 +22,28 @@ static KeywordToken *reserved_keywords[] = { (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) { - {"if", 698}, - {"as", 696}, - {"in", 711}, + {"if", 700}, + {"as", 698}, + {"in", 713}, {"or", 589}, {"is", 597}, {NULL, -1}, }, (KeywordToken[]) { {"del", 634}, - {"def", 715}, - {"for", 710}, - {"try", 672}, + {"def", 717}, + {"for", 712}, + {"try", 674}, {"and", 590}, - {"not", 719}, + {"not", 721}, {NULL, -1}, }, (KeywordToken[]) { - {"from", 646}, + {"from", 650}, {"pass", 527}, - {"with", 663}, - {"elif", 703}, - {"else", 702}, + {"with", 665}, + {"elif", 705}, + {"else", 704}, {"None", 628}, {"True", 627}, {NULL, -1}, @@ -52,24 +52,24 @@ static KeywordToken *reserved_keywords[] = { {"raise", 632}, {"yield", 588}, {"break", 528}, - {"async", 714}, - {"class", 717}, - {"while", 705}, + {"async", 716}, + {"class", 719}, + {"while", 707}, {"False", 629}, {"await", 598}, {NULL, -1}, }, (KeywordToken[]) { - {"import", 647}, + {"import", 651}, {"return", 522}, {"assert", 638}, {"global", 530}, - {"except", 693}, + {"except", 695}, {"lambda", 622}, {NULL, -1}, }, (KeywordToken[]) { - {"finally", 689}, + {"finally", 691}, {NULL, -1}, }, (KeywordToken[]) { @@ -326,224 +326,225 @@ static char *soft_keywords[] = { #define invalid_import_type 1237 #define invalid_dotted_as_name_type 1238 #define invalid_import_from_as_name_type 1239 -#define invalid_import_from_targets_type 1240 -#define invalid_with_stmt_type 1241 -#define invalid_with_stmt_indent_type 1242 -#define invalid_try_stmt_type 1243 -#define invalid_except_stmt_type 1244 -#define invalid_except_star_stmt_type 1245 -#define invalid_finally_stmt_type 1246 -#define invalid_except_stmt_indent_type 1247 -#define invalid_except_star_stmt_indent_type 1248 -#define invalid_match_stmt_type 1249 -#define invalid_case_block_type 1250 -#define invalid_as_pattern_type 1251 -#define invalid_class_pattern_type 1252 -#define invalid_mapping_pattern_type 1253 -#define invalid_class_argument_pattern_type 1254 -#define invalid_if_stmt_type 1255 -#define invalid_elif_stmt_type 1256 -#define invalid_else_stmt_type 1257 -#define invalid_while_stmt_type 1258 -#define invalid_for_stmt_type 1259 -#define invalid_def_raw_type 1260 -#define invalid_class_def_raw_type 1261 -#define invalid_double_starred_kvpairs_type 1262 -#define invalid_kvpair_unpacking_type 1263 -#define invalid_kvpair_type 1264 -#define invalid_starred_expression_unpacking_type 1265 -#define invalid_starred_expression_unpacking_sequence_type 1266 -#define invalid_starred_expression_type 1267 -#define invalid_fstring_replacement_field_type 1268 -#define invalid_fstring_conversion_character_type 1269 -#define invalid_tstring_replacement_field_type 1270 -#define invalid_tstring_conversion_character_type 1271 -#define invalid_string_tstring_concat_type 1272 -#define invalid_arithmetic_type 1273 -#define invalid_factor_type 1274 -#define invalid_type_params_type 1275 -#define invalid_bitwise_and_type 1276 // Left-recursive -#define invalid_bitwise_or_type 1277 // Left-recursive -#define _loop0_1_type 1278 -#define _loop1_2_type 1279 -#define _loop0_3_type 1280 -#define _gather_4_type 1281 -#define _tmp_5_type 1282 -#define _tmp_6_type 1283 -#define _tmp_7_type 1284 -#define _tmp_8_type 1285 -#define _tmp_9_type 1286 -#define _tmp_10_type 1287 -#define _tmp_11_type 1288 -#define _loop1_12_type 1289 -#define _loop0_13_type 1290 -#define _gather_14_type 1291 -#define _tmp_15_type 1292 -#define _tmp_16_type 1293 -#define _loop0_17_type 1294 -#define _loop1_18_type 1295 -#define _loop0_19_type 1296 -#define _gather_20_type 1297 -#define _tmp_21_type 1298 -#define _loop0_22_type 1299 -#define _gather_23_type 1300 -#define _loop1_24_type 1301 -#define _tmp_25_type 1302 -#define _tmp_26_type 1303 -#define _loop0_27_type 1304 -#define _loop0_28_type 1305 -#define _loop1_29_type 1306 -#define _loop1_30_type 1307 -#define _loop0_31_type 1308 -#define _loop1_32_type 1309 -#define _loop0_33_type 1310 -#define _gather_34_type 1311 -#define _tmp_35_type 1312 -#define _loop1_36_type 1313 -#define _loop1_37_type 1314 -#define _loop1_38_type 1315 -#define _loop0_39_type 1316 -#define _gather_40_type 1317 -#define _tmp_41_type 1318 -#define _tmp_42_type 1319 -#define _tmp_43_type 1320 -#define _loop0_44_type 1321 -#define _gather_45_type 1322 -#define _loop0_46_type 1323 -#define _gather_47_type 1324 -#define _tmp_48_type 1325 -#define _loop0_49_type 1326 -#define _gather_50_type 1327 -#define _loop0_51_type 1328 -#define _gather_52_type 1329 -#define _loop0_53_type 1330 -#define _gather_54_type 1331 -#define _loop1_55_type 1332 -#define _loop1_56_type 1333 -#define _loop0_57_type 1334 -#define _gather_58_type 1335 -#define _loop0_59_type 1336 -#define _gather_60_type 1337 -#define _loop1_61_type 1338 -#define _loop1_62_type 1339 -#define _loop1_63_type 1340 -#define _tmp_64_type 1341 -#define _loop0_65_type 1342 -#define _gather_66_type 1343 -#define _tmp_67_type 1344 -#define _tmp_68_type 1345 -#define _tmp_69_type 1346 -#define _tmp_70_type 1347 -#define _tmp_71_type 1348 -#define _loop0_72_type 1349 -#define _loop0_73_type 1350 -#define _loop1_74_type 1351 -#define _loop1_75_type 1352 -#define _loop0_76_type 1353 -#define _loop1_77_type 1354 -#define _loop0_78_type 1355 -#define _loop0_79_type 1356 -#define _loop0_80_type 1357 -#define _loop0_81_type 1358 -#define _loop1_82_type 1359 -#define _loop1_83_type 1360 -#define _tmp_84_type 1361 -#define _loop0_85_type 1362 -#define _gather_86_type 1363 -#define _loop1_87_type 1364 -#define _loop0_88_type 1365 -#define _tmp_89_type 1366 -#define _loop0_90_type 1367 -#define _gather_91_type 1368 -#define _tmp_92_type 1369 -#define _loop0_93_type 1370 -#define _gather_94_type 1371 -#define _loop0_95_type 1372 -#define _gather_96_type 1373 -#define _loop0_97_type 1374 -#define _loop0_98_type 1375 -#define _gather_99_type 1376 -#define _loop1_100_type 1377 -#define _tmp_101_type 1378 -#define _loop0_102_type 1379 -#define _gather_103_type 1380 -#define _loop0_104_type 1381 -#define _gather_105_type 1382 -#define _tmp_106_type 1383 -#define _tmp_107_type 1384 -#define _loop0_108_type 1385 -#define _gather_109_type 1386 -#define _tmp_110_type 1387 -#define _tmp_111_type 1388 -#define _tmp_112_type 1389 -#define _tmp_113_type 1390 -#define _tmp_114_type 1391 -#define _loop1_115_type 1392 -#define _tmp_116_type 1393 -#define _tmp_117_type 1394 -#define _tmp_118_type 1395 -#define _tmp_119_type 1396 -#define _tmp_120_type 1397 -#define _loop0_121_type 1398 -#define _loop0_122_type 1399 -#define _tmp_123_type 1400 -#define _tmp_124_type 1401 -#define _tmp_125_type 1402 -#define _tmp_126_type 1403 -#define _tmp_127_type 1404 -#define _tmp_128_type 1405 -#define _tmp_129_type 1406 -#define _tmp_130_type 1407 -#define _loop0_131_type 1408 -#define _gather_132_type 1409 -#define _tmp_133_type 1410 -#define _tmp_134_type 1411 -#define _tmp_135_type 1412 -#define _tmp_136_type 1413 -#define _loop0_137_type 1414 -#define _gather_138_type 1415 -#define _tmp_139_type 1416 -#define _loop0_140_type 1417 -#define _gather_141_type 1418 -#define _loop0_142_type 1419 -#define _gather_143_type 1420 -#define _tmp_144_type 1421 -#define _loop0_145_type 1422 -#define _tmp_146_type 1423 -#define _tmp_147_type 1424 -#define _tmp_148_type 1425 -#define _tmp_149_type 1426 -#define _tmp_150_type 1427 -#define _tmp_151_type 1428 -#define _tmp_152_type 1429 -#define _tmp_153_type 1430 -#define _tmp_154_type 1431 -#define _tmp_155_type 1432 -#define _tmp_156_type 1433 -#define _tmp_157_type 1434 -#define _tmp_158_type 1435 -#define _tmp_159_type 1436 -#define _tmp_160_type 1437 -#define _tmp_161_type 1438 -#define _tmp_162_type 1439 -#define _tmp_163_type 1440 -#define _tmp_164_type 1441 -#define _tmp_165_type 1442 -#define _tmp_166_type 1443 -#define _tmp_167_type 1444 -#define _tmp_168_type 1445 -#define _tmp_169_type 1446 -#define _tmp_170_type 1447 -#define _tmp_171_type 1448 -#define _tmp_172_type 1449 -#define _tmp_173_type 1450 -#define _loop0_174_type 1451 -#define _tmp_175_type 1452 -#define _tmp_176_type 1453 -#define _tmp_177_type 1454 -#define _tmp_178_type 1455 -#define _tmp_179_type 1456 -#define _tmp_180_type 1457 +#define invalid_import_from_type 1240 +#define invalid_import_from_targets_type 1241 +#define invalid_with_stmt_type 1242 +#define invalid_with_stmt_indent_type 1243 +#define invalid_try_stmt_type 1244 +#define invalid_except_stmt_type 1245 +#define invalid_except_star_stmt_type 1246 +#define invalid_finally_stmt_type 1247 +#define invalid_except_stmt_indent_type 1248 +#define invalid_except_star_stmt_indent_type 1249 +#define invalid_match_stmt_type 1250 +#define invalid_case_block_type 1251 +#define invalid_as_pattern_type 1252 +#define invalid_class_pattern_type 1253 +#define invalid_mapping_pattern_type 1254 +#define invalid_class_argument_pattern_type 1255 +#define invalid_if_stmt_type 1256 +#define invalid_elif_stmt_type 1257 +#define invalid_else_stmt_type 1258 +#define invalid_while_stmt_type 1259 +#define invalid_for_stmt_type 1260 +#define invalid_def_raw_type 1261 +#define invalid_class_def_raw_type 1262 +#define invalid_double_starred_kvpairs_type 1263 +#define invalid_kvpair_unpacking_type 1264 +#define invalid_kvpair_type 1265 +#define invalid_starred_expression_unpacking_type 1266 +#define invalid_starred_expression_unpacking_sequence_type 1267 +#define invalid_starred_expression_type 1268 +#define invalid_fstring_replacement_field_type 1269 +#define invalid_fstring_conversion_character_type 1270 +#define invalid_tstring_replacement_field_type 1271 +#define invalid_tstring_conversion_character_type 1272 +#define invalid_string_tstring_concat_type 1273 +#define invalid_arithmetic_type 1274 +#define invalid_factor_type 1275 +#define invalid_type_params_type 1276 +#define invalid_bitwise_and_type 1277 // Left-recursive +#define invalid_bitwise_or_type 1278 // Left-recursive +#define _loop0_1_type 1279 +#define _loop1_2_type 1280 +#define _loop0_3_type 1281 +#define _gather_4_type 1282 +#define _tmp_5_type 1283 +#define _tmp_6_type 1284 +#define _tmp_7_type 1285 +#define _tmp_8_type 1286 +#define _tmp_9_type 1287 +#define _tmp_10_type 1288 +#define _tmp_11_type 1289 +#define _loop1_12_type 1290 +#define _loop0_13_type 1291 +#define _gather_14_type 1292 +#define _tmp_15_type 1293 +#define _tmp_16_type 1294 +#define _loop0_17_type 1295 +#define _loop1_18_type 1296 +#define _loop0_19_type 1297 +#define _gather_20_type 1298 +#define _tmp_21_type 1299 +#define _loop0_22_type 1300 +#define _gather_23_type 1301 +#define _loop1_24_type 1302 +#define _tmp_25_type 1303 +#define _tmp_26_type 1304 +#define _loop0_27_type 1305 +#define _loop0_28_type 1306 +#define _loop1_29_type 1307 +#define _loop1_30_type 1308 +#define _loop0_31_type 1309 +#define _loop1_32_type 1310 +#define _loop0_33_type 1311 +#define _gather_34_type 1312 +#define _tmp_35_type 1313 +#define _loop1_36_type 1314 +#define _loop1_37_type 1315 +#define _loop1_38_type 1316 +#define _loop0_39_type 1317 +#define _gather_40_type 1318 +#define _tmp_41_type 1319 +#define _tmp_42_type 1320 +#define _tmp_43_type 1321 +#define _loop0_44_type 1322 +#define _gather_45_type 1323 +#define _loop0_46_type 1324 +#define _gather_47_type 1325 +#define _tmp_48_type 1326 +#define _loop0_49_type 1327 +#define _gather_50_type 1328 +#define _loop0_51_type 1329 +#define _gather_52_type 1330 +#define _loop0_53_type 1331 +#define _gather_54_type 1332 +#define _loop1_55_type 1333 +#define _loop1_56_type 1334 +#define _loop0_57_type 1335 +#define _gather_58_type 1336 +#define _loop0_59_type 1337 +#define _gather_60_type 1338 +#define _loop1_61_type 1339 +#define _loop1_62_type 1340 +#define _loop1_63_type 1341 +#define _tmp_64_type 1342 +#define _loop0_65_type 1343 +#define _gather_66_type 1344 +#define _tmp_67_type 1345 +#define _tmp_68_type 1346 +#define _tmp_69_type 1347 +#define _tmp_70_type 1348 +#define _tmp_71_type 1349 +#define _loop0_72_type 1350 +#define _loop0_73_type 1351 +#define _loop1_74_type 1352 +#define _loop1_75_type 1353 +#define _loop0_76_type 1354 +#define _loop1_77_type 1355 +#define _loop0_78_type 1356 +#define _loop0_79_type 1357 +#define _loop0_80_type 1358 +#define _loop0_81_type 1359 +#define _loop1_82_type 1360 +#define _loop1_83_type 1361 +#define _tmp_84_type 1362 +#define _loop0_85_type 1363 +#define _gather_86_type 1364 +#define _loop1_87_type 1365 +#define _loop0_88_type 1366 +#define _tmp_89_type 1367 +#define _loop0_90_type 1368 +#define _gather_91_type 1369 +#define _tmp_92_type 1370 +#define _loop0_93_type 1371 +#define _gather_94_type 1372 +#define _loop0_95_type 1373 +#define _gather_96_type 1374 +#define _loop0_97_type 1375 +#define _loop0_98_type 1376 +#define _gather_99_type 1377 +#define _loop1_100_type 1378 +#define _tmp_101_type 1379 +#define _loop0_102_type 1380 +#define _gather_103_type 1381 +#define _loop0_104_type 1382 +#define _gather_105_type 1383 +#define _tmp_106_type 1384 +#define _tmp_107_type 1385 +#define _loop0_108_type 1386 +#define _gather_109_type 1387 +#define _tmp_110_type 1388 +#define _tmp_111_type 1389 +#define _tmp_112_type 1390 +#define _tmp_113_type 1391 +#define _tmp_114_type 1392 +#define _loop1_115_type 1393 +#define _tmp_116_type 1394 +#define _tmp_117_type 1395 +#define _tmp_118_type 1396 +#define _tmp_119_type 1397 +#define _tmp_120_type 1398 +#define _loop0_121_type 1399 +#define _loop0_122_type 1400 +#define _tmp_123_type 1401 +#define _tmp_124_type 1402 +#define _tmp_125_type 1403 +#define _tmp_126_type 1404 +#define _tmp_127_type 1405 +#define _tmp_128_type 1406 +#define _tmp_129_type 1407 +#define _tmp_130_type 1408 +#define _loop0_131_type 1409 +#define _gather_132_type 1410 +#define _tmp_133_type 1411 +#define _tmp_134_type 1412 +#define _tmp_135_type 1413 +#define _tmp_136_type 1414 +#define _loop0_137_type 1415 +#define _gather_138_type 1416 +#define _tmp_139_type 1417 +#define _loop0_140_type 1418 +#define _gather_141_type 1419 +#define _loop0_142_type 1420 +#define _gather_143_type 1421 +#define _tmp_144_type 1422 +#define _loop0_145_type 1423 +#define _tmp_146_type 1424 +#define _tmp_147_type 1425 +#define _tmp_148_type 1426 +#define _tmp_149_type 1427 +#define _tmp_150_type 1428 +#define _tmp_151_type 1429 +#define _tmp_152_type 1430 +#define _tmp_153_type 1431 +#define _tmp_154_type 1432 +#define _tmp_155_type 1433 +#define _tmp_156_type 1434 +#define _tmp_157_type 1435 +#define _tmp_158_type 1436 +#define _tmp_159_type 1437 +#define _tmp_160_type 1438 +#define _tmp_161_type 1439 +#define _tmp_162_type 1440 +#define _tmp_163_type 1441 +#define _tmp_164_type 1442 +#define _tmp_165_type 1443 +#define _tmp_166_type 1444 +#define _tmp_167_type 1445 +#define _tmp_168_type 1446 +#define _tmp_169_type 1447 +#define _tmp_170_type 1448 +#define _tmp_171_type 1449 +#define _tmp_172_type 1450 +#define _tmp_173_type 1451 +#define _loop0_174_type 1452 +#define _tmp_175_type 1453 +#define _tmp_176_type 1454 +#define _tmp_177_type 1455 +#define _tmp_178_type 1456 +#define _tmp_179_type 1457 +#define _tmp_180_type 1458 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -785,6 +786,7 @@ static void *invalid_group_rule(Parser *p); static void *invalid_import_rule(Parser *p); static void *invalid_dotted_as_name_rule(Parser *p); static void *invalid_import_from_as_name_rule(Parser *p); +static void *invalid_import_from_rule(Parser *p); static void *invalid_import_from_targets_rule(Parser *p); static void *invalid_with_stmt_rule(Parser *p); static void *invalid_with_stmt_indent_rule(Parser *p); @@ -1968,7 +1970,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); stmt_ty if_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 698) // token='if' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 700) // token='if' && (if_stmt_var = if_stmt_rule(p)) // if_stmt ) @@ -2052,7 +2054,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); stmt_ty try_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 672) // token='try' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 674) // token='try' && (try_stmt_var = try_stmt_rule(p)) // try_stmt ) @@ -2073,7 +2075,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); stmt_ty while_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 705) // token='while' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 707) // token='while' && (while_stmt_var = while_stmt_rule(p)) // while_stmt ) @@ -2840,7 +2842,7 @@ raise_stmt_rule(Parser *p) && (a = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 646)) // token='from' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='from' && (b = expression_rule(p)) // expression ) @@ -3619,7 +3621,7 @@ import_name_rule(Parser *p) if ( (lazy = _PyPegen_expect_soft_keyword(p, "lazy"), !p->error_indicator) // "lazy"? && - (_keyword = _PyPegen_expect_token(p, 647)) // token='import' + (_keyword = _PyPegen_expect_token(p, 651)) // token='import' && (a = dotted_as_names_rule(p)) // dotted_as_names ) @@ -3653,6 +3655,7 @@ import_name_rule(Parser *p) } // import_from: +// | invalid_import_from // | "lazy"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets // | "lazy"? 'from' (('.' | '...'))+ 'import' import_from_targets static stmt_ty @@ -3676,6 +3679,25 @@ import_from_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro + if (p->call_invalid_rules) { // invalid_import_from + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import_from")); + void *invalid_import_from_var; + if ( + (invalid_import_from_var = invalid_import_from_rule(p)) // invalid_import_from + ) + { + D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_import_from")); + _res = invalid_import_from_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_import_from")); + } { // "lazy"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets if (p->error_indicator) { p->level--; @@ -3691,13 +3713,13 @@ import_from_rule(Parser *p) if ( (lazy = _PyPegen_expect_soft_keyword(p, "lazy"), !p->error_indicator) // "lazy"? && - (_keyword = _PyPegen_expect_token(p, 646)) // token='from' + (_keyword = _PyPegen_expect_token(p, 650)) // token='from' && (a = _loop0_17_rule(p)) // (('.' | '...'))* && (b = dotted_name_rule(p)) // dotted_name && - (_keyword_1 = _PyPegen_expect_token(p, 647)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='import' && (c = import_from_targets_rule(p)) // import_from_targets ) @@ -3712,7 +3734,7 @@ import_from_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _PyPegen_checked_future_import ( p , b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , lazy , EXTRA ); + _res = _PyPegen_checked_from_import ( p , a , b , c , lazy , EXTRA ); if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -3738,11 +3760,11 @@ import_from_rule(Parser *p) if ( (lazy = _PyPegen_expect_soft_keyword(p, "lazy"), !p->error_indicator) // "lazy"? && - (_keyword = _PyPegen_expect_token(p, 646)) // token='from' + (_keyword = _PyPegen_expect_token(p, 650)) // token='from' && (a = _loop1_18_rule(p)) // (('.' | '...'))+ && - (_keyword_1 = _PyPegen_expect_token(p, 647)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='import' && (b = import_from_targets_rule(p)) // import_from_targets ) @@ -4529,7 +4551,7 @@ class_def_raw_rule(Parser *p) asdl_stmt_seq* c; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 717)) // token='class' + (_keyword = _PyPegen_expect_token(p, 719)) // token='class' && (a = _PyPegen_name_token(p)) // NAME && @@ -4696,7 +4718,7 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 715)) // token='def' + (_keyword = _PyPegen_expect_token(p, 717)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4757,9 +4779,9 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 715)) // token='def' + (_keyword_1 = _PyPegen_expect_token(p, 717)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -6097,7 +6119,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6142,7 +6164,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6237,7 +6259,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 703)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 705)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6282,7 +6304,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 703)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 705)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6363,7 +6385,7 @@ else_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword = _PyPegen_expect_token(p, 704)) // token='else' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6442,7 +6464,7 @@ while_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 705)) // token='while' + (_keyword = _PyPegen_expect_token(p, 707)) // token='while' && (a = named_expression_rule(p)) // named_expression && @@ -6542,11 +6564,11 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword = _PyPegen_expect_token(p, 712)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 713)) // token='in' && (_cut_var = 1) && @@ -6604,13 +6626,13 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 712)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_2 = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 713)) // token='in' && (_cut_var = 1) && @@ -6739,7 +6761,7 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword = _PyPegen_expect_token(p, 665)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -6790,7 +6812,7 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword = _PyPegen_expect_token(p, 665)) // token='with' && (a = (asdl_withitem_seq*)_gather_34_rule(p)) // ','.with_item+ && @@ -6839,9 +6861,9 @@ with_stmt_rule(Parser *p) asdl_withitem_seq* a; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 665)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -6891,9 +6913,9 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 665)) // token='with' && (a = (asdl_withitem_seq*)_gather_34_rule(p)) // ','.with_item+ && @@ -6979,7 +7001,7 @@ with_item_rule(Parser *p) if ( (e = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (t = star_target_rule(p)) // star_target && @@ -7104,7 +7126,7 @@ try_stmt_rule(Parser *p) asdl_stmt_seq* b; asdl_stmt_seq* f; if ( - (_keyword = _PyPegen_expect_token(p, 672)) // token='try' + (_keyword = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7148,7 +7170,7 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 672)) // token='try' + (_keyword = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7196,7 +7218,7 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 672)) // token='try' + (_keyword = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7295,7 +7317,7 @@ except_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (e = expression_rule(p)) // expression && @@ -7339,11 +7361,11 @@ except_block_rule(Parser *p) expr_ty e; expr_ty t; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (e = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 698)) // token='as' && (t = _PyPegen_name_token(p)) // NAME && @@ -7385,7 +7407,7 @@ except_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (e = expressions_rule(p)) // expressions && @@ -7426,7 +7448,7 @@ except_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7538,7 +7560,7 @@ except_star_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -7585,13 +7607,13 @@ except_star_block_rule(Parser *p) expr_ty e; expr_ty t; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (e = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 698)) // token='as' && (t = _PyPegen_name_token(p)) // NAME && @@ -7634,7 +7656,7 @@ except_star_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -7734,7 +7756,7 @@ finally_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 689)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 691)) // token='finally' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -8042,7 +8064,7 @@ guard_rule(Parser *p) Token * _keyword; expr_ty guard; if ( - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (guard = named_expression_rule(p)) // named_expression ) @@ -8237,7 +8259,7 @@ as_pattern_rule(Parser *p) if ( (pattern = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (target = pattern_capture_target_rule(p)) // pattern_capture_target ) @@ -11732,11 +11754,11 @@ if_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 704)) // token='else' && (c = expression_rule(p)) // expression ) @@ -11803,7 +11825,7 @@ yield_expr_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 588)) // token='yield' && - (_keyword_1 = _PyPegen_expect_token(p, 646)) // token='from' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='from' && (a = expression_rule(p)) // expression ) @@ -12685,7 +12707,7 @@ inversion_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 719)) // token='not' + (_keyword = _PyPegen_expect_token(p, 721)) // token='not' && (a = inversion_rule(p)) // inversion ) @@ -13339,9 +13361,9 @@ notin_bitwise_or_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 719)) // token='not' + (_keyword = _PyPegen_expect_token(p, 721)) // token='not' && - (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 713)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -13387,7 +13409,7 @@ in_bitwise_or_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword = _PyPegen_expect_token(p, 713)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -13436,7 +13458,7 @@ isnot_bitwise_or_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 597)) // token='is' && - (_keyword_1 = _PyPegen_expect_token(p, 719)) // token='not' + (_keyword_1 = _PyPegen_expect_token(p, 721)) // token='not' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -18133,13 +18155,13 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 712)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_2 = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 713)) // token='in' && (_cut_var = 1) && @@ -18178,11 +18200,11 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword = _PyPegen_expect_token(p, 712)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 713)) // token='in' && (_cut_var = 1) && @@ -21509,11 +21531,11 @@ expression_without_invalid_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 704)) // token='else' && (c = expression_rule(p)) // expression ) @@ -21813,7 +21835,7 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && @@ -21846,11 +21868,11 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 704)) // token='else' && _PyPegen_lookahead_for_expr(0, expression_rule, p) ) @@ -21882,11 +21904,11 @@ invalid_expression_rule(Parser *p) if ( (a = (stmt_ty)_tmp_118_rule(p)) // pass_stmt | break_stmt | continue_stmt && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 704)) // token='else' && (c = simple_stmt_rule(p)) // simple_stmt ) @@ -22005,11 +22027,11 @@ invalid_if_expression_rule(Parser *p) if ( (disjunction_var = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 704)) // token='else' && (a = _PyPegen_expect_token(p, 16)) // token='*' ) @@ -22041,11 +22063,11 @@ invalid_if_expression_rule(Parser *p) if ( (disjunction_var = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 704)) // token='else' && (a = _PyPegen_expect_token(p, 35)) // token='**' ) @@ -22514,7 +22536,7 @@ invalid_raise_stmt_rule(Parser *p) if ( (a = _PyPegen_expect_token(p, 632)) // token='raise' && - (b = _PyPegen_expect_token(p, 646)) // token='from' + (b = _PyPegen_expect_token(p, 650)) // token='from' ) { D(fprintf(stderr, "%*c+ invalid_raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' 'from'")); @@ -22544,7 +22566,7 @@ invalid_raise_stmt_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (a = _PyPegen_expect_token(p, 646)) // token='from' + (a = _PyPegen_expect_token(p, 650)) // token='from' ) { D(fprintf(stderr, "%*c+ invalid_raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' expression 'from'")); @@ -24173,7 +24195,7 @@ invalid_with_item_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (a = expression_rule(p)) // expression && @@ -24223,13 +24245,13 @@ invalid_for_if_clause_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings void *_tmp_136_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword = _PyPegen_expect_token(p, 712)) // token='for' && (_tmp_136_var = _tmp_136_rule(p)) // bitwise_or ((',' bitwise_or))* ','? && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 711) // token='in' + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 713) // token='in' ) { D(fprintf(stderr, "%*c+ invalid_for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' (bitwise_or ((',' bitwise_or))* ','?) !'in'")); @@ -24275,9 +24297,9 @@ invalid_for_target_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings expr_ty a; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword = _PyPegen_expect_token(p, 712)) // token='for' && (a = star_expressions_rule(p)) // star_expressions ) @@ -24407,11 +24429,11 @@ invalid_import_rule(Parser *p) Token * a; expr_ty dotted_name_var; if ( - (a = _PyPegen_expect_token(p, 647)) // token='import' + (a = _PyPegen_expect_token(p, 651)) // token='import' && (_gather_138_var = _gather_138_rule(p)) // ','.dotted_name+ && - (_keyword = _PyPegen_expect_token(p, 646)) // token='from' + (_keyword = _PyPegen_expect_token(p, 650)) // token='from' && (dotted_name_var = dotted_name_rule(p)) // dotted_name ) @@ -24438,7 +24460,7 @@ invalid_import_rule(Parser *p) Token * _keyword; Token * token; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='import' + (_keyword = _PyPegen_expect_token(p, 651)) // token='import' && (token = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -24487,7 +24509,7 @@ invalid_dotted_as_name_rule(Parser *p) if ( (dotted_name_var = dotted_name_rule(p)) // dotted_name && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && _PyPegen_lookahead(0, _tmp_139_rule, p) && @@ -24538,7 +24560,7 @@ invalid_import_from_as_name_rule(Parser *p) if ( (name_var = _PyPegen_name_token(p)) // NAME && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && _PyPegen_lookahead(0, _tmp_139_rule, p) && @@ -24564,6 +24586,65 @@ invalid_import_from_as_name_rule(Parser *p) return _res; } +// invalid_import_from: +// | 'from' (('.' | '...'))* dotted_name "lazy" 'import' import_from_targets +static void * +invalid_import_from_rule(Parser *p) +{ + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'from' (('.' | '...'))* dotted_name "lazy" 'import' import_from_targets + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name \"lazy\" 'import' import_from_targets")); + Token * _keyword; + Token * _keyword_1; + asdl_seq * _loop0_17_var; + expr_ty a; + expr_ty dotted_name_var; + asdl_alias_seq* import_from_targets_var; + if ( + (_keyword = _PyPegen_expect_token(p, 650)) // token='from' + && + (_loop0_17_var = _loop0_17_rule(p)) // (('.' | '...'))* + && + (dotted_name_var = dotted_name_rule(p)) // dotted_name + && + (a = _PyPegen_expect_soft_keyword(p, "lazy")) // soft_keyword='"lazy"' + && + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='import' + && + (import_from_targets_var = import_from_targets_rule(p)) // import_from_targets + ) + { + D(fprintf(stderr, "%*c+ invalid_import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name \"lazy\" 'import' import_from_targets")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "use 'lazy from ... ' instead of 'from ... lazy import'" ); + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_import_from[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))* dotted_name \"lazy\" 'import' import_from_targets")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // invalid_import_from_targets: import_from_as_names ',' NEWLINE | NEWLINE static void * invalid_import_from_targets_rule(Parser *p) @@ -24666,9 +24747,9 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings Token * trailing; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword = _PyPegen_expect_token(p, 665)) // token='with' && (_gather_141_var = _gather_141_rule(p)) // ','.(expression ['as' star_target])+ && @@ -24702,9 +24783,9 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword = _PyPegen_expect_token(p, 665)) // token='with' && (_gather_141_var = _gather_141_rule(p)) // ','.(expression ['as' star_target])+ && @@ -24740,9 +24821,9 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var_1); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword = _PyPegen_expect_token(p, 665)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -24802,9 +24883,9 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 663)) // token='with' + (a = _PyPegen_expect_token(p, 665)) // token='with' && (_gather_141_var = _gather_141_rule(p)) // ','.(expression ['as' star_target])+ && @@ -24845,9 +24926,9 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 663)) // token='with' + (a = _PyPegen_expect_token(p, 665)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -24910,7 +24991,7 @@ invalid_try_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 672)) // token='try' + (a = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24942,7 +25023,7 @@ invalid_try_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 672)) // token='try' + (_keyword = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24981,7 +25062,7 @@ invalid_try_stmt_rule(Parser *p) Token * b; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 672)) // token='try' + (_keyword = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24989,7 +25070,7 @@ invalid_try_stmt_rule(Parser *p) && (_loop1_36_var = _loop1_36_rule(p)) // except_block+ && - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (b = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25028,7 +25109,7 @@ invalid_try_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings Token * a; if ( - (_keyword = _PyPegen_expect_token(p, 672)) // token='try' + (_keyword = _PyPegen_expect_token(p, 674)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -25036,7 +25117,7 @@ invalid_try_stmt_rule(Parser *p) && (_loop1_37_var = _loop1_37_rule(p)) // except_star_block+ && - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (_opt_var = _tmp_146_rule(p), !p->error_indicator) // [expression ['as' NAME]] && @@ -25093,7 +25174,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty expressions_var; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (a = expression_rule(p)) // expression && @@ -25101,7 +25182,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 698)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -25133,7 +25214,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (expression_var = expression_rule(p)) // expression && @@ -25164,7 +25245,7 @@ invalid_except_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -25195,11 +25276,11 @@ invalid_except_stmt_rule(Parser *p) asdl_stmt_seq* block_var; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (expression_var = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 698)) // token='as' && (a = expression_rule(p)) // expression && @@ -25259,7 +25340,7 @@ invalid_except_star_stmt_rule(Parser *p) expr_ty expressions_var; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25269,7 +25350,7 @@ invalid_except_star_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 698)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -25302,7 +25383,7 @@ invalid_except_star_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25336,7 +25417,7 @@ invalid_except_star_stmt_rule(Parser *p) void *_tmp_147_var; Token * a; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25370,13 +25451,13 @@ invalid_except_star_stmt_rule(Parser *p) asdl_stmt_seq* block_var; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (expression_var = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 698)) // token='as' && (a = expression_rule(p)) // expression && @@ -25427,7 +25508,7 @@ invalid_finally_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 689)) // token='finally' + (a = _PyPegen_expect_token(p, 691)) // token='finally' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -25483,7 +25564,7 @@ invalid_except_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (expression_var = expression_rule(p)) // expression && @@ -25519,7 +25600,7 @@ invalid_except_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -25575,7 +25656,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 693)) // token='except' + (a = _PyPegen_expect_token(p, 695)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25852,7 +25933,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' ) @@ -25882,7 +25963,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (a = expression_rule(p)) // expression ) @@ -26098,7 +26179,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26129,7 +26210,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty a_1; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 698)) // token='if' + (a = _PyPegen_expect_token(p, 700)) // token='if' && (a_1 = named_expression_rule(p)) // named_expression && @@ -26184,7 +26265,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 703)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 705)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26215,7 +26296,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 703)) // token='elif' + (a = _PyPegen_expect_token(p, 705)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26268,7 +26349,7 @@ invalid_else_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 702)) // token='else' + (a = _PyPegen_expect_token(p, 704)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -26301,13 +26382,13 @@ invalid_else_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword = _PyPegen_expect_token(p, 704)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (block_var = block_rule(p)) // block && - (_keyword_1 = _PyPegen_expect_token(p, 703)) // token='elif' + (_keyword_1 = _PyPegen_expect_token(p, 705)) // token='elif' ) { D(fprintf(stderr, "%*c+ invalid_else_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':' block 'elif'")); @@ -26354,7 +26435,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 705)) // token='while' + (_keyword = _PyPegen_expect_token(p, 707)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26385,7 +26466,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 705)) // token='while' + (a = _PyPegen_expect_token(p, 707)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26444,13 +26525,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword = _PyPegen_expect_token(p, 712)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 713)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -26485,13 +26566,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 710)) // token='for' + (a = _PyPegen_expect_token(p, 712)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword = _PyPegen_expect_token(p, 711)) // token='in' + (_keyword = _PyPegen_expect_token(p, 713)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -26557,9 +26638,9 @@ invalid_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 715)) // token='def' + (a = _PyPegen_expect_token(p, 717)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -26616,9 +26697,9 @@ invalid_def_raw_rule(Parser *p) asdl_stmt_seq* block_var; expr_ty name_var; if ( - (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 716), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 715)) // token='def' + (_keyword = _PyPegen_expect_token(p, 717)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -26682,7 +26763,7 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 717)) // token='class' + (_keyword = _PyPegen_expect_token(p, 719)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -26721,7 +26802,7 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 717)) // token='class' + (a = _PyPegen_expect_token(p, 719)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -28357,7 +28438,7 @@ invalid_arithmetic_rule(Parser *p) && (_tmp_157_var = _tmp_157_rule(p)) // '+' | '-' | '*' | '/' | '%' | '//' | '@' && - (a = _PyPegen_expect_token(p, 719)) // token='not' + (a = _PyPegen_expect_token(p, 721)) // token='not' && (b = inversion_rule(p)) // inversion ) @@ -28406,7 +28487,7 @@ invalid_factor_rule(Parser *p) if ( (_tmp_158_var = _tmp_158_rule(p)) // '+' | '-' | '~' && - (a = _PyPegen_expect_token(p, 719)) // token='not' + (a = _PyPegen_expect_token(p, 721)) // token='not' && (b = factor_rule(p)) // factor ) @@ -28853,7 +28934,7 @@ _tmp_5_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='import' + (_keyword = _PyPegen_expect_token(p, 651)) // token='import' ) { D(fprintf(stderr, "%*c+ _tmp_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); @@ -28872,7 +28953,7 @@ _tmp_5_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 646)) // token='from' + (_keyword = _PyPegen_expect_token(p, 650)) // token='from' ) { D(fprintf(stderr, "%*c+ _tmp_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); @@ -28929,7 +29010,7 @@ _tmp_6_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 715)) // token='def' + (_keyword = _PyPegen_expect_token(p, 717)) // token='def' ) { D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); @@ -28967,7 +29048,7 @@ _tmp_6_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -29005,7 +29086,7 @@ _tmp_7_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 717)) // token='class' + (_keyword = _PyPegen_expect_token(p, 719)) // token='class' ) { D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); @@ -29062,7 +29143,7 @@ _tmp_8_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + (_keyword = _PyPegen_expect_token(p, 665)) // token='with' ) { D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); @@ -29081,7 +29162,7 @@ _tmp_8_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -29119,7 +29200,7 @@ _tmp_9_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 710)) // token='for' + (_keyword = _PyPegen_expect_token(p, 712)) // token='for' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); @@ -29138,7 +29219,7 @@ _tmp_9_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='async' + (_keyword = _PyPegen_expect_token(p, 716)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -29839,7 +29920,7 @@ _tmp_21_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -35811,7 +35892,7 @@ _tmp_117_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 702)) // token='else' + (_keyword = _PyPegen_expect_token(p, 704)) // token='else' ) { D(fprintf(stderr, "%*c+ _tmp_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); @@ -37474,7 +37555,7 @@ _tmp_144_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='except' + (_keyword = _PyPegen_expect_token(p, 695)) // token='except' ) { D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); @@ -37493,7 +37574,7 @@ _tmp_144_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 689)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 691)) // token='finally' ) { D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); @@ -38795,7 +38876,7 @@ _tmp_166_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 698)) // token='if' + (_keyword = _PyPegen_expect_token(p, 700)) // token='if' && (z = disjunction_rule(p)) // disjunction ) @@ -39531,7 +39612,7 @@ _tmp_180_rule(Parser *p) Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 696)) // token='as' + (_keyword = _PyPegen_expect_token(p, 698)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) diff --git a/Parser/pegen.h b/Parser/pegen.h index 4a4f7536db2da79..cbf44ba474fa395 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -371,8 +371,10 @@ mod_ty _PyPegen_make_module(Parser *, asdl_stmt_seq *); void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension); void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions); -stmt_ty _PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq *, - int, expr_ty, int, int, int, int, PyArena *); +stmt_ty _PyPegen_checked_from_import(Parser *p, asdl_seq *dots, expr_ty module_name, + asdl_alias_seq *names, expr_ty lazy_token, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); asdl_stmt_seq* _PyPegen_register_stmts(Parser *p, asdl_stmt_seq* stmts); stmt_ty _PyPegen_register_stmt(Parser *p, stmt_ty s);