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

Predicate guardNode

Gets a node that controls whether other nodes are evaluated.

In the base case, this is the last node of conditionBlock, and flipped is false. This definition accounts for (short circuting) and- and or-expressions, as the structure of basic blocks will reflect their semantics.

However, in the program

if not is_safe(path):

the last node in the ConditionBlock is not is_safe(path).

We would like to consider also is_safe(path) a guard node, albeit with flipped being true. Thus we recurse through not-expressions.

Import path

ControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped)