Skip to content

Commit 6ba65b0

Browse files
committed
Python: Add support for PEP-758 exception syntax
See https://peps.python.org/pep-0758/ for more details. We implement this by extending the syntax for exceptions and exception groups so that the `type` field can now contain either an expression (which matches the old behaviour), or a comma-separated list of at least two elements (representing the new behaviour). We model the latter case using a new node type `exception_list`, which in `tsg-python` is simply mapped to a tuple. This means it matches the existing behaviour (when the tuple is surrounded by parentheses) exactly, hence we don't need to change any other code. As a consequence of this, however, we cannot directly parse the Python 2.7 syntax `except Foo, e: ...` as `except Foo as e: ...`, as this would introduce an ambiguity in the grammar. Thus, we have removed support for the (deprecated) 2.7-style syntax, and only allow `as` to indicate binding of the exception. The syntax `except Foo, e: ...` continues to be parsed (in particular, it's not suddenly a syntax error), but it will be parsed as if it were `except (Foo, e): ...`, which may not give the correct results. In principle we could extend the QL libraries to account for this case (specifically when analysing Python 2 code). In practice, however, I expect this to have a minor impact on results, and not worth the additional investment at this time.
1 parent a35fba1 commit 6ba65b0

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

python/extractor/tsg-python/python.tsg

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
(assignment !type) @assign
1313
{ let @assign.node = (ast-node @assign "Assign") }
1414

15-
[ (expression_list) (tuple) (tuple_pattern) (pattern_list) (index_expression_list) ] @tuple
15+
[ (expression_list) (tuple) (tuple_pattern) (pattern_list) (index_expression_list) (exception_list)] @tuple
1616
{ let @tuple.node = (ast-node @tuple "Tuple") }
1717

1818
(list_pattern) @list
@@ -3445,6 +3445,9 @@
34453445
(tuple element: (_) @elt) @parent
34463446

34473447
(tuple_pattern element: (_) @elt) @parent
3448+
3449+
; An exception list, as in `except A, B, C: ...`
3450+
(exception_list element: (_) @elt) @parent
34483451
]
34493452
{
34503453
edge @parent.node -> @elt.node
@@ -3480,6 +3483,7 @@
34803483
(parenthesized_expression inner: (_) @elt)
34813484
(set element: (_) @elt)
34823485
(match_sequence_pattern (_) @elt)
3486+
(exception_list element: (_) @elt)
34833487
] @seq
34843488
{
34853489
attr (@elt.node) _inherited_ctx = @seq.node

python/extractor/tsg-python/tsp/grammar.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,21 @@ module.exports = grammar({
297297
)
298298
),
299299

300+
exception_list: $ => seq(
301+
field('element', $.expression),
302+
repeat1(
303+
seq(
304+
',',
305+
field('element', $.expression))
306+
)
307+
),
308+
300309
except_clause: $ => seq(
301310
'except',
302311
optional(seq(
303-
field('type', $.expression),
312+
field('type', choice($.expression, $.exception_list)),
304313
optional(seq(
305-
choice('as', ','),
314+
'as',
306315
field('alias', $.expression)
307316
))
308317
)),
@@ -314,7 +323,7 @@ module.exports = grammar({
314323
'except',
315324
'*',
316325
seq(
317-
field('type', $.expression),
326+
field('type', choice($.expression, $.exception_list)),
318327
optional(seq(
319328
'as',
320329
field('alias', $.expression)

0 commit comments

Comments
 (0)