1416 Commits
Author SHA1 Message Date
sobolevn 7b12a415c8 gh-152631: Fix ast.parse on lazy imports with older feature_version (#152632) 2026-10-25 20:35:59 +00:00
Lysandros Nikolaou aa0e4109a8 gh-153568: Use a managed dict for AST nodes (#160616)
AST nodes had an explicit `__dict__` slot, so every node built by
`ast.parse` allocated its own dict. With `Py_TPFLAGS_MANAGED_DICT`,
node attributes are stored as inline values with shared keys instead.

`ast.parse` is ~15.8% faster, walking trees is ~15.9% faster, and
the memory used by the AST trees is reduced by ~51.6%.
2026-10-25 10:08:26 -07:00
Lysandros Nikolaou 2258026edd gh-160491: Fix location of invalid escapes in f-strings and t-strings (#160493)
Literal parts of f-strings and t-strings are decoded only after the
whole string has been parsed, so a decode error took the location of
the last token. The resulting SyntaxError pointed at the closing quote,
and for multi-line strings it could be on the wrong line.

Raise the error at the literal part being decoded instead.
2026-10-23 15:29:41 -07:00
Pablo Galindo SalgadoandLysandros Nikolaou b77cb891e9 gh-153568: Skip the expression precedence chain for single-token atoms (#153575)
A bare name or number followed by a token that cannot extend an expression now produces its AST node directly. This avoids the expression precedence chain for common arguments, assignments, and subscripts.

Rules declare the hook with a fastpath flag. The Rule constructor exposes memo and fastpath attributes, and the C generator emits the hook call.

Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
2026-10-23 14:23:10 -07:00
Pablo Galindo Salgado 612ce88b34 gh-159465: Preserve escape errors in unfinished f-strings and t-strings (#159669) 2026-10-23 13:42:41 -07:00
Lysandros Nikolaou e548b472f3 gh-153195: Allow splitting the PEG grammar into several files (#159917)
Add an @include meta to pegen: the rules of an included grammar file are
appended to the including file's rules. The C generator emits the rules
of each included file into a separate C file next to the main output.

Use it to move the invalid_* rules from Grammar/python.gram into
Grammar/invalid.gram, which generates Parser/parser_invalid.c.
2026-10-23 12:58:39 -07:00
Lysandros Nikolaou 0b8bb7154c gh-160284: Number each keyword once in the PEG generator (#160290)
`KeywordCollectorVisitor` checked the quoted spelling of a keyword against
keys stored without quotes, so the check never matched and every
occurrence of a keyword in the grammar took a new token type. The 35
hard keywords were numbered between 500 and 721 instead of 500 to 534.
2026-10-22 19:25:07 +00:00
Shamil f65e2a2095 gh-160245: Reduce padding in the Memo struct in the parser (#160266) 2026-10-22 18:42:46 +00:00
Lysandros Nikolaou 86758d1950 gh-160268: Fix tokenize on a mismatched closing bracket in an f-string (#160272)
Since gh-105042, `tokenize` tolerates mismatched brackets. That also let
a mismatched closing bracket pop the brace that opened an f-string
replacement field, which the f-string state relies on. In `f'{]a'`, this
triggered an assertion failure in _PyLexer_scan_string.

Check the replacement field brace in both modes.
2026-10-22 11:40:46 -07:00
Jelle Zijlstra 9c239fb50a gh-159739: Preserve the syntax error if metadata allocation fails (#159751)
Restore the original exception when optional syntax-error metadata
cannot be allocated.
2026-10-19 19:31:16 -07:00
Pablo Galindo Salgado 6af655301a gh-159465: Improve incomplete input detection (#159466)
* gh-159465: Improve incomplete input detection

* gh-159465: Track newline effects and preserve parser layout

* gh-159465: Share incomplete-input error cleanup
2026-10-18 11:54:19 +01:00
Pablo Galindo Salgado f892b11f22 gh-153569: Simplify tokenizer source views and reader ownership (#158849)
Move source access and logical spans into the tokenizer source API, and keep input and encoding ownership in the reader. Export the incremental decoder helper for parser generator extensions.
2026-10-13 13:01:17 +00:00
Pablo Galindo Salgado 0b8aa89a05 gh-153569: Simplify tokenizer state (#158124)
* Use diagnostic line for missing-brace errors

* Keep implicit prepared newline metadata in the reader

* Reuse parsed formatted string kind in lexer

* Transfer owned tokenizer encoding strings

* Remove unused tokenizer state and redundant branches

* Avoid rescanning partial decoded tokenizer lines

* Reuse prepared tokenizer line terminators for CR detection

* Reuse interactive tokenizer chunks without carriage returns

* Release tokenizer constructor resources on allocation failure

* Narrow interactive newline normalization wrapper

* Close duplicated tokenizer descriptors when fdopen fails

* Preserve cached tokenizer lines when newline allocation fails

* Collect cycles involving tokenizer readline callbacks

* Preserve buffered text when decoding source files

* Clear the transferred syntax error line before cleanup

* Propagate tokenizer column conversion failures

* Allocate parser repetition buffers on first match

* Allocate type comment storage only when needed

* Reuse decoded multiline text when counting token columns

* Skip empty decoded tokenizer chunks

* Check parser array growth before allocating

* Name tokenizer bounds and derive byte lengths from their data

* Set the tokenizer exception when file input size overflows

* gh-153569: Send exact line endings in the REPL test

* Share parser repetition buffer growth

* Fold Unicode input coverage into the existing REPL test

* Keep parser array growth policy private

* Drop obsolete bitmap stress from source discard test

* Preserve input failures while scanning string literals

* fixup! Preserve input failures while scanning string literals

* fixup! fixup! Preserve input failures while scanning string literals

* gh-153569: Remove assertion-only lexer bookkeeping
2026-10-05 14:28:51 +01:00
Pengyu Lee 83bea6487c gh-158309: Set MemoryError when allocation fails in decode_unicode_with_escapes() (#158311) 2026-09-28 12:52:26 +01:00
Sergey B Kirpichev 198bc76836 gh-151464: exclude '<>' token from tokenize output (#154854)
* gh-151464: exclude '<>' token from tokenize output

Was:
```
$ echo '1 <> 2' | python -m tokenize
1,0-1,1:            NUMBER         '1'
1,2-1,4:            OP             '<>'
1,5-1,6:            NUMBER         '2'
1,6-1,7:            NEWLINE        '\n'
2,0-2,0:            ENDMARKER      ''
```

Now (regardless on ``__future__.barry_as_FLUFL`` import):
```
$ echo '1 <> 2' | ./python -m tokenize
1,0-1,1:            NUMBER         '1'
1,2-1,3:            OP             '<'
1,3-1,4:            OP             '>'
1,5-1,6:            NUMBER         '2'
1,6-1,7:            NEWLINE        '\n'
2,0-2,0:            ENDMARKER      ''
```
in accordance with the Grammar:
https://docs.python.org/3.14/reference/lexical_analysis.html#operators-and-delimiters

Also adds a custom error message for ``<>`` ("not equal" in Pascal
and Python 2).

* +1

* address review: lowercase and move invalid rule

* address review: news

* address review: move test_guido_as_bdfl_ineq_tokens()

* address review: revert _PyTokenizer_From* changes

* + revert unrelated change

* address review: remove whatsnew entry
2026-09-25 19:51:59 +01:00
Pablo Galindo Salgado 2a96282d9a gh-153569: consolidate tokenizer input, layout, and diagnostics (#157055)
* gh-153569: move tokenizer input state and relocation into the reader

* gh-153569: borrow diagnostic lines through the source API

* gh-153569: group indentation and logical-line state

* gh-153569: remove unused tokenizer cursor and source lookup APIs

* gh-153569: report tokenizer diagnostics without rewinding the scanner

* gh-153569: use tokenizer views and remove obsolete API remnants
2026-09-24 16:26:47 +00:00
Inada Naoki bd0913a840 gh-157407: Fix a compilation error on Windows. (#158048)
`&PyUnicode_Type` cannot be determined at compile time on Windows.
Caused by #157393.
2026-09-24 15:06:56 +09:00
7884f48af4 gh-152708: Fix AST generation asymmetry for unary positive in match statements (#152712)
Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: johnslavik <bartosz@ilikepython.com>
2026-09-23 19:56:53 -07:00
Pablo Galindo Salgado 1cdd590cb5 gh-157778: Include opening brace line in multiline f-string errors (#157779) 2026-09-24 01:23:06 +01:00
Inada NaokiandPieter Eendebak 16b357b6cd gh-157407: Reduce code size of ast and unicodeobject (#157393)
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
2026-09-23 23:13:51 +09:00
Victor Stinner 1e03154546 gh-155742: Use PyMem_Malloc() in decode_unicode_with_escapes() (#157587)
Replace soft deprecated PyBytes_FromStringAndSize(NULL, size) with a
simple PyMem_Malloc(). Avoid also "s = buf" to make the code easier to follow
(and easier to debug).

Add non-ASCII tests to test_string_literals.
2026-09-17 11:54:26 +00:00
Pablo Galindo Salgado d8a1072491 gh-153568: Reduce parser allocations (#157374) 2026-09-16 16:10:40 -04:00
Bartosz Sławecki 1bfcc3cc87 gh-156909: Fix AST.__repr__ call getting the _fields attribute (GH-157490) 2026-09-15 08:26:26 +02:00
Pablo Galindo Salgado 89fe9857dd gh-153568: Reuse shared prefixes in generated parser rules (#157465) 2026-09-14 20:26:18 -04:00
Pablo Galindo SalgadoandMaurycy Pawłowski-Wieroński e5fbabbb47 gh-153568: Don't materialize parser token text that is never read (#153576)
* gh-153568: Don't materialize parser token text that is never read

Only tokens whose text is actually consumed get a bytes object;
operators and structural tokens no longer allocate one.

* Update Parser/pegen.c

Co-authored-by: Maurycy Pawłowski-Wieroński <maurycy@maurycy.com>

* gh-153568: Preserve keyword token text

---------

Co-authored-by: Maurycy Pawłowski-Wieroński <maurycy@maurycy.com>
2026-09-14 20:31:59 +00:00
Pablo Galindo Salgado c3f23734a8 gh-153568: Share expression parsing with assignment targets (#157450)
* gh-153568: Share expression parsing with assignment targets

* Clarify target parsing contracts and AST expectations
2026-09-14 16:53:25 +00:00
Pablo Galindo Salgado 0d6671d744 gh-153568: Skip newline translation for source without carriage returns (#153584)
The tokenizer copied every input byte by byte to normalize newlines,
but source without a carriage return needs no translation and can be
copied verbatim.
2026-09-14 16:24:02 +00:00
Pablo Galindo Salgado f88d6687b6 gh-153568: Make the parser's per-rule stack check an inline comparison (#153573)
* gh-153568: Make the parser's per-rule stack check an inline comparison

The parser now caches the thread state and stack limit up front and
only falls back to the full check when the stack is nearly exhausted.

* fixup! gh-153568: Make the parser's per-rule stack check an inline comparison

* fixup! gh-153568: Make the parser's per-rule stack check an inline comparison
2026-09-14 16:08:59 +00:00
Pablo Galindo Salgado ac86e12d74 gh-153568: Stop re-walking memo lists when growing left-recursive rules (#153574)
The left-recursion driver now keeps a direct reference to its memo
entry and updates it in place on every iteration.
2026-09-14 11:41:14 -04:00
Shamil e66bec09b7 gh-157378: Fix SyntaxError.offset for "Non-UTF-8 code" error (#157412) 2026-09-14 12:13:40 +00:00
Bartosz Sławecki b62380fdb8 gh-156021: Don't include ... for empty AST node representations (GH-156022) 2026-09-14 14:06:22 +02:00
Pengyu Lee 1a703ab9e6 gh-154719: Preserve trailing whitespace in t-string interpolation expressions (#154762) 2026-09-13 01:09:22 +01:00
Pablo Galindo Salgado 7bfa97f4dc gh-153569: hide tokenizer state behind token and source operations (#156654)
Make pegen and _tokenize consume tokenizer operations instead of accessing the tokenizer layout. Return token kind, span, location, and raw-string context together, so parser actions use the context of the cached token.

Represent persistent scanner positions as offsets and remove pointer save/restore bookkeeping when input storage grows.
2026-09-12 14:30:00 +01:00
Pablo Galindo Salgado 2ddc218b20 gh-153569: centralize formatted-string state and source spans (#156484)
Formatted-string expressions and comments can outlive the buffer window where
scanning began. Pointer boundaries require buffer relocation to repair tokenizer
state. Record logical source ranges instead. Retain the active input window while a
formatted string is open, give each mode ownership of its comment spans, and
materialize text through shared span views.
2026-09-09 00:15:01 +01:00
Pablo Galindo Salgado 09117bc317 gh-153569: return token spans and unify decoded source storage (#156482)
Represent token boundaries as logical source offsets with explicit start
and end locations, and adapt pegen and _tokenize to consume them.

Use SourceText to own decoded input across all reader modes. Streaming
readers discard consumed windows while preserving logical offsets and
reusing the allocation. Prepared and interactive input retain their source.

Force source relocation on growth in debug builds and add coverage for
formatted-string growth, interactive input, storage reuse, and offset
limits. Scanner positions remain pointers, rebased when storage moves.
2026-09-06 21:15:44 +01:00
Serhiy StorchakaandClaude Opus 5 59a691361c gh-156894: Fix the position of syntax errors which cover a range (GH-156901)
The callers of _PyTokenizer_syntaxerror_known_range() pass columns in bytes,
but SyntaxError.offset and end_offset are columns in characters.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 14:14:13 +03:00
Stan Ulbrych d7f9c6400f gh-156689: Fix out-of-bounds read in PyAst_CheckMode() for mode='func_type' (#156697) 2026-08-31 12:49:03 +01:00
c922aa0ddd gh-72353: Continue reading from the console after ignored Ctrl+C (GH-155434)
If the console cancels a read because of Ctrl+C, but the SIGINT handler
does not raise an exception, restart the read instead of ending it as if
at end of file.

Co-authored-by: Valeriya Sinevich <valeriya.sinevich@phystech.edu>
Co-authored-by: Zackery Spytz <zspytz@gmail.com>
2026-08-29 21:05:33 +03:00
Pablo Galindo Salgado f5dbcbafae gh-153569: Unify tokenizer input readers (#156472) 2026-08-28 17:26:05 +02:00
Pablo Galindo Salgado f54fd2ab6e gh-153569: Add tokenizer source and cursor primitives (#153587) 2026-08-26 12:38:22 +01:00
Victor Stinner 079dd5ee39 gh-155742: Get PyBytes_AS_STRING() as const char* (#155751)
Use "const char*" type instead of "char*" to store
PyBytes_AS_STRING(): treat bytes objects as immutable.
2026-08-14 12:00:45 +00:00
Petr ViktorinandBartosz Sławecki a85830c7f8 gh-154775: Don't accept duplicate plus sign when matching complex number (GH-154776)
Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
2026-07-28 09:19:46 +02:00
Pablo Galindo Salgado d49e76b1eb gh-153568: Skip parser memo lookups that cannot match (#153571)
Each token now carries a small filter of the rule types present in its
memo list, so the common case of a miss no longer walks the list.
2026-07-18 18:12:38 +02:00
Pablo Galindo Salgado a0c6c4cc35 gh-153568: Cache repeated identifiers while parsing (#153577) 2026-07-18 13:25:39 +00:00
Pablo Galindo Salgado a2d3787105 gh-153569: Split tokenizer lexer into focused files (#153585) 2026-07-11 19:53:27 +01:00
Serhiy StorchakaandClaude Fable 5 1034e73f69 gh-153171: Produce specialized syntax errors for 'not' after an operator in more positions (GH-153175)
Move the invalid_factor rule from term to factor and the
invalid_arithmetic rule from shift_expr to sum, so that they are
tried at all positions where the invalid construct can occur.
Previously a generic "invalid syntax" error was reported for
constructs like "1 << 2 + not x" or "1 * + not x".

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:00:05 +03:00
sobolevn ec5f154e33 gh-150459: Fix SyntaxError message for from x lazy import y (#150877) 2026-07-04 14:17:58 +01:00
tonghuaroot (童话) 669299b62f gh-151763: Fix OOM-0013 crash when the parser or compiler fails to allocate (#151968) 2026-07-02 01:34:16 +01:00
Thomas Kowalski 2dd6e59aea gh-149689: add missing error checks in Parser/action_helpers.c (#149710) 2026-06-29 23:18:19 +00:00
Serhiy Storchaka bc3fa17c30 gh-82312: Further improvement of error messages for generating AST nodes (GH-150912)
This is a follow up of GH-17715.

* Use %T instead of _PyType_Name().
* Add the wrong type name we got for identifier and string.
2026-06-30 01:03:33 +03:00