Skip to content

Commit b89f45a

Browse files
Updated for Python 3.13
1 parent 9d479cd commit b89f45a

File tree

2 files changed

+119
-25
lines changed

2 files changed

+119
-25
lines changed

notebooks/PythonFuzzer.ipynb

+113-22
Original file line numberDiff line numberDiff line change
@@ -1534,14 +1534,31 @@
15341534
" # https://docs.python.org/3/reference/lexical_analysis.html#identifiers\n",
15351535
"\n",
15361536
" # Function Calls\n",
1537-
" '<Call>': [ 'Call(func=<func>, args=<expr_list>, keywords=<keyword_list>)' ],\n",
1538-
" '<func>': [ '<expr>' ], # Actually <Expr>, but this is more readable and parses 90%\n",
1537+
" '<Call>': [ 'Call(func=<func><args_param><keywords_param>)' ],\n",
1538+
" '<args_param>': [ ', args=<expr_list>' ],\n",
1539+
" '<keywords_param>': [ ', keywords=<keyword_list>' ],\n",
1540+
" '<func>': [ '<expr>' ], # Actually <Expr>, but this is more readable and parses 90%\n",
15391541
" '<keyword_list>': [ '[<keywords>?]' ],\n",
15401542
" '<keywords>': [ '<keyword>', '<keyword>, <keywords>' ],\n",
15411543
" '<keyword>': [ 'keyword(arg=<identifier>, value=<expr>)' ]\n",
15421544
"})"
15431545
]
15441546
},
1547+
{
1548+
"cell_type": "code",
1549+
"execution_count": null,
1550+
"id": "4505b2fe",
1551+
"metadata": {},
1552+
"outputs": [],
1553+
"source": [
1554+
"# do import this unconditionally\n",
1555+
"if sys.version_info >= (3, 13):\n",
1556+
" PYTHON_AST_IDS_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_IDS_GRAMMAR, {\n",
1557+
" # As of 3.13, args and keywords parameters are optional\n",
1558+
" '<Call>': [ 'Call(func=<func><args_param>?<keywords_param>?)' ],\n",
1559+
" })"
1560+
]
1561+
},
15451562
{
15461563
"cell_type": "code",
15471564
"execution_count": null,
@@ -1615,7 +1632,8 @@
16151632
"metadata": {},
16161633
"outputs": [],
16171634
"source": [
1618-
"call_str = ast.dump(ast.parse('open()').body[0].value) # type: ignore\n",
1635+
"call_str = ast.dump(ast.parse('open(\"foo.txt\", \"r\")').body[0].value) # type: ignore\n",
1636+
"print(call_str)\n",
16191637
"call_solver = ISLaSolver(ast_ids_grammar)\n",
16201638
"assert call_solver.check(call_str)"
16211639
]
@@ -1880,7 +1898,10 @@
18801898
" ],\n",
18811899
"\n",
18821900
" '<If>': [\n",
1883-
" 'If(test=<expr>, body=<nonempty_stmt_list>, orelse=<stmt_list>)'\n",
1901+
" 'If(test=<expr>, body=<nonempty_stmt_list><orelse_param>)'\n",
1902+
" ],\n",
1903+
" '<orelse_param>': [\n",
1904+
" ', orelse=<stmt_list>'\n",
18841905
" ],\n",
18851906
"\n",
18861907
" '<With>': [\n",
@@ -1909,11 +1930,29 @@
19091930
" '<Break>': [ 'Break()' ],\n",
19101931
" '<Continue>': [ 'Continue()']\n",
19111932
"\n",
1912-
" # FIXME: A few more: AsyncFor, AsyncWith, Match, Try, TryStar, With\n",
1933+
" # FIXME: A few more: AsyncFor, AsyncWith, Match, Try, TryStar\n",
19131934
" # Import, ImportFrom, Global, Nonlocal...\n",
19141935
"})"
19151936
]
19161937
},
1938+
{
1939+
"cell_type": "code",
1940+
"execution_count": null,
1941+
"id": "5db1c800",
1942+
"metadata": {},
1943+
"outputs": [],
1944+
"source": [
1945+
"# do import this unconditionally\n",
1946+
"if sys.version_info >= (3, 13):\n",
1947+
" PYTHON_AST_STMTS_GRAMMAR: Grammar = \\\n",
1948+
" extend_grammar(PYTHON_AST_STMTS_GRAMMAR, {\n",
1949+
" # As of 3.13, orelse is optional\n",
1950+
" '<If>': [\n",
1951+
" 'If(test=<expr>, body=<nonempty_stmt_list><orelse_param>?)'\n",
1952+
" ],\n",
1953+
" })"
1954+
]
1955+
},
19171956
{
19181957
"cell_type": "code",
19191958
"execution_count": null,
@@ -1969,6 +2008,7 @@
19692008
"source": [
19702009
"python_ast_stmts_grammar = convert_ebnf_grammar(PYTHON_AST_STMTS_GRAMMAR)\n",
19712010
"with_tree_str = ast.dump(with_tree.body[0]) # get the `With(...)` subtree\n",
2011+
"print(with_tree_str)\n",
19722012
"with_solver = ISLaSolver(python_ast_stmts_grammar)\n",
19732013
"assert with_solver.check(with_tree_str)"
19742014
]
@@ -2031,11 +2071,28 @@
20312071
" '<stmt>': PYTHON_AST_STMTS_GRAMMAR['<stmt>'] + [ '<FunctionDef>' ],\n",
20322072
"\n",
20332073
" '<FunctionDef>': [\n",
2034-
" 'FunctionDef(name=<identifier>, args=<arguments>, body=<nonempty_stmt_list>, decorator_list=<expr_list><returns>?<type_comment>?)'\n",
2074+
" 'FunctionDef(name=<identifier>, args=<arguments>, body=<nonempty_stmt_list><decorator_list_param><returns>?<type_comment>?)'\n",
2075+
" ],\n",
2076+
" '<decorator_list_param>': [\n",
2077+
" ', decorator_list=<expr_list>'\n",
20352078
" ],\n",
2079+
"\n",
20362080
" '<arguments>': [\n",
2037-
" 'arguments(posonlyargs=<arg_list>, args=<arg_list><vararg>?, kwonlyargs=<arg_list>, kw_defaults=<expr_list><kwarg>?, defaults=<expr_list>)'\n",
2081+
" 'arguments(<posonlyargs_param>args=<arg_list><vararg>?<kwonlyargs_param><kw_defaults_param><kwarg>?<defaults_param>)'\n",
2082+
" ],\n",
2083+
" '<posonlyargs_param>': [\n",
2084+
" 'posonlyargs=<arg_list>, '\n",
2085+
" ],\n",
2086+
" '<kwonlyargs_param>': [\n",
2087+
" ', kwonlyargs=<arg_list>'\n",
2088+
" ],\n",
2089+
" '<kw_defaults_param>': [\n",
2090+
" ', kw_defaults=<expr_list>'\n",
20382091
" ],\n",
2092+
" '<defaults_param>': [\n",
2093+
" ', defaults=<expr_list>'\n",
2094+
" ],\n",
2095+
"\n",
20392096
"\n",
20402097
" '<arg_list>': [ '[<args>?]' ],\n",
20412098
" '<args>': [ '<arg>', '<arg>, <arg>' ],\n",
@@ -2057,16 +2114,6 @@
20572114
"In Python 3.12 and later, function definitions also have a `type_param` field:"
20582115
]
20592116
},
2060-
{
2061-
"cell_type": "code",
2062-
"execution_count": null,
2063-
"id": "ac5c79cf",
2064-
"metadata": {},
2065-
"outputs": [],
2066-
"source": [
2067-
"import sys"
2068-
]
2069-
},
20702117
{
20712118
"cell_type": "code",
20722119
"execution_count": null,
@@ -2078,7 +2125,7 @@
20782125
"if sys.version_info >= (3, 12):\n",
20792126
" PYTHON_AST_DEFS_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_DEFS_GRAMMAR, {\n",
20802127
" '<FunctionDef>': [\n",
2081-
" 'FunctionDef(name=<identifier>, args=<arguments>, body=<nonempty_stmt_list>, decorator_list=<expr_list><returns>?<type_comment>?<type_params>?)'\n",
2128+
" 'FunctionDef(name=<identifier>, args=<arguments>, body=<nonempty_stmt_list><decorator_list_param><returns>?<type_comment>?<type_params>?)'\n",
20822129
" ],\n",
20832130
" '<type_params>': [\n",
20842131
" ', type_params=<type_param_list>',\n",
@@ -2097,6 +2144,33 @@
20972144
" })"
20982145
]
20992146
},
2147+
{
2148+
"cell_type": "markdown",
2149+
"id": "02959d01",
2150+
"metadata": {},
2151+
"source": [
2152+
"In Python 3.13 and later, several `<FunctionDef>` and `<arguments>` attributes are optional:"
2153+
]
2154+
},
2155+
{
2156+
"cell_type": "code",
2157+
"execution_count": null,
2158+
"id": "ee08d09d",
2159+
"metadata": {},
2160+
"outputs": [],
2161+
"source": [
2162+
"# do import this unconditionally\n",
2163+
"if sys.version_info >= (3, 13):\n",
2164+
" PYTHON_AST_DEFS_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_DEFS_GRAMMAR, {\n",
2165+
" '<FunctionDef>': [\n",
2166+
" 'FunctionDef(name=<identifier>, args=<arguments>, body=<nonempty_stmt_list><decorator_list_param>?<returns>?<type_comment>?<type_params>?)'\n",
2167+
" ],\n",
2168+
" '<arguments>': [\n",
2169+
" 'arguments(<posonlyargs_param>?args=<arg_list><vararg>?<kwonlyargs_param>?<kw_defaults_param>?<kwarg>?<defaults_param>?)'\n",
2170+
" ],\n",
2171+
" })"
2172+
]
2173+
},
21002174
{
21012175
"cell_type": "code",
21022176
"execution_count": null,
@@ -2155,14 +2229,31 @@
21552229
"PYTHON_AST_MODULE_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_DEFS_GRAMMAR, {\n",
21562230
" '<start>': [ '<mod>' ],\n",
21572231
" '<mod>': [ '<Module>' ],\n",
2158-
" '<Module>': [ 'Module(body=<nonempty_stmt_list>, type_ignores=<type_ignore_list>)'],\n",
2232+
" '<Module>': [ 'Module(body=<nonempty_stmt_list><type_ignore_param>)'],\n",
21592233
"\n",
2234+
" '<type_ignore_param>': [ ', type_ignores=<type_ignore_list>' ],\n",
21602235
" '<type_ignore_list>': [ '[<type_ignores>?]' ],\n",
21612236
" '<type_ignores>': [ '<type_ignore>', '<type_ignore>, <type_ignore>' ],\n",
21622237
" '<type_ignore>': [ 'TypeIgnore(lineno=<integer>, tag=<string>)' ],\n",
21632238
"})"
21642239
]
21652240
},
2241+
{
2242+
"cell_type": "code",
2243+
"execution_count": null,
2244+
"id": "ef453b00",
2245+
"metadata": {},
2246+
"outputs": [],
2247+
"source": [
2248+
"# do import this unconditionally\n",
2249+
"if sys.version_info >= (3, 13):\n",
2250+
" PYTHON_AST_MODULE_GRAMMAR: Grammar = \\\n",
2251+
" extend_grammar(PYTHON_AST_MODULE_GRAMMAR, {\n",
2252+
" # As of 3.13, the type_ignore parameter is optional\n",
2253+
" '<Module>': [ 'Module(body=<nonempty_stmt_list><type_ignore_param>?)'],\n",
2254+
" })"
2255+
]
2256+
},
21662257
{
21672258
"cell_type": "code",
21682259
"execution_count": null,
@@ -2751,7 +2842,7 @@
27512842
"outputs": [],
27522843
"source": [
27532844
"solver = ISLaSolver(python_ast_grammar)\n",
2754-
"solver.check(sum_str)"
2845+
"assert solver.check(sum_str)"
27552846
]
27562847
},
27572848
{
@@ -4180,7 +4271,7 @@
41804271
],
41814272
"metadata": {
41824273
"kernelspec": {
4183-
"display_name": "Python 3 (ipykernel)",
4274+
"display_name": "python3.11",
41844275
"language": "python",
41854276
"name": "python3"
41864277
},
@@ -4194,7 +4285,7 @@
41944285
"name": "python",
41954286
"nbconvert_exporter": "python",
41964287
"pygments_lexer": "ipython3",
4197-
"version": "3.12.1"
4288+
"version": "3.11.10"
41984289
}
41994290
},
42004291
"nbformat": 4,

notebooks/ReleaseNotes.ipynb

+6-3
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@
3535
"cell_type": "markdown",
3636
"metadata": {},
3737
"source": [
38-
"## Version 1.2.2 (released 2024-11-09)\n",
38+
"## Version 1.2.2 (released 2024-11-10)\n",
3939
"\n",
40+
"* Adapted the code to work with Python 3.13:\n",
41+
" - Work around an error in the `showast` module\n",
42+
" - Extended the [chapter on Compiler Testing](PythonFuzzer.ipynb) to work with Python 3.13 and later\n",
43+
" - Added automatic Python 3.13 tests into our workflow\n",
4044
"* Fix: Outputting code coverage using the `Coverage` class would prefix _covered_ code with `#`, rather than _uncovered_ code as should be. This has been fixed.\n",
41-
"* Work around an error in the `showast` module, occurring in notebooks running Python 3.12 and later\n",
42-
"* Lots of additional typos fixed, thanks to Sergey Bronnikov!"
45+
"* Lots of additional typos fixed, [thanks to Sergey Bronnikov](https://github.com/uds-se/fuzzingbook/pull/181)."
4346
]
4447
},
4548
{

0 commit comments

Comments
 (0)