diff --git a/notebooks/PythonFuzzer.ipynb b/notebooks/PythonFuzzer.ipynb index 2fceda45a..b140d8139 100644 --- a/notebooks/PythonFuzzer.ipynb +++ b/notebooks/PythonFuzzer.ipynb @@ -1534,14 +1534,31 @@ " # https://docs.python.org/3/reference/lexical_analysis.html#identifiers\n", "\n", " # Function Calls\n", - " '': [ 'Call(func=, args=, keywords=)' ],\n", - " '': [ '' ], # Actually , but this is more readable and parses 90%\n", + " '': [ 'Call(func=)' ],\n", + " '': [ ', args=' ],\n", + " '': [ ', keywords=' ],\n", + " '': [ '' ], # Actually , but this is more readable and parses 90%\n", " '': [ '[?]' ],\n", " '': [ '', ', ' ],\n", " '': [ 'keyword(arg=, value=)' ]\n", "})" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "4505b2fe", + "metadata": {}, + "outputs": [], + "source": [ + "# do import this unconditionally\n", + "if sys.version_info >= (3, 13):\n", + " PYTHON_AST_IDS_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_IDS_GRAMMAR, {\n", + " # As of 3.13, args and keywords parameters are optional\n", + " '': [ 'Call(func=??)' ],\n", + " })" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1615,7 +1632,8 @@ "metadata": {}, "outputs": [], "source": [ - "call_str = ast.dump(ast.parse('open()').body[0].value) # type: ignore\n", + "call_str = ast.dump(ast.parse('open(\"foo.txt\", \"r\")').body[0].value) # type: ignore\n", + "print(call_str)\n", "call_solver = ISLaSolver(ast_ids_grammar)\n", "assert call_solver.check(call_str)" ] @@ -1880,7 +1898,10 @@ " ],\n", "\n", " '': [\n", - " 'If(test=, body=, orelse=)'\n", + " 'If(test=, body=)'\n", + " ],\n", + " '': [\n", + " ', orelse='\n", " ],\n", "\n", " '': [\n", @@ -1909,11 +1930,29 @@ " '': [ 'Break()' ],\n", " '': [ 'Continue()']\n", "\n", - " # FIXME: A few more: AsyncFor, AsyncWith, Match, Try, TryStar, With\n", + " # FIXME: A few more: AsyncFor, AsyncWith, Match, Try, TryStar\n", " # Import, ImportFrom, Global, Nonlocal...\n", "})" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "5db1c800", + "metadata": {}, + "outputs": [], + "source": [ + "# do import this unconditionally\n", + "if sys.version_info >= (3, 13):\n", + " PYTHON_AST_STMTS_GRAMMAR: Grammar = \\\n", + " extend_grammar(PYTHON_AST_STMTS_GRAMMAR, {\n", + " # As of 3.13, orelse is optional\n", + " '': [\n", + " 'If(test=, body=?)'\n", + " ],\n", + " })" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1969,6 +2008,7 @@ "source": [ "python_ast_stmts_grammar = convert_ebnf_grammar(PYTHON_AST_STMTS_GRAMMAR)\n", "with_tree_str = ast.dump(with_tree.body[0]) # get the `With(...)` subtree\n", + "print(with_tree_str)\n", "with_solver = ISLaSolver(python_ast_stmts_grammar)\n", "assert with_solver.check(with_tree_str)" ] @@ -2031,11 +2071,28 @@ " '': PYTHON_AST_STMTS_GRAMMAR[''] + [ '' ],\n", "\n", " '': [\n", - " 'FunctionDef(name=, args=, body=, decorator_list=??)'\n", + " 'FunctionDef(name=, args=, body=??)'\n", + " ],\n", + " '': [\n", + " ', decorator_list='\n", " ],\n", + "\n", " '': [\n", - " 'arguments(posonlyargs=, args=?, kwonlyargs=, kw_defaults=?, defaults=)'\n", + " 'arguments(args=??)'\n", + " ],\n", + " '': [\n", + " 'posonlyargs=, '\n", + " ],\n", + " '': [\n", + " ', kwonlyargs='\n", + " ],\n", + " '': [\n", + " ', kw_defaults='\n", " ],\n", + " '': [\n", + " ', defaults='\n", + " ],\n", + "\n", "\n", " '': [ '[?]' ],\n", " '': [ '', ', ' ],\n", @@ -2057,16 +2114,6 @@ "In Python 3.12 and later, function definitions also have a `type_param` field:" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac5c79cf", - "metadata": {}, - "outputs": [], - "source": [ - "import sys" - ] - }, { "cell_type": "code", "execution_count": null, @@ -2078,7 +2125,7 @@ "if sys.version_info >= (3, 12):\n", " PYTHON_AST_DEFS_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_DEFS_GRAMMAR, {\n", " '': [\n", - " 'FunctionDef(name=, args=, body=, decorator_list=???)'\n", + " 'FunctionDef(name=, args=, body=???)'\n", " ],\n", " '': [\n", " ', type_params=',\n", @@ -2097,6 +2144,33 @@ " })" ] }, + { + "cell_type": "markdown", + "id": "02959d01", + "metadata": {}, + "source": [ + "In Python 3.13 and later, several `` and `` attributes are optional:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee08d09d", + "metadata": {}, + "outputs": [], + "source": [ + "# do import this unconditionally\n", + "if sys.version_info >= (3, 13):\n", + " PYTHON_AST_DEFS_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_DEFS_GRAMMAR, {\n", + " '': [\n", + " 'FunctionDef(name=, args=, body=????)'\n", + " ],\n", + " '': [\n", + " 'arguments(?args=?????)'\n", + " ],\n", + " })" + ] + }, { "cell_type": "code", "execution_count": null, @@ -2155,14 +2229,31 @@ "PYTHON_AST_MODULE_GRAMMAR: Grammar = extend_grammar(PYTHON_AST_DEFS_GRAMMAR, {\n", " '': [ '' ],\n", " '': [ '' ],\n", - " '': [ 'Module(body=, type_ignores=)'],\n", + " '': [ 'Module(body=)'],\n", "\n", + " '': [ ', type_ignores=' ],\n", " '': [ '[?]' ],\n", " '': [ '', ', ' ],\n", " '': [ 'TypeIgnore(lineno=, tag=)' ],\n", "})" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef453b00", + "metadata": {}, + "outputs": [], + "source": [ + "# do import this unconditionally\n", + "if sys.version_info >= (3, 13):\n", + " PYTHON_AST_MODULE_GRAMMAR: Grammar = \\\n", + " extend_grammar(PYTHON_AST_MODULE_GRAMMAR, {\n", + " # As of 3.13, the type_ignore parameter is optional\n", + " '': [ 'Module(body=?)'],\n", + " })" + ] + }, { "cell_type": "code", "execution_count": null, @@ -2751,7 +2842,7 @@ "outputs": [], "source": [ "solver = ISLaSolver(python_ast_grammar)\n", - "solver.check(sum_str)" + "assert solver.check(sum_str)" ] }, { @@ -4180,7 +4271,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "python3.11", "language": "python", "name": "python3" }, @@ -4194,7 +4285,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.1" + "version": "3.11.10" } }, "nbformat": 4, diff --git a/notebooks/ReleaseNotes.ipynb b/notebooks/ReleaseNotes.ipynb index 6c2011d98..38ed0883a 100644 --- a/notebooks/ReleaseNotes.ipynb +++ b/notebooks/ReleaseNotes.ipynb @@ -35,11 +35,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Version 1.2.2 (released 2024-11-09)\n", + "## Version 1.2.2 (released 2024-11-10)\n", "\n", + "* Adapted the code to work with Python 3.13:\n", + " - Work around an error in the `showast` module\n", + " - Extended the [chapter on Compiler Testing](PythonFuzzer.ipynb) to work with Python 3.13 and later\n", + " - Added automatic Python 3.13 tests into our workflow\n", "* 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", - "* Work around an error in the `showast` module, occurring in notebooks running Python 3.12 and later\n", - "* Lots of additional typos fixed, thanks to Sergey Bronnikov!" + "* Lots of additional typos fixed, [thanks to Sergey Bronnikov](https://github.com/uds-se/fuzzingbook/pull/181)." ] }, {