Skip to content

Commit 46d8a00

Browse files
authored
Add Python 3.14 support (#304)
* - transferring Python 3.14-related changes from the typing branch * - apply latest zope.meta templates * - fix test-related issues * - fix version number in Sphinx docs * - update transformer.INSPECT_ATTRIBUTES * - use a pinned commit hash for astral/setup-uv action * - remove outdated code and expand change log entry * - fix test code * - fix test code
1 parent f208c0c commit 46d8a00

File tree

13 files changed

+335
-9
lines changed

13 files changed

+335
-9
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ jobs:
4747
with:
4848
persist-credentials: false
4949
- name: Install uv + caching
50-
uses: astral-sh/setup-uv@v6
50+
# astral/setup-uv@7
51+
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d
5152
with:
5253
enable-cache: true
5354
cache-dependency-glob: |

.meta.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
33
[meta]
44
template = "pure-python"
5-
commit-id = "7dcce077"
5+
commit-id = "72252845"
66

77
[python]
88
with-pypy = false
@@ -55,7 +55,7 @@ coverage-setenv = [
5555
]
5656

5757
[coverage]
58-
fail-under = 97.3
58+
fail-under = 97.2
5959

6060
[isort]
6161
additional-sources = "{toxinidir}/tests"

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
minimum_pre_commit_version: '3.6'
44
repos:
55
- repo: https://github.com/pycqa/isort
6-
rev: "6.1.0"
6+
rev: "7.0.0"
77
hooks:
88
- id: isort
99
- repo: https://github.com/hhatto/autopep8
@@ -12,7 +12,7 @@ repos:
1212
- id: autopep8
1313
args: [--in-place, --aggressive, --aggressive]
1414
- repo: https://github.com/asottile/pyupgrade
15-
rev: v3.20.0
15+
rev: v3.21.0
1616
hooks:
1717
- id: pyupgrade
1818
args: [--py39-plus]

CHANGES.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Changes
44
8.1 (unreleased)
55
----------------
66

7-
- Nothing changed yet.
7+
- Allow to use the package with Python 3.14 including t-string support.
88

99

1010
8.1a1.dev0 (2025-03-20)

docs/conf.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060
# built documents.
6161
#
6262
# The short X.Y version.
63-
version = '7.5'
63+
version = '8.1'
6464
# The full version, including alpha/beta/rc tags.
65-
release = '7.5'
65+
release = '8.1'
6666

6767
# The language for content autogenerated by Sphinx. Refer to documentation
6868
# for a list of supported languages.
@@ -117,6 +117,7 @@
117117
'python311': ('https://docs.python.org/3.11', None),
118118
'python312': ('https://docs.python.org/3.12', None),
119119
'python313': ('https://docs.python.org/3.13', None),
120+
'python314': ('https://docs.python.org/3.14', None),
120121
}
121122

