CodeQL library for Python
codeql/python-all 1.0.1 (changelog, source)
Search

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): case pattern as alias:

matchCaptureFlowStep

capture pattern: subject flows to the variable syntax (toplevel): case var:

matchClassReadStep

class pattern: all keywords read the appropriate attribute from the subject syntax (toplevel): case ClassName(attr = val):

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): case literal:

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): case {**var}:

matchMappingReadStep

mapping pattern: each value reads from subject at the associated key syntax (toplevel): case {"color": c, "height": x}:

matchOrFlowStep

or pattern: subject flows to each alternative syntax (toplevel): case alt1 | alt2:

matchReadStep

All read steps associated with match.

matchSequenceReadStep

sequence pattern: each element reads from subject at the associated index syntax (toplevel): case [a, b]:

matchStarReadStep

star pattern: subject flows to the variable, possibly via a conversion syntax (toplevel): case *var:

matchStarStoreStep

star pattern: subject flows to the variable, possibly via a conversion syntax (toplevel): case *var:

matchStoreStep

All store steps associated with match.

matchSubjectFlowStep

Holds when there is flow from the subject nodeFrom to the (top-level) pattern nodeTo of a match statement.

matchValueFlowStep

value pattern: flow from the value to the pattern, to add information syntax (toplevel): case Dotted.value: