API Reference

API

These are high level objects for interacting with mutatest. The primary objects include:

  1. The Genome

  2. The GenomeGroup

  3. The Mutant

Genomes are representations of a Python source code file. This includes a representation of the Abstract Syntax Tree (AST) and the locations within the AST that could be mutated. The locations are accessed by the targets and covered_targets properties of the Genome, the latter being available if a coverage file is set for the Genome. Locations are represented as LocIndex objects from mutatest.transformers which may be referenced as specific points of mutation.

Mutants are created from Genome.mutate() for a specific LocIndex in the Genome targets. A mutant is an immutable named-tuple with all of the attributes necessary to mutate the appropriate __pycache__ file with the write_cache() method.

Collections of Genomes can be managed through a GenomeGroup. The GenomeGroup provides methods for setting global filters, coverage files, and producing targets of LocIndex objects across the collection of Genomes. This is a useful representation when dealing with a folder of multiple source files.

class mutatest.api.Genome(source_file: Union[pathlib.Path, str, None] = None, coverage_file: Union[pathlib.Path, str, None] = PosixPath('.coverage'), filter_codes: Optional[Iterable[str]] = None)[source]

The Genome class describes the source file to be mutated.

The class describes a single .py file and has properties for the abstract syntax tree (AST) and the viable mutation targets. You can initialize without any arguments. If the source_file is changed the ast and targets properties will be recalculated for that file.

Locations in the Genome may be mutated and written to the __pycache__ using the mutate method.

property ast

Abstract Syntax Tree (AST) representation of the source_file.

This is cached locally and updated if the source_file is changed.

Returns

Parsed AST for the source file.

Raises

TypeError – if source_file is not set.

property coverage_file

The .coverage file to use for filtering targets.

property covered_targets

Targets that are marked as covered based on the coverage_file.

This is cached locally and updated if the coverage_file is changed. Filtering is not cached and applies any time the filter_codes are changed.

Returns

The targets that are covered.

Raises

TypeError – if the source_file or coverage_file is not set for the Genome.

property filter_codes

Filter codes applied to targets and covered targets.

mutate(target_idx: mutatest.transformers.LocIndex, mutation_op: Any, write_cache: bool = False) → mutatest.api.Mutant[source]

Create a mutant from a single LocIndex that is in the Genome.

Mutation_op must be a valid mutation for the target_idx operation code type. Optionally, use write_cache to write the mutant to __pycache__ based on the detected location at the time of creation. The Genome AST is unmodified by mutate.

Parameters
  • target_idx – the target location index (member of .targets)

  • mutation_op – the mutation operation to use

  • write_cache – optional flag to write to __pycache__

Returns

The mutant definition

Raises
  • MutationException – if mutation_op is not a valid mutation for the location index.

  • TypeError – if the source_file property is not set on the Genome.

  • ValueError – if the target_idx is not a member of Genome targets.

property source_file

The source .py file represented by this Genome.

Returns

The source_file path.

property targets

Viable mutation targets within the AST of the source_file.

This is cached locally and updated if the source_file is changed. Filtering is not cached and applies any time the filter_codes are changed.

Returns

The set of the location index objects from the transformer that could be potential mutation targets.

class mutatest.api.GenomeGroup(source_location: Union[pathlib.Path, str, None] = None)[source]

The GenomeGroup: a MutableMapping of Genomes for operations on the group.

add_file(source_file: Union[str, pathlib.Path], coverage_file: Union[pathlib.Path, str, None] = PosixPath('.coverage')) → None[source]

Add a .py source file to the group as a new Genome. The Genome is created automatically.

Parameters
  • source_file – the source file to add with Genome creation

  • coverage_file – an optional coverage file to set on the Genome, defaults to “.coverage”.

Returns

None

add_folder(source_folder: Union[str, pathlib.Path], exclude_files: Optional[Iterable[Union[str, pathlib.Path]]] = None, ignore_test_files: bool = True) → None[source]

Add a folder (recursively) to the GenomeGroup for all .py files.

Parameters
  • source_folder – the folder to recursively search

  • exclude_files – optional iterable of specific files in the source_folder to skip

  • ignore_test_files – optional flag, default to true, to ignore files prefixed with test_ or suffixed with _test in the stem of the file name.

Returns

None, adds all files as Genomes to the group.

Raises

TypeError – if source_folder is not a folder.

add_genome(genome: mutatest.api.Genome) → None[source]

Add a Genome to the GenomeGroup. Genomes must have a defined source_file.

Parameters

genome – the Genome to add

Returns

None

Raises

TypeError – if the Genome.source_file is not set.

property covered_targets

All mutation targets in the group that are covered, returned as tuples of source_file and location indices in a single set.

Returns

Set of tuples of source_file and location index for all covered targets in the group. These are GenomeGroupTargets to make attribute access easier.

items() → ItemsView[pathlib.Path, mutatest.api.Genome][source]

ItemsView for the mapping store.

keys() → KeysView[pathlib.Path][source]

KeysView of the mapping store.

set_coverage(coverage_file: Union[str, pathlib.Path]) → None[source]

Set a common coverage file for all Genomes in the group.

Parameters

coverage_file – the coverage file to set.

Returns

None

set_filter(filter_codes: Iterable[str]) → None[source]

Set the filter codes for all Genomes in the group.

Parameters

filter_codes – iterable of 2-letter codes to set on all Genomes in the group.

Returns

None

property targets

All mutation targets in the group, returned as tuples of source_file and location indices in a single set.

Returns

Set of tuples of source_file and location index for all targets in the group. These are GenomeGroupTargets to make attribute access easier.

values() → ValuesView[mutatest.api.Genome][source]

ValuesView of the mapping store.

class mutatest.api.GenomeGroupTarget[source]

Container for targets returned from GenomeGroup to associated source path to LocIdx.

property loc_idx

Alias for field number 1

property source_path

Alias for field number 0

class mutatest.api.Mutant[source]

Mutant definition.

Mutants are created through the Genome at specific targets using the mutate method. Mutants are immutable and can be written to disk in the __pycache__.

You can create Mutants using Genome.mutate, and then write_cache to apply to the __pycache__.

property cfile

Alias for field number 2

property loader

Alias for field number 3

property mode

Alias for field number 5

property mutant_code

Alias for field number 0

property mutation

Alias for field number 7

property source_stats

Alias for field number 4

property src_file

Alias for field number 1

property src_idx

Alias for field number 6

write_cache() → None[source]

Create the cache file for the mutant on disk in __pycache__.

Existing target cache files are removed to ensure clean overwrites.

Reference: https://github.com/python/cpython/blob/master/Lib/py_compile.py#L157

Returns

None, creates the cache file on disk.

exception mutatest.api.MutationException[source]

Mutation Exception type specifically for mismatches in mutation operations.

Cache

These functions are used to manipulate the __pycache__ when writing mutations to disk for detection by the test runners. Many functions are encapsulated in the Mutant.write_cache() method. Note that the parallel pycache controls are in the run.create_mutation_run_parallelcache_trial() function for multiprocessing.

mutatest.cache.check_cache_invalidation_mode() → py_compile.PycInvalidationMode[source]

Check the invalidation mode for cache files.

Reference: https://github.com/python/cpython/blob/master/Lib/py_compile.py#L72 The above reference does both time and hash invalidation. This method only supports time invalidation.

Hash invalidation is a future TODO.

Returns

None

Raises

EnvironmentError – if the SOURCE_DATE_EPOCH environment variable is set.

mutatest.cache.create_cache_dirs(cache_file: pathlib.Path) → None[source]

Create the __pycache__ directories if needed for the cache_file.

Parameters

cache_file – Path to the cache_file

Returns

None, creates the cache directory on disk if needed.

mutatest.cache.get_cache_file_loc(src_file: Union[str, pathlib.Path]) → pathlib.Path[source]

Use importlib to determine the cache file location for the source file.

Reference: https://github.com/python/cpython/blob/master/Lib/py_compile.py#L130

Parameters

src_file – source file to determine cache file

Returns

Path to the cache file

Raises

FileExistsError – if the cache-file path is symlink or irregular file

mutatest.cache.remove_existing_cache_files(src_loc: pathlib.Path) → None[source]

Remove cache files by name or by directory.

In the directory instance, all cache files are removed but the directory is not.

Parameters

src_loc – the file or directory that is a target for removal

Returns

None, deletes cache files from disk.

CLI

The command line interface controls. This module defines the entry point for running mutatest from the command line and the full main trial routine - clean trials, mutations trials, reporting results.

class mutatest.cli.ParserActionMap[source]

Container for parser mappings used in ConfigParsing with CLI args.

property action_types

Alias for field number 1

property actions

Alias for field number 0

class mutatest.cli.PositiveIntegerAction(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)[source]

Custom action for ensuring positive integers in number of trials.

class mutatest.cli.RunMode[source]

Running mode choices. This translate the -m argument into valid Config options.

property mode

Alias for field number 0

class mutatest.cli.SettingsFile[source]

Container for settings file in ini or cfg parsing format.

property path

Alias for field number 0

property sections

Alias for field number 1

exception mutatest.cli.SurvivingMutantException[source]

Exception for surviving mutations.

class mutatest.cli.TrialTimes[source]

Container for trial run times used in summary report.

property clean_trial_1

Alias for field number 0

property clean_trial_2

Alias for field number 1

property mutation_trials

Alias for field number 2

class mutatest.cli.ValidCategoryAction(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)[source]

Custom action to ensure only valid categories are used for only/skip listing.

mutatest.cli.cli_args(args: Sequence[str], search_config_files: bool = True) → argparse.Namespace[source]

Command line arguments as parsed args.

If a INI configuration file is set it is used to set additional default arguments, but the CLI arguments override any INI file settings.

Parameters
  • args – the argument sequence from the command line

  • search_config_files – flag for looking through SETTINGS_FILES for settings

Returns

Parsed args from ArgumentParser

mutatest.cli.cli_epilog() → str[source]

Epilog for the help output.

mutatest.cli.cli_main() → None[source]

Entry point to run CLI args and execute main function.

mutatest.cli.cli_parser() → argparse.ArgumentParser[source]

CLI argument parser.

Returns

The ArgumentParser

mutatest.cli.cli_summary_report(src_loc: pathlib.Path, args: argparse.Namespace, locs_mutated: int, locs_identified: int, runtimes: mutatest.cli.TrialTimes) → str[source]

Create a command line summary header for the final reporting.

Parameters
  • src_loc – source location

  • args – argparse namespace from cli

  • locs_mutated – total locations that were mutated

  • locs_identified – total locations identified as potential mutations

  • runtimes – trial times for the clean trials and mutation trials

Returns

str

mutatest.cli.exception_processing(n_survivors: int, trial_results: List[mutatest.run.MutantTrialResult]) → None[source]

Raise a custom mutation exception if n_survivors count is met.

Parameters
  • n_survivors – tolerance number for survivors

  • trial_results – results from the trials

Returns

None

Raises

SurvivingMutantException – if the number of survivors is exceeded.

mutatest.cli.get_parser_actions(parser: argparse.ArgumentParser) → mutatest.cli.ParserActionMap[source]

Create a parser action map used when creating the command list mixed from the CLI and the ini config file.

ParserActionMap has both actions and types e.g.,

# action-types:

{argparse._HelpAction: ['help'],
 mutatest.cli.ValidCategoryAction: ['skip', 'only'],
 argparse._AppendAction: ['exclude'],
 argparse._StoreAction: ['mode', 'output', 'src', 'testcmds'],
 mutatest.cli.PositiveIntegerAction: ['nlocations', 'rseed', 'exception'],
 argparse._StoreTrueAction: ['debug', 'nocov']}

# actions:

{'-h': '--help',
 '-k': '--skip',
 '-e': '--exclude',
 '-m': '--mode',
 '-n': '--nlocations',
 '-o': '--output',
 '-r': '--rseed',
 '-s': '--src',
 '-t': '--testcmds',
 '-x': '--exception',
 '-y': '--only',
 '--debug': '--debug',
 '--parallel': '--parallel',
 '--nocov': '--nocov'}
