Module MatchUnpacking
There are a number of patterns available for the match statement. Each one transfers data and content differently to its parts.
Furthermore, given a successful match, we can infer some data about the subject. Consider the example:
match choice:
case 'Y':
...body
Inside body
, we know that choice
has the value 'Y'
.
A similar thing happens with the “as pattern”. Consider the example:
match choice:
case ('y'|'Y') as c:
...body
By the binding rules, there is data flow from choice
to c
. But we
can infer the value of c
to be either 'y'
or 'Y'
if the match succeeds.
We will treat such inferences separately as guards. First we will model the data flow stemming from the bindings and the matching of shape. Below, ‘subject’ is not necessarily the top-level subject of the match, but rather the part recursively matched by the current pattern. For instance, in the example:
match command:
case ('quit' as c) | ('go', ('up'|'down') as c):
...body
command
is the subject of first the as-pattern, while the second component of command
is the subject of the second as-pattern. As such, ‘subject’ refers to the pattern under evaluation.
- as pattern: subject flows to alias as well as to the interior pattern
- or pattern: subject flows to each alternative
- literal pattern: flow from the literal to the pattern, to add information
- capture pattern: subject flows to the variable
- wildcard pattern: no flow
- value pattern: flow from the value to the pattern, to add information
- sequence pattern: each element reads from subject at the associated index
- star pattern: subject flows to the variable, possibly via a conversion
- mapping pattern: each value reads from subject at the associated key
- double star pattern: subject flows to the variable, possibly via a conversion
- key-value pattern: the value reads from the subject at the key (see mapping pattern)
- class pattern: all keywords read the appropriate attribute from the subject
- keyword pattern: the appropriate attribute is read from the subject (see class pattern)
Inside the class pattern, we also find positional arguments. They are converted to
keyword arguments using the __match_args__
attribute on the class. We do not
currently model this.
Import path
import semmle.python.dataflow.new.internal.MatchUnpacking
Predicates
matchAsFlowStep | as pattern: subject flows to alias as well as to the interior pattern syntax (toplevel): |
matchCaptureFlowStep | capture pattern: subject flows to the variable syntax (toplevel): |
matchClassReadStep | class pattern: all keywords read the appropriate attribute from the subject syntax (toplevel): |
matchClearStep | All clear steps associated with match |
matchFlowStep | All flow steps associated with match. |
matchLiteralFlowStep | literal pattern: flow from the literal to the pattern, to add information syntax (toplevel): |
matchMappingClearStep | Bindings that are mentioned in a mapping pattern will not be available to a double star pattern in the same mapping pattern. |
matchMappingFlowStep | double star pattern: subject flows to the variable, possibly via a conversion syntax (toplevel): |
matchMappingReadStep | mapping pattern: each value reads from subject at the associated key syntax (toplevel): |
matchOrFlowStep | or pattern: subject flows to each alternative syntax (toplevel): |
matchReadStep | All read steps associated with match. |
matchSequenceReadStep | sequence pattern: each element reads from subject at the associated index syntax (toplevel): |
matchStarReadStep | star pattern: subject flows to the variable, possibly via a conversion syntax (toplevel): |
matchStarStoreStep | star pattern: subject flows to the variable, possibly via a conversion syntax (toplevel): |
matchStoreStep | All store steps associated with match. |
matchSubjectFlowStep | Holds when there is flow from the subject |
matchValueFlowStep | value pattern: flow from the value to the pattern, to add information syntax (toplevel): |