From cd3ccb03aae612173ae860782c1e0ffc942678bd Mon Sep 17 00:00:00 2001 From: Victor Lin <13424970+victorlin@users.noreply.github.com> Date: Tue, 22 Oct 2024 10:37:21 -0700 Subject: [PATCH] Centralize --validation-mode and --skip-validation Since --validation-mode is used in many subcommands, create a centralized function that adds the option as well as the related --skip-validation option. This adds --skip-validation to ancestral and translate. --- augur/ancestral.py | 6 ++---- augur/argparse_.py | 35 ++++++++++++++++++++++++++++++++++- augur/export_v2.py | 30 ++---------------------------- augur/translate.py | 5 ++--- 4 files changed, 40 insertions(+), 36 deletions(-) diff --git a/augur/ancestral.py b/augur/ancestral.py index 932d86072..7a39764da 100644 --- a/augur/ancestral.py +++ b/augur/ancestral.py @@ -34,9 +34,8 @@ from .io.vcf import is_vcf as is_filename_vcf from treetime.vcf_utils import read_vcf, write_vcf from collections import defaultdict -from .types import ValidationMode +from .argparse_ import add_validation_arguments from .util_support.node_data_file import NodeDataObject -from .export_v2 import validation_mode_help_message def ancestral_sequence_inference(tree=None, aln=None, ref=None, infer_gtr=True, marginal=False, fill_overhangs=True, infer_tips=False, @@ -335,8 +334,7 @@ def register_parser(parent_subparsers): general_group = parser.add_argument_group( "general", ) - general_group.add_argument('--validation-mode', type=ValidationMode, choices=[mode for mode in ValidationMode], default=ValidationMode.ERROR, - help=validation_mode_help_message) + add_validation_arguments(general_group) return parser diff --git a/augur/argparse_.py b/augur/argparse_.py index 6f0ee5e72..6084fdd5e 100644 --- a/augur/argparse_.py +++ b/augur/argparse_.py @@ -1,7 +1,9 @@ """ Custom helpers for the argparse standard library. """ -from argparse import Action, ArgumentDefaultsHelpFormatter +from argparse import Action, ArgumentDefaultsHelpFormatter, ArgumentParser, _ArgumentGroup +from typing import Union +from .types import ValidationMode # Include this in an argument help string to suppress the automatic appending @@ -93,3 +95,34 @@ def __call__(self, parser, namespace, value, option_string = None): current = [] setattr(namespace, self.dest, [*current, *value]) + + +def add_validation_arguments(parser: Union[ArgumentParser, _ArgumentGroup]): + """ + Add arguments to configure validation mode of node data JSON files. + """ + parser.add_argument( + '--validation-mode', + dest="validation_mode", + type=ValidationMode, + choices=[mode for mode in ValidationMode], + default=ValidationMode.ERROR, + help=""" + Control if optional validation checks are performed and what + happens if they fail. + + 'error' and 'warn' modes perform validation and emit messages about + failed validation checks. 'error' mode causes a non-zero exit + status if any validation checks failed, while 'warn' does not. + + 'skip' mode performs no validation. + + Note that some validation checks are non-optional and as such are + not affected by this setting. + """) + parser.add_argument( + '--skip-validation', + dest="validation_mode", + action="store_const", + const=ValidationMode.SKIP, + help="Skip validation of input/output files, equivalent to --validation-mode=skip. Use at your own risk!") diff --git a/augur/export_v2.py b/augur/export_v2.py index b781bc835..6cd04eb37 100644 --- a/augur/export_v2.py +++ b/augur/export_v2.py @@ -13,7 +13,7 @@ from Bio import Phylo from typing import Dict, Union, TypedDict, Any, Tuple -from .argparse_ import ExtendOverwriteDefault +from .argparse_ import ExtendOverwriteDefault, add_validation_arguments from .errors import AugurError from .io.file import open_file from .io.metadata import DEFAULT_DELIMITERS, DEFAULT_ID_COLUMNS, InvalidDelimiter, read_metadata @@ -926,20 +926,6 @@ def node_data_prop_is_normal_trait(name): return True -validation_mode_help_message = """ - Control if optional validation checks are performed and what - happens if they fail. - - 'error' and 'warn' modes perform validation and emit messages about - failed validation checks. 'error' mode causes a non-zero exit - status if any validation checks failed, while 'warn' does not. - - 'skip' mode performs no validation. - - Note that some validation checks are non-optional and as such are - not affected by this setting. -""" - def register_parser(parent_subparsers): parser = parent_subparsers.add_parser("v2", help=__doc__) @@ -1007,19 +993,7 @@ def register_parser(parent_subparsers): optional_settings = parser.add_argument_group( title="OTHER OPTIONAL SETTINGS" ) - optional_settings.add_argument( - '--validation-mode', - dest="validation_mode", - type=ValidationMode, - choices=[mode for mode in ValidationMode], - default=ValidationMode.ERROR, - help=validation_mode_help_message) - optional_settings.add_argument( - '--skip-validation', - dest="validation_mode", - action="store_const", - const=ValidationMode.SKIP, - help="Skip validation of input/output files, equivalent to --validation-mode=skip. Use at your own risk!") + add_validation_arguments(optional_settings) return parser diff --git a/augur/translate.py b/augur/translate.py index 6ec4d4b3d..637759e99 100644 --- a/augur/translate.py +++ b/augur/translate.py @@ -22,9 +22,8 @@ from treetime.vcf_utils import read_vcf from augur.errors import AugurError from textwrap import dedent -from .types import ValidationMode +from .argparse_ import add_validation_arguments from .util_support.node_data_file import NodeDataObject -from .export_v2 import validation_mode_help_message class MissingNodeError(Exception): pass @@ -373,7 +372,7 @@ def register_parser(parent_subparsers): parser.add_argument('--alignment-output', type=str, help="write out translated gene alignments. " "If a VCF-input, a .vcf or .vcf.gz will be output here (depending on file ending). If fasta-input, specify the file name " "like so: 'my_alignment_%%GENE.fasta', where '%%GENE' will be replaced by the name of the gene") - parser.add_argument('--validation-mode', type=ValidationMode, choices=[mode for mode in ValidationMode], default=ValidationMode.ERROR, help=validation_mode_help_message) + add_validation_arguments(parser) vcf_only = parser.add_argument_group( title="VCF specific",