Parameters

parser – the argparser

Returns

includes actions and action_types

Return type

ParserActionMap

mutatest.cli.get_src_location(src_loc: Optional[pathlib.Path] = None) → pathlib.Path[source]

Find packages is used if the src_loc is not set

Parameters

src_loc – current source location, defaults to None

Returns

Path to the source location

Raises

FileNoeFoundError – if the source location doesn’t exist.

mutatest.cli.main(args: argparse.Namespace) → None[source]

Main CLI function to run the mutation trials and report results.

Parameters

args – argparse arguments

Returns

None, reports output

mutatest.cli.parse_ini_config_with_cli(parser: argparse.ArgumentParser, ini_config: configparser.SectionProxy, cli_args: Sequence[str]) → List[str][source]

Combine the INI file settings with the CLI args, using the CLI args as the override.

Parameters
  • parser – the argparser

  • ini_config – the section of the parsed INI file

  • cli_args – the original cli args

Returns

Updated args mixing INI and CLI, with CLI used as the override

mutatest.cli.read_ini_config(config_path: pathlib.Path, sections: Optional[List[str]] = None) → configparser.SectionProxy[source]

Read a config_path using ConfigParser

Parameters
  • config_path – path to the INI config file

  • sections – sections of config file to return, default to [‘mutatest’] if None

Returns

config section proxy

Raises

KeyError if section not in config_path.

mutatest.cli.selected_categories(only: List[str], skip: List[str]) → List[str][source]

Create the selected categories from the skip/only set to use in filtering.

Parameters
  • only – list of categories

  • skip – list of categories

Returns

Selection set of mutation categories

Filters

Filters operate on the sets of location indices, the LocIndex objects, returned by Genomes using targets or covered_targets. There are two main filters:

  1. CoverageFilter

  2. CategoryCodeFilter

The CoverageFilter is used to create the covered_targets returned by the Genome. The CategoryCodeFilter is used to restrict the returned sets of LocIndex objects to specific types of mutations e.g., only BinOp, only Compare, or a combination of multiple mutation categories.

Both of these filters are implemented in Genome and GenomeGroup for basic usage in filtering by category code or covered lines.

class mutatest.filters.CategoryCodeFilter(codes: Optional[Iterable[str]] = None)[source]

Filter by mutation category code.

add_code(code: str) → None[source]

Add a single 2-letter code to the codes set for the class.

Parameters

code – a valid 2 letter code

Returns

None

Raises

ValueError – if an invalid code is passed.

property codes

Getter for the codes set for filtering purposes.

Returns

Set of 2 letter codes used in filtering.

discard_code(code: str) → None[source]

Discard a 2-letter code from the codes set.

This uses the built-in set.discard() so that a KeyError is not raised if the code does not exist in the set already.

Parameters

code – the 2-letter code to discard

Returns

None

filter(loc_idxs: Set[mutatest.transformers.LocIndex], invert: bool = False) → Set[mutatest.transformers.LocIndex][source]

Filter a set of location indices based on the set codes.

If the codes property is an empty set, the loc_idxs is returned unmodified.

Parameters
  • loc_idxs – the set of location indices to filter.

  • invert – flag for inverted filtering using NOT

Returns

Set of location indices with the filter applied.

property valid_categories

All valid categories with descriptive name and 2 letter code.

Returns

The categories defined in transformers.

property valid_codes

All valid 2 letter codes.

Returns

View of the values of valid_categories.

property valid_mutations

Valid mutations for the set of category codes.

Returns

Set of valid mutations for the codes, types will vary

class mutatest.filters.CoverageFilter(coverage_file: Union[str, pathlib.Path] = PosixPath('.coverage'))[source]

Filter for covered lines to be applied to mutation targets in Genome.

property coverage_data

Read the coverage file for lines and arcs data.

This is cached locally and updated if the coverage_file is changed.

Returns

A CoverageData object based on the coverage_file.

Raises

FileNotFoundError – if coverage_file does not exist.

property coverage_file

