Mutations

mutatest supports the following mutation operations based on the Python AST grammar 1:

Supported operations:
  • AugAssign mutations e.g. += -= *= /=.

  • BinOp mutations e.g. + - / *.

  • BinOp Bitwise Comparison mutations e.g. x&y x|y x^y.

  • BinOp Bitwise Shift mutations e.g. << >>.

  • BoolOp mutations e.g. and or.

  • Compare mutations e.g. == >= < <= !=.

  • Compare In mutations e.g. in, not in.

  • Compare Is mutations e.g. is, is not.

  • If mutations e.g. If x > y becomes If True or If False.

  • Index mutations e.g. i[0] becomes i[1] and i[-1].

  • NameConstant mutations e.g. True, False, and None.

  • Slice mutations e.g. changing x[:2] to x[2:].

These are the current operations that are mutated as compatible sets. The two-letter category code for white/black-list selection is beside the name in double quotes.

AugAssign - “aa”

Augmented assignment e.g. += -= /= *=.

Members:
  • AugAssign_Add

  • AugAssign_Div

  • AugAssign_Mult

  • AugAssign_Sub

Example:

# source code
x += y

# mutations
x -= y  # AugAssign_Sub
x *= y  # AugAssign_Mult
x /= y  # AugAssign_Div

BinOp - “bn”

Binary operations e.g. add, subtract, divide, etc.

Members:
  • ast.Add

  • ast.Div

  • ast.FloorDiv

  • ast.Mod

  • ast.Mult

  • ast.Pow

  • ast.Sub

Example:

# source code
x = a + b

# mutations
x = a / b  # ast.Div
x = a - b  # ast.Sub

BinOp Bit Comparison - “bc”

Bitwise comparison operations e.g. x & y, x | y, x ^ y.

Members:
  • ast.BitAnd

  • ast.BitOr

  • ast.BitXor

Example:

# source code
x = a & y

# mutations
x = a | y  # ast.BitOr
x = a ^ y  # ast.BitXor

BinOp Bit Shifts - “bs”

Bitwise shift operations e.g. << >>.

Members:
  • ast.LShift

  • ast.RShift

Example:

# source code
x >> y

# mutation
x << y

BoolOp - “bl”

Boolean operations e.g. and or.

Members:
  • ast.And

  • ast.Or

Example:

# source code
if x and y:

# mutation
if x or y:

Compare - “cp”

Comparison operations e.g. == >= <= > <.

Members:
  • ast.Eq

  • ast.Gt

  • ast.GtE

  • ast.Lt

  • ast.LtE

  • ast.NotEq

Example:

# source code
x >= y

# mutations
x < y  # ast.Lt
x > y  # ast.Gt
x != y  # ast.NotEq

Compare In - “cn”

Compare membership e.g. in, not in.

Members:
  • ast.In

  • ast.NotIn

Example:

# source code
x in [1, 2, 3, 4]

# mutation
x not in [1, 2, 3, 4]

Compare Is - “cs”

Comapre identity e.g. is, is not.

Members:
  • ast.Is

  • ast.IsNot

Example:

# source code
x is None

# mutation
x is not None

If - “if”

If mutations change if statements to always be True or False. The original statement is represented by the class If_Statement in reporting.

Members:
  • If_False

  • If_Statement

  • If_True

Example:

# source code
if a > b:   # If_Statement
    ...

# Mutations
if True:   # If_True
    ...

if False:  # If_False
    ...

Index - “ix”

Index values for iterables e.g. i[-1], i[0], i[0][1]. It is worth noting that this is a unique mutation form in that any index value that is positive will be marked as Index_NumPos and the same relative behavior will happen for negative index values to Index_NumNeg. During the mutation process there are three possible outcomes: the index is set to 0, -1 or 1. The alternate values are chosen as potential mutations e.g. if the original operation is classified as Index_NumPos such as x[10] then valid mutations are to x[0] or x[-1].

Members:
  • Index_NumNeg

  • Index_NumPos

  • Index_NumZero

Example:

# source code
x = [a[10], a[-4], a[0]]

# mutations
x = [a[-1], a[-4], a[0]]  # a[10] mutated to Index_NumNeg
x = [a[10], a[0], a[0]]  # a[-4] mutated to Index_NumZero
x = [a[10], a[1], a[0]]  # a[-4] mutated to Index_NumPos
x = [a[10], a[-4], a[1]]  # a[0] mutated to Index_NumPos

NameConstant - “nc”

Named constant mutations e.g. True, False, None.

Members:
  • False

  • None

  • True

Example:

# source code
x = True

# mutations
x = False
X = None

Slices - “su”

Slice mutations to swap lower/upper values, or change range e.g. x[2:] to x[:2]. This is a unique mutation. If the upper or lower bound is set to None then the bound values are swapped. This is represented by the operations of Slice_UnboundedUpper for swap None to the “upper” value from “lower”. The category code for this type of mutation is “su”.

Members:
  • Slice_Unbounded

  • Slice_UnboundedLower

  • Slice_UnboundedUpper

Example:

# source code
w = a[:2]
x = a[4:]

# mutation
w = a[2:]  # Slice_UnboundedUpper, upper is now unbounded and lower has a value
x = a[4:]

# mutation
w = a[:2]
x = a[:4]  # Slice_UnboundedLower, lower is now unbounded and upper has a value

# mutation
w = a[:2]
x = a[:]  # Slice_Unbounded, both upper and lower are unbounded
1

https://docs.python.org/3/library/ast.html#abstract-grammar