Changes from Python 3.14 to Python 3.15¶
--- /home/docs/checkouts/readthedocs.org/user_builds/restrictedpython/checkouts/stable/docs/contributing/ast/python3_14.ast
+++ /home/docs/checkouts/readthedocs.org/user_builds/restrictedpython/checkouts/stable/docs/contributing/ast/python3_15.ast
@@ -1,8 +1,8 @@
--- Python 3.14 AST
+-- Python 3.15 AST
-- ASDL's 4 builtin types are:
-- identifier, int, string, constant
-module Python version "3.14"
+module Python version "3.15"
{
mod = Module(stmt* body, type_ignore* type_ignores)
| Interactive(stmt* body)
@@ -54,8 +54,8 @@
| TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
| Assert(expr test, expr? msg)
- | Import(alias* names)
- | ImportFrom(identifier? module, alias* names, int? level)
+ | Import(alias* names, int? is_lazy)
+ | ImportFrom(identifier? module, alias* names, int? level, int? is_lazy)
| Global(identifier* names)
| Nonlocal(identifier* names)
@@ -78,7 +78,7 @@
| Set(expr* elts)
| ListComp(expr elt, comprehension* generators)
| SetComp(expr elt, comprehension* generators)
- | DictComp(expr key, expr value, comprehension* generators)
+ | DictComp(expr key, expr? value, comprehension* generators)
| GeneratorExp(expr elt, comprehension* generators)
-- the grammar constrains where yield expressions can occur
| Await(expr value)
Security audit of the Python 3.15 changes¶
- Lazy imports (PEP 810)
lazy importstatements do not introduce a new AST node. They only add a new fieldis_lazyto the existingImportandImportFromnodes, so the default-deny mechanism ofRestrictingNodeTransformer.generic_visitdoes not apply to them. At run time a lazy import is resolved through the new__lazy_import__builtin instead of__import__, thus bypassing a guarded__import__. Therefore lazy imports are explicitly not allowed. Assigning__lazy_modules__was already blocked by the rule denying names which start with an underscore.- Unpacking in comprehensions (PEP 798)
[*x for x in seq],{*x for x in seq},(*x for x in seq)and{**x for x in seq}reuse the existingStarrednode (resp. aDictCompnode without a value), so they compiled silently. The unpacked value is iterated by the bytecode without calling the_getiter_guard — unlike the equivalent nested comprehension[y for x in seq for y in x]. Therefore unpacking in comprehensions is explicitly not allowed.- Unary
+inmatchliteral patterns No action needed as the
matchstatement is not allowed in RestrictedPython.- New builtins
frozendict(PEP 814) andsentinel(PEP 661) No action needed as
safe_builtinsis an allow list, so the new builtins are not available in restricted code.- New
inspectattributesgi_state,cr_stateandag_state They only reveal the state of a (async) generator resp. coroutine as a string, so they are treated like the other harmless attributes (e. g.
gi_running) and remain accessible. ReviewingINSPECT_ATTRIBUTESalso revealed that the attributes of asynchronous generator objects (ag_await,ag_frame,ag_code) were missing from the list; they are now blocked.- Removed
astclasses (ast.Num,ast.Str,ast.Bytes,ast.NameConstant,ast.Ellipsis) No action needed as they are no longer used by RestrictedPython.