Property accessor for _coverage_file set at initialization.

Returns

The coverage file path.

filter(loc_idxs: Set[mutatest.transformers.LocIndex], source_file: Union[str, pathlib.Path], invert: bool = False, resolve_source: bool = True) → Set[mutatest.transformers.LocIndex][source]

Filter based on coverage measured file.

This adds the source_file argument to the filter abstract method because the coverage file holds multiple measured-files, and the LocIndex object does not have a source file attribute. The choice is that the coverage file can be set and read once for the class instance, and any valid measured file can be used in the filter.

Parameters
  • loc_idxs – location index set of targets

  • source_file – source file that is measured by the coverage file

  • invert – flag for inverted filter using NOT

  • resolve_source – flag for using resolved source_file vs. direct str, default True. This exists mostly for testing purposes to access mocked entries in the fake coverage files.

Returns

Filtered set of location index set

class mutatest.filters.Filter[source]

Abstract Base Class for filters, interface should include a filter method.

abstract filter(loc_idxs: Set[mutatest.transformers.LocIndex], invert: bool = False) → Set[mutatest.transformers.LocIndex][source]

General filter method that should return a location index set.

A filter should take a set of location indices (loc_idxs) and return the filtered set of location indices. The invert kwarg is set as a reversible filter e.g., to specify NOT for the filtering effect.

Other args or kwargs may be required so this is not a hard-enforced signature.

Report

Functions used to aggregate and produce the final RST reports seen on the CLI.

class mutatest.report.DisplayResults[source]

Results to display on the CLI with coloring.

property detected

Alias for field number 3

property summary

Alias for field number 0

property survived

Alias for field number 1

property timedout

Alias for field number 2

class mutatest.report.ReportedMutants[source]

Container for reported mutants to pair status with the list of mutants.

property mutants

Alias for field number 1

property status

Alias for field number 0

mutatest.report.analyze_mutant_trials(trial_results: List[mutatest.run.MutantTrialResult]) → Tuple[str, mutatest.report.DisplayResults][source]

Create the analysis text report string for the trials.

Additionally, return a DisplayResults NamedTuple that includes terminal coloring for the output on the terminal.

It will look like:

Overall mutation trial summary:
===============================
DETECTED: x
TIMEOUT: w
SURVIVED: y
...

Breakdown by section:
=====================

Section title
-------------
source_file.py: (l: 1, c: 10) - mutation from op.Original to op.Mutated
source_file.py: (l: 3, c: 10) - mutation from op.Original to op.Mutated
Parameters

trial_results – list of MutantTrial results

Returns

(text report, DisplayResults)

Return type

Tuple

mutatest.report.build_report_section(title: str, mutants: List[mutatest.run.MutantReport]) → str[source]

Build a readable mutation report section from the list of mutants.

It will look like:

Title
-----
source_file.py: (l: 1, c: 10) - mutation from op.Original to op.Mutated
source_file.py: (l: 3, c: 10) - mutation from op.Original to op.Mutated
Parameters
  • title – title for the section.

  • mutants – list of mutants for the formatted lines.

Returns

The report section as a formatted string.

mutatest.report.get_reported_results(trial_results: List[mutatest.run.MutantTrialResult], status: str) → mutatest.report.ReportedMutants[source]

Utility function to create filtered lists of mutants based on status.

Parameters
  • trial_results – list of mutant trial results

  • status – the status to filter by

Returns

The reported mutants as a ReportedMutants container.

mutatest.report.get_status_summary(trial_results: List[mutatest.run.MutantTrialResult]) → Dict[str, Union[str, int]][source]

Create a status summary dictionary for later formatting.

Parameters

trial_results – list of mutant trials

Returns

Dictionary with keys for formatting in the report

mutatest.report.write_report(report: str, location: pathlib.Path) → None[source]

Write the report to a file.

If the location does not exist with folders they are created.

Parameters
  • report – the string report to write

  • location – path location to the file

Returns

None, writes output to location

Run

The run functions are used to run mutation trials from the CLI. These can be used directly for other customized running requirements. The Config data-class defines the running parameters for the full trial suite. Sampling functions are defined here as well.

