mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
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.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
(assignment !type) @assign
|
||||
{ let @assign.node = (ast-node @assign "Assign") }
|
||||
|
||||
[ (expression_list) (tuple) (tuple_pattern) (pattern_list) (index_expression_list) ] @tuple
|
||||
[ (expression_list) (tuple) (tuple_pattern) (pattern_list) (index_expression_list) (exception_list)] @tuple
|
||||
{ let @tuple.node = (ast-node @tuple "Tuple") }
|
||||
|
||||
(list_pattern) @list
|
||||
@@ -3445,6 +3445,9 @@
|
||||
(tuple element: (_) @elt) @parent
|
||||
|
||||
(tuple_pattern element: (_) @elt) @parent
|
||||
|
||||
; An exception list, as in `except A, B, C: ...`
|
||||
(exception_list element: (_) @elt) @parent
|
||||
]
|
||||
{
|
||||
edge @parent.node -> @elt.node
|
||||
@@ -3480,6 +3483,7 @@
|
||||
(parenthesized_expression inner: (_) @elt)
|
||||
(set element: (_) @elt)
|
||||
(match_sequence_pattern (_) @elt)
|
||||
(exception_list element: (_) @elt)
|
||||
] @seq
|
||||
{
|
||||
attr (@elt.node) _inherited_ctx = @seq.node
|
||||
|
||||
@@ -297,12 +297,21 @@ module.exports = grammar({
|
||||
)
|
||||
),
|
||||
|
||||
exception_list: $ => seq(
|
||||
field('element', $.expression),
|
||||
repeat1(
|
||||
seq(
|
||||
',',
|
||||
field('element', $.expression))
|
||||
)
|
||||
),
|
||||
|
||||
except_clause: $ => seq(
|
||||
'except',
|
||||
optional(seq(
|
||||
field('type', $.expression),
|
||||
field('type', choice($.expression, $.exception_list)),
|
||||
optional(seq(
|
||||
choice('as', ','),
|
||||
'as',
|
||||
field('alias', $.expression)
|
||||
))
|
||||
)),
|
||||
@@ -314,7 +323,7 @@ module.exports = grammar({
|
||||
'except',
|
||||
'*',
|
||||
seq(
|
||||
field('type', $.expression),
|
||||
field('type', choice($.expression, $.exception_list)),
|
||||
optional(seq(
|
||||
'as',
|
||||
field('alias', $.expression)
|
||||
|
||||
Reference in New Issue
Block a user