122123
# Options for sphinx.ext.todo:
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
-- Python 3.14 AST
2+
-- ASDL's 4 builtin types are:
3+
-- identifier, int, string, constant
4+
5+
module Python version "3.14"
6+
{
7+
mod = Module(stmt* body, type_ignore* type_ignores)
8+
| Interactive(stmt* body)
9+
| Expression(expr body)
10+
| FunctionType(expr* argtypes, expr returns)
11+
12+
stmt = FunctionDef(identifier name,
13+
arguments args,
14+
stmt* body,
15+
expr* decorator_list,
16+
expr? returns,
17+
string? type_comment,
18+
type_param* type_params)
19+
| AsyncFunctionDef(identifier name,
20+
arguments args,
21+
stmt* body,
22+
expr* decorator_list,
23+
expr? returns,
24+
string? type_comment,
25+
type_param* type_params)
26+
27+
| ClassDef(identifier name,
28+
expr* bases,
29+
keyword* keywords,
30+
stmt* body,
31+
expr* decorator_list,
32+
type_param* type_params)
33+
| Return(expr? value)
34+
35+
| Delete(expr* targets)
36+
| Assign(expr* targets, expr value, string? type_comment)
37+
| TypeAlias(expr name, type_param* type_params, expr value)
38+
| AugAssign(expr target, operator op, expr value)
39+
-- 'simple' indicates that we annotate simple name without parens
40+
| AnnAssign(expr target, expr annotation, expr? value, int simple)
41+
42+
-- use 'orelse' because else is a keyword in target languages
43+
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
44+
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
45+
| While(expr test, stmt* body, stmt* orelse)
46+
| If(expr test, stmt* body, stmt* orelse)
47+
| With(withitem* items, stmt* body, string? type_comment)
48+
| AsyncWith(withitem* items, stmt* body, string? type_comment)
49+
50+
| Match(expr subject, match_case* cases)
51+
52+
| Raise(expr? exc, expr? cause)
53+
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
54+
| TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
55+
| Assert(expr test, expr? msg)
56+
57+
| Import(alias* names)
58+
| ImportFrom(identifier? module, alias* names, int? level)
59+
60+
| Global(identifier* names)
61+
| Nonlocal(identifier* names)
62+
| Expr(expr value)
63+
| Pass
64+
| Break
65+
| Continue
66+
67+
-- col_offset is the byte offset in the utf8 string the parser uses
68+
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
69+
70+
-- BoolOp() can use left & right?
71+
expr = BoolOp(boolop op, expr* values)
72+
| NamedExpr(expr target, expr value)
73+
| BinOp(expr left, operator op, expr right)
74+
| UnaryOp(unaryop op, expr operand)
75+
| Lambda(arguments args, expr body)
76+
| IfExp(expr test, expr body, expr orelse)
77+
| Dict(expr?* keys, expr* values)
78+
| Set(expr* elts)
79+
| ListComp(expr elt, comprehension* generators)
80+
| SetComp(expr elt, comprehension* generators)
81+
| DictComp(expr key, expr value, comprehension* generators)
82+
| GeneratorExp(expr elt, comprehension* generators)
83+
-- the grammar constrains where yield expressions can occur
84+
| Await(expr value)
85+
| Yield(expr? value)
86+
| YieldFrom(expr value)
87+
-- need sequences for compare to distinguish between
88+
-- x < 4 < 3 and (x < 4) < 3
89+
| Compare(expr left, cmpop* ops, expr* comparators)
90+
| Call(expr func, expr* args, keyword* keywords)
91+
| FormattedValue(expr value, int conversion, expr? format_spec)
92+
| Interpolation(expr value, constant str, int conversion, expr? format_spec)
93+
| JoinedStr(expr* values)
94+
| TemplateStr(expr* values)
95+
| Constant(constant value, string? kind)
96+
97+
-- the following expression can appear in assignment context
98+
| Attribute(expr value, identifier attr, expr_context ctx)
99+
| Subscript(expr value, expr slice, expr_context ctx)
100+
| Starred(expr value, expr_context ctx)
101+
| Name(identifier id, expr_context ctx)
102+
| List(expr* elts, expr_context ctx)
103+
| Tuple(expr* elts, expr_context ctx)
104+
105+
-- can appear only in Subscript
106+
| Slice(expr? lower, expr? upper, expr? step)
107+
108+
-- col_offset is the byte offset in the utf8 string the parser uses
109+
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
110+
111+
expr_context = Load
112+
| Store
113+
| Del
114+
115+
boolop = And
116+
| Or
117+
118+
operator = Add
119+
| Sub
120+
| Mult
121+
| MatMult
122+
| Div
123+
| Mod
124+
| Pow
125+
| LShift
126+
| RShift
127+
| BitOr
128+
| BitXor
129+
| BitAnd
130+
| FloorDiv
131+
132+
unaryop = Invert
133+
| Not
134+
| UAdd
135+
| USub
136+
137+
cmpop = Eq
138+
| NotEq
139+
| Lt
140+
| LtE
141+
| Gt
142+
| GtE
143+
| Is
144+
| IsNot
145+
| In
146+
| NotIn
147+
148+
comprehension = (expr target, expr iter, expr* ifs, int is_async)
149+
150+
excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
151+
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
152+
153+
arguments = (arg* posonlyargs,
154+
arg* args,
155+
arg? vararg,
156+
arg* kwonlyargs,
157+
expr* kw_defaults,
158+
arg? kwarg,
159+
expr* defaults)
160+
161+
arg = (identifier arg, expr? annotation, string? type_comment)
162+
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
163+
164+
-- keyword arguments supplied to call (NULL identifier for **kwargs)
165+
keyword = (identifier? arg, expr value)
166+
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
167+
168+
-- import name with optional 'as' alias.
169+
alias = (identifier name, identifier? asname)
170+
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
171+
172+
withitem = (expr context_expr, expr? optional_vars)
173+
174+
match_case = (pattern pattern, expr? guard, stmt* body)
175+
176+
pattern = MatchValue(expr value)
177+
| MatchSingleton(constant value)
178+
| MatchSequence(pattern* patterns)
179+
| MatchMapping(expr* keys, pattern* patterns, identifier? rest)
180+
| MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)
181+
182+
| MatchStar(identifier? name)
183+
-- The optional "rest" MatchMapping parameter handles capturing extra mapping keys
184+
185+
| MatchAs(pattern? pattern, identifier? name)
186+
| MatchOr(pattern* patterns)
187+
188+
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
189+
190+
type_ignore = TypeIgnore(int lineno, string tag)
191+
192+
type_param = TypeVar(identifier name, expr? bound, expr? default_value)
193+
| ParamSpec(identifier name, expr? default_value)
194+
| TypeVarTuple(identifier name, expr? default_value)
195+
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
196+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Changes from Python 3.13 to Python 3.14
2+
---------------------------------------
3+
4+
.. literalinclude:: ast/python3_14.ast
5+
:diff: ast/python3_13.ast