exception mutatest.run.BaselineTestException[source]

Used as an exception for the clean trial runs.

class mutatest.run.Config(n_locations: int = 0, exclude_files: List[pathlib.Path] = <factory>, filter_codes: List[str] = <factory>, random_seed: Optional[int] = None, break_on_survival: bool = False, break_on_detected: bool = False, break_on_error: bool = False, break_on_unknown: bool = False, break_on_timeout: bool = False, ignore_coverage: bool = False, max_runtime: float = 10, multi_processing: bool = False)[source]

Run configuration used for mutation trials.

class mutatest.run.MutantReport[source]

Pickleable reporting mutant object for multiprocessing collection.

property mutation

Alias for field number 2

property src_file

Alias for field number 0

property src_idx

Alias for field number 1

class mutatest.run.MutantTrialResult[source]

Mutant trial result to encode return_code status with mutation information.

property mutant

Alias for field number 0

property return_code

Alias for field number 1

property status

Based on pytest return codes

class mutatest.run.ResultsSummary[source]

Results summary container.

property n_locs_identified

Alias for field number 2

property n_locs_mutated

Alias for field number 1

property results

Alias for field number 0

property total_runtime

Alias for field number 3

mutatest.run.capture_output(log_level: int) → bool[source]

Utility function used in subprocess for captured output.

Available log levels are: https://docs.python.org/3/library/logging.html#levels 10 is the value for Debug, so if it’s not “DEBUG”, return true and capture output.

Parameters

log_level – the logging level

Returns

Bool indicator on capturing output

mutatest.run.clean_trial(src_loc: pathlib.Path, test_cmds: List[str]) → datetime.timedelta[source]

Remove all existing cache files and run the test suite.

Parameters
  • src_loc – the directory of the package for cache removal, may be a file

  • test_cmds – test running commands for subprocess.run()

Returns

None

Raises

BaselineTestException – if the clean trial does not pass from the test run.

mutatest.run.colorize_output(output: str, color: str) → str[source]

Color output for the terminal display as either red or green.

Parameters
  • output – string to colorize

  • color – choice of terminal color, “red” vs. “green”

Returns

colorized string, or original string for bad color choice.

mutatest.run.create_mutation_run_parallelcache_trial(genome: mutatest.api.Genome, target_idx: mutatest.transformers.LocIndex, mutation_op: Any, test_cmds: List[str], max_runtime: float) → mutatest.run.MutantTrialResult[source]

Similar to run.create_mutation_run_trial() but using the parallel cache directory settings.

This function requires Python 3.8 and does not run with Python 3.7. Importantly, it has the identical signature to run.create_mutation_run_trial() and is substituted in the run.mutation_sample_dispatch().

Parameters
  • genome – the genome to mutate

  • target_idx – the mutation location

  • mutation_op – the mutation operation

  • test_cmds – the test commands to execute with the mutated code

  • max_runtime – timeout for the subprocess trial

Returns

MutantTrialResult

Raises

EnvironmentError – if Python version is less than 3.8

mutatest.run.create_mutation_run_trial(genome: mutatest.api.Genome, target_idx: mutatest.transformers.LocIndex, mutation_op: Any, test_cmds: List[str], max_runtime: float) → mutatest.run.MutantTrialResult[source]

Run a single mutation trial by creating a new mutated cache file, running the test commands, and then removing the mutated cache file.

Parameters
  • genome – the genome to mutate

  • target_idx – the mutation location

  • mutation_op – the mutation operation

  • test_cmds – the test commands to execute with the mutated code

  • max_runtime – timeout for the trial

Returns

The mutation trial result

mutatest.run.get_genome_group(src_loc: pathlib.Path, config: mutatest.run.Config) → mutatest.api.GenomeGroup[source]

Get the GenomeGroup based on src_loc and config.

Config is used to set global filter codes and exclude files on group creation.

Parameters
  • src_loc – Path, can be directory or file

  • config – the running config object

Returns

GenomeGroup based on src_loc and config.

