mirror of
https://github.com/github/codeql.git
synced 2026-05-27 17:41:24 +02:00
Implements `AstSig::Parameter` and `callableGetParameter(c, i)` in
`AstNodeImpl.qll`, following the C# template
(`csharp/.../ControlFlowGraph.qll:147-156`) rather than Java's
`Parameter() { none() }`.
Each Python parameter (positional, *args, keyword-only, **kwargs) now
becomes a CFG node at a stable position in the enclosing callable's
entry sequence. Defaults still evaluate at function-definition time
via `FunctionDefExpr.getDefault` / `LambdaExpr.getDefault`, so
`Parameter::getDefaultValue()` returns `none()` (the shared CFG
library calls this to model the missing-argument fallback, which
Python does not surface at the CFG level).
The bindings test now exercises parameters (the `py_expr_contexts(_, 4, ...)`
exclusion has been removed). A new `parameters.py` test case covers
positional, defaulted, vararg, kwarg, keyword-only, kitchen-sink,
method (self/cls), lambda, and PEP 570 positional-only parameters.
Several other test files were updated to annotate parameters that the
test had previously hidden (synthetic `.0` comprehension parameter,
method `self`, decorator `f`, etc.).
Verified:
- All 24 ControlFlow/evaluation-order tests still pass.
- CFG consistency query (`python/ql/consistency-queries/CfgConsistency.ql`)
shows zero violations on CPython.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
43 lines
1.1 KiB
Python
43 lines
1.1 KiB
Python
# Function parameters.
|
|
|
|
def positional(a, b): # $ cfgdefines=positional cfgdefines=a cfgdefines=b
|
|
pass
|
|
|
|
|
|
def with_default(x=1, y=2): # $ cfgdefines=with_default cfgdefines=x cfgdefines=y
|
|
pass
|
|
|
|
|
|
def with_vararg(*args): # $ cfgdefines=with_vararg cfgdefines=args
|
|
pass
|
|
|
|
|
|
def with_kwarg(**kwargs): # $ cfgdefines=with_kwarg cfgdefines=kwargs
|
|
pass
|
|
|
|
|
|
def with_kwonly(*, k1, k2=5): # $ cfgdefines=with_kwonly cfgdefines=k1 cfgdefines=k2
|
|
pass
|
|
|
|
|
|
def kitchen_sink(a, b=2, *args, k1, k2=5, **kw): # $ cfgdefines=kitchen_sink cfgdefines=a cfgdefines=b cfgdefines=args cfgdefines=k1 cfgdefines=k2 cfgdefines=kw
|
|
pass
|
|
|
|
|
|
# Methods get `self` / `cls`.
|
|
class C: # $ cfgdefines=C
|
|
def method(self, x): # $ cfgdefines=method cfgdefines=self cfgdefines=x
|
|
pass
|
|
|
|
@classmethod
|
|
def cmethod(cls, x): # $ cfgdefines=cmethod cfgdefines=cls cfgdefines=x
|
|
pass
|
|
|
|
|
|
# Lambda parameter.
|
|
_ = lambda p: p + 1 # $ cfgdefines=_ cfgdefines=p
|
|
|
|
# PEP 570 positional-only.
|
|
def pos_only(a, b, /, c): # $ cfgdefines=pos_only cfgdefines=a cfgdefines=b cfgdefines=c
|
|
pass
|