docs/contributing/index.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ A (modified style) Copy of all Abstract Grammar Definitions for the Python versi
103103
changes_from310to311
104104
changes_from311to312
105105
changes_from312to313
106+
changes_from313to314
106107

107108
.. _understand:
108109

@@ -235,6 +236,7 @@ Technical Backgrounds - Links to External Documentation
235236

236237
* AST Grammar of Python (`Status of Python Versions`_)
237238

239+
* `Python 3.14 AST`_ (EOL 2030-10)
238240
* `Python 3.13 AST`_ (EOL 2029-10)
239241
* `Python 3.12 AST`_ (EOL 2028-10)
240242
* `Python 3.11 AST`_ (EOL 2027-10)
@@ -257,6 +259,8 @@ Todos
257259
258260
.. _`What's new in Python`: https://docs.python.org/3/whatsnew/
259261

262+
.. _`What's new in Python 3.14`: https://docs.python.org/3.14/whatsnew/3.14.html
263+
260264
.. _`What's new in Python 3.13`: https://docs.python.org/3.13/whatsnew/3.13.html
261265

262266
.. _`What's new in Python 3.12`: https://docs.python.org/3.12/whatsnew/3.12.html
@@ -281,6 +285,8 @@ Todos
281285

282286
.. _`Python 3 AST`: https://docs.python.org/3/library/ast.html#abstract-grammar
283287

288+
.. _`Python 3.14 AST`: https://docs.python.org/3.14/library/ast.html#abstract-grammar
289+
284290
.. _`Python 3.13 AST`: https://docs.python.org/3.13/library/ast.html#abstract-grammar
285291

286292
.. _`Python 3.12 AST`: https://docs.python.org/3.12/library/ast.html#abstract-grammar

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ branch = true
1414
source = ["RestrictedPython"]
1515

1616
[tool.coverage.report]
17-
fail_under = 97.3
17+
fail_under = 97.2
1818
precision = 2
1919
ignore_errors = true
2020
show_missing = true

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def read(*rnames):
4444
'Programming Language :: Python :: 3.11',
4545
'Programming Language :: Python :: 3.12',
4646
'Programming Language :: Python :: 3.13',
47+
'Programming Language :: Python :: 3.14',
4748
'Programming Language :: Python :: Implementation :: CPython',
4849
'Topic :: Security',
4950
],

0 commit comments

Comments
 (0)