mutatest.run.get_mutation_sample_locations(sample_space: List[mutatest.api.GenomeGroupTarget], n_locations: int) → List[mutatest.api.GenomeGroupTarget][source]

Create the mutation sample space and set n_locations to a correct value for reporting.

n_locations will change if it is larger than the total sample_space.

Parameters
  • sample_space – sample space to draw random locations from

  • n_locations – number of locations to draw

Returns

mutation sample

mutatest.run.get_sample(ggrp: mutatest.api.GenomeGroup, ignore_coverage: bool) → List[mutatest.api.GenomeGroupTarget][source]

Get the sample space for the mutation trials.

This will attempt to use covered-targets as the default unless ignore_coverage is set to True. If the set .coverage file is not found then the total targets are returned instead.

Parameters
  • ggrp – the Genome Group to generate the sample space of targets

  • ignore_coverage – flag to ignore coverage if present

Returns

Sorted list of Path-LocIndex pairs as complete sample space from the GenomeGroup.

mutatest.run.mutation_sample_dispatch(ggrp_target: mutatest.api.GenomeGroupTarget, ggrp: mutatest.api.GenomeGroup, test_cmds: List[str], config: mutatest.run.Config, trial_runner: Callable[[mutatest.api.Genome, mutatest.transformers.LocIndex, Any, List[str], float], mutatest.run.MutantTrialResult]) → List[mutatest.run.MutantTrialResult][source]

Dispatch for the mutant trial.

This is fed either from a loop across GenomeGroupTargets, or through a multi-processing pool using the starmap_async.

Parameters
  • ggrp_target – The target index and source object

  • ggrp – the GenomeGroup

  • test_cmds – test commands to execute

  • config – running config object

  • trial_runner – function callable either for single or multi-processing execution

Returns

MutantTrialResult

mutatest.run.run_mutation_trials(src_loc: pathlib.Path, test_cmds: List[str], config: mutatest.run.Config) → mutatest.run.ResultsSummary[source]

This is the main function for running the mutation trials.

It will cycle through creation of the GenomeGroups from the source location, selecting the mutation sample based on the config settings, and executing the mutation trials using the test commands. This function does not include a clean-trial, it only runs the mutation trials.

Parameters
  • src_loc – the source location path for mutation

  • test_cmds – the test commands to execute

  • config – the running config object

Returns

ResultsSummary object of the mutation trials.

mutatest.run.trial_output_check_break(trial_results: mutatest.run.MutantTrialResult, config: mutatest.run.Config, sample_src: pathlib.Path, sample_idx: mutatest.transformers.LocIndex) → bool[source]

Flagging function to break the mutation operations loop and output logging.

This is called within the run_mutation_trials as a utility function to determine the break-on behavior for progression e.g., break-on-survival.

Parameters
  • trial_results – mutation trial results

  • config – running configuration object

  • sample_src – the sample source location

  • sample_idx – the sample index where the mutation occurred

Returns

Bool flag for whether or not to break the outer operations loop.

Transformers

Transformers defines the mutations that can be applied. The CATEGORIES dictionary lists all valid category codes that are valid filters. The primary classes are:

  1. LocIndex

  2. MutateAST

The LocIndex is a location index within a given Abstract Syntax Tree (AST) that can be mutated. The MutateAST class walks the AST of a given source file to identify all of the locations, and optionally create the mutation at that node. These are implemented in the Genome object.

MutateAST is constructed from MutateBase and the appropriate mixin class - either ConstantMixin for Python 3.8, or NameConstantMixin for Python 3.7.

class mutatest.transformers.ConstantMixin[source]

Mixin for Python 3.8 AST applied to MutateBase.

visit_Constant(node: _ast.Constant) → _ast.AST[source]

Constants: https://bugs.python.org/issue32892 NameConstant: True, False, None. Num: isinstance(int, float) Str: isinstance(str)

class mutatest.transformers.LocIndex[source]

Location index within AST to mark mutation targets.

The end_lineno and end_col_offset properties are set to None by default as they are only used distinctly in Python 3.8.

property ast_class

Alias for field number 0

property col_offset

Alias for field number 2

property end_col_offset

Alias for field number 5

property end_lineno

Alias for field number 4

property lineno

Alias for field number 1

property op_type

Alias for field number 3

class mutatest.transformers.LocIndexNode(*args, **kwargs)[source]

Type protocol for AST Nodes that include lineno and col_offset properties.

class mutatest.transformers.MutateAST(target_idx: Optional[mutatest.transformers.LocIndex] = None, mutation: Optional[Any] = None, readonly: bool = False, src_file: Union[pathlib.Path, str, None] = None)[source]

Implementation of the MutateAST class based on running environment.

class mutatest.transformers.MutateBase(target_idx: Optional[mutatest.transformers.LocIndex] = None, mutation: Optional[Any] = None, readonly: bool = False, src_file: Union[pathlib.Path, str, None] = None)[source]

AST NodeTransformer to replace nodes with mutations by visits.

property constant_type

Overridden using the MixinClasses for NameConstant(3.7) vs. Constant(3.8).

mixin_NameConstant(node: Union[_ast.NameConstant, _ast.Constant]) → _ast.AST[source]

Constants: True, False, None.

This method is called by using the Mixin classes for handling the difference of ast.NameConstant (Py 3.7) an ast.Constant (Py 3.8).

property mutation

The mutation to apply, may be a type or a value

property readonly

A flag for read-only operations, used to visit nodes instead of transform

property src_file

Source file name, used for logging purposes

property target_idx

Location index for the mutation in the AST

visit_AugAssign(node: _ast.AugAssign) → _ast.AST[source]

AugAssign is -=, +=, /=, *= for augmented assignment.

visit_BinOp(node: _ast.BinOp) → _ast.AST[source]

BinOp nodes are bit-shifts and general operators like add, divide, etc.

visit_BoolOp(node: _ast.BoolOp) → _ast.AST[source]

Boolean operations, AND/OR.

visit_Compare(node: _ast.Compare) → _ast.AST[source]

Compare nodes are ==, >=, is, in etc. There are multiple Compare categories.

visit_If(node: _ast.If) → _ast.AST[source]

If statements e.g. If x == y is transformed to if True and if False.

This visit method only works when the appropriate Mixin is used.

visit_Index(node: _ast.Index) → _ast.AST[source]

Index visit e.g. i[0], i[0][1].

visit_Subscript(node: _ast.Subscript) → _ast.AST[source]

Subscript slice operations e.g., x[1:] or y[::2].

class mutatest.transformers.MutationOpSet[source]

Container for compatible mutation operations. Also used in the CLI display.

property category

Alias for field number 3

property desc

Alias for field number 1

property name

Alias for field number 0

property operations

Alias for field number 2

class mutatest.transformers.NameConstantMixin[source]

Mixin for Python 3.7 AST applied to MutateBase.

visit_NameConstant(node: _ast.NameConstant) → _ast.AST[source]

NameConstants: True, False, None.

class mutatest.transformers.NodeSpan[source]

Node span to support Py3.7 and 3.8 compatibility for locations. This is used to generate the set the values in the LocIndex as a general class.

property col_offset

Col offset for the node.

property end_col_offset

Python 3.8 will have this defined, in Python 3.7 it will be None.

Type

End col offset

property end_lineno

Python 3.8 will have this defined, in Python 3.7 it will be None.

Type

End line no

property lineno

Line number for the node.

property node

Alias for field number 0

mutatest.transformers.get_compatible_operation_sets() → List[mutatest.transformers.MutationOpSet][source]

Utility function to return a list of compatible AST mutations with names.

All of the mutation transformation sets that are supported by mutatest are defined here. See: https://docs.python.org/3/library/ast.html#abstract-grammar

This is used to create the search space in finding mutations for a target, and also to list the support operations in the CLI help function.

Returns

List of MutationOpSets that have substitutable operations

mutatest.transformers.get_mutations_for_target(target: mutatest.transformers.LocIndex) → Set[Any][source]

Given a target, find all the mutations that could apply from the AST definitions.

Parameters

target – the location index target

Returns

Set of types that can mutated into the target location.