datacompy.cli package¶
Submodules¶
datacompy.cli.backends module¶
Backend strategies for the DataComPy CLI.
Each CLIBackend owns the three things that vary between backends:
opening a session (Spark and Snowflake only), turning a --left or
--right reference into something the comparison accepts, and calling the
right *Compare constructor.
The constructor keyword arguments themselves are not written out here. They are
derived from datacompy.cli.parser.OPTIONS by compare_kwargs(), so
the parser and the constructor call site cannot drift apart.
Imports of pyspark and snowflake.snowpark are deferred into methods,
following the same pattern as datacompy/__init__.py.
- class datacompy.cli.backends.CLIBackend¶
Bases:
ABCStrategy describing how the CLI drives one comparison backend.
- build(namespace: Namespace, session: Any, left: Any, right: Any) BaseCompare¶
Construct the
*Compareinstance.
- property compare_cls: Callable[[...], BaseCompare]¶
Import and return the backend’s
*Compareclass.Typed as a callable rather than
type[BaseCompare]because the constructor signatures differ between backends, which is exactly whatcompare_kwargs()and the drift guard intests/cliexist to reconcile.- Raises:
MissingExtraError – When the backend needs an optional dependency that is not installed.
- extra: ClassVar[str | None] = None¶
Optional dependency extra required by this backend, if any.
- abstractmethod load(session: Any, ref: str, namespace: Namespace) Any¶
Turn ref into whatever the backend’s comparison accepts.
- module: ClassVar[str]¶
Module holding the
*Compareclass, imported on demand.
- name: ClassVar[str]¶
Value accepted by
--backend.
- open_session(namespace: Namespace, stack: ExitStack) Any¶
Return a session for this backend, or
Nonewhen none is needed.Implementations register teardown on stack so the session is closed on both the success and the failure path.
- class datacompy.cli.backends.PandasBackend¶
Bases:
CLIBackendCompare two files in memory with pandas.
- load(session: Any, ref: str, namespace: Namespace) DataFrame¶
Read ref into a
pandas.DataFrame.
- module: ClassVar[str] = 'datacompy.pandas'¶
Module holding the
*Compareclass, imported on demand.
- name: ClassVar[str] = 'pandas'¶
Value accepted by
--backend.
- class datacompy.cli.backends.PolarsBackend¶
Bases:
CLIBackendCompare two files in memory with polars.
- load(session: Any, ref: str, namespace: Namespace) DataFrame¶
Read ref into a
polars.DataFrame.
- module: ClassVar[str] = 'datacompy.polars'¶
Module holding the
*Compareclass, imported on demand.
- name: ClassVar[str] = 'polars'¶
Value accepted by
--backend.
- class datacompy.cli.backends.SnowflakeBackend¶
Bases:
CLIBackendCompare two Snowflake tables in place.
--leftand--rightare always table references for this backend, eitherdb.schema.tableorschema.table. Local files are read with--backend pandasor--backend polarsinstead.- build(namespace: Namespace, session: Any, left: Any, right: Any) BaseCompare¶
Construct a
SnowflakeCompare.
- extra: ClassVar[str | None] = 'snowflake'¶
Optional dependency extra required by this backend, if any.
- load(session: Any, ref: str, namespace: Namespace) str¶
Validate ref and return it as a fully qualified table name.
- Raises:
BadArgsError – When ref is not a two or three part dotted identifier, or when a two part reference cannot be qualified because the session has no current database.
- module: ClassVar[str] = 'datacompy.snowflake'¶
Module holding the
*Compareclass, imported on demand.
- name: ClassVar[str] = 'snowflake'¶
Value accepted by
--backend.
- open_session(namespace: Namespace, stack: ExitStack) Any¶
Return a Snowpark session built from
--snowflake-configor the environment.
- class datacompy.cli.backends.SparkBackend¶
Bases:
CLIBackendCompare two files with Spark SQL.
- build(namespace: Namespace, session: Any, left: Any, right: Any) BaseCompare¶
Construct a
SparkSQLCompare.
- extra: ClassVar[str | None] = 'spark'¶
Optional dependency extra required by this backend, if any.
- load(session: Any, ref: str, namespace: Namespace) Any¶
Read ref into a PySpark DataFrame.
- module: ClassVar[str] = 'datacompy.spark'¶
Module holding the
*Compareclass, imported on demand.
- name: ClassVar[str] = 'spark'¶
Value accepted by
--backend.
- open_session(namespace: Namespace, stack: ExitStack) Any¶
Return a
pyspark.sql.SparkSession, stopping it only if we made it.A SparkSession is process wide, so
getOrCreatereturns the caller’s existing session when there is one.datacompy.cli.main()is a public function that can be called in process from a notebook or an Airflow task, and stopping a session the CLI did not create would kill the caller’sSparkContextalong with it. Teardown is therefore registered only when this call is the one that created the session.For the same reason
--spark-app-namehas no effect when a session already exists: an application name cannot be changed once theSparkContextis running.The log level defaults to
ERRORso PySpark’s INFO and WARN chatter stays out of the CLI’s own output. Override it withDATACOMPY_SPARK_LOG_LEVEL.
- datacompy.cli.backends.compare_kwargs(namespace: Namespace, backend: str) dict[str, Any]¶
Build the
*Compareconstructor keyword arguments for backend.Walks
datacompy.cli.parser.OPTIONS, keeping the rows that name a constructor keyword and that apply to this backend. Values that resolve toNoneare omitted so the library default applies.
- datacompy.cli.backends.infer_delimiter(ref: str, override: str | None) str¶
Return the field delimiter for ref.
- Parameters:
ref (str) – File path or URI.
override (str, optional) – Explicit
--csv-delimitervalue. Returned as is when provided, and applied to both inputs. This is also how a comma is forced for a comma delimited file that happens to be named.tsv, because--input-formatselects the reader and says nothing about the delimiter.
- Returns:
The delimiter implied by the extension, or a comma for anything else.
- Return type:
str
- datacompy.cli.backends.infer_format(ref: str, override: str | None) str¶
Return the input format for ref.
- Parameters:
ref (str) – File path or URI.
override (str, optional) – Explicit
--input-formatvalue. Returned as is when provided.
- Returns:
One of
"csv","parquet", or"json".- Return type:
str
- Raises:
BadArgsError – When the extension is unrecognised and no override was given.
- datacompy.cli.backends.suspect_delimiter(ref: str, namespace: Namespace, frame: Any) str | None¶
Return a warning when frame looks like it was read with the wrong delimiter.
A CSV input read with the wrong delimiter collapses every row into one column whose name is the entire header line. Nothing fails at that point: the symptom surfaces later as a missing join column, or not at all under
--on-index, where two mangled strings are compared instead. This is the last place where the reference, the resolved format and the resolved delimiter are all still in hand, so the guess is made here.- Parameters:
ref (str) – The
--leftor--rightreference frame was read from.namespace (argparse.Namespace) – Parsed arguments, for the format and delimiter overrides.
frame (Any) – The loaded DataFrame. Only
columnsis read, which every file backend exposes without touching the data.
- Returns:
A warning message, or
Nonewhen the parse looks fine. Only a single column CSV whose one column name repeats a delimiter other than the one used is reported, because that is what a collapsed multi-column header looks like. A genuine single column file, a name that merely contains one such delimiter (for examplea;b), and a plain typo in--onall stay quiet.- Return type:
str or None
datacompy.cli.compare module¶
The datacompy compare subcommand.
- datacompy.cli.compare.run_compare(namespace: Namespace) int¶
Run a comparison and return the process exit code.
- Parameters:
namespace (argparse.Namespace) – Parsed arguments from the
comparesubparser.- Returns:
0when the datasets match or stay within--max-unequal-rows, and1when they differ. Problems with the arguments, the input files, or the backend raise aCLIError, whichdatacompy.cli.main()turns into exit code2.- Return type:
int
- datacompy.cli.compare.validate_arguments(namespace: Namespace) None¶
Reject argument combinations that argparse cannot express.
Per value rules (delimiter length, non negative counts, tolerance syntax) are enforced by the
type=callables indatacompy.cli.parser. This function covers the rules that need to look at more than one argument at a time.Must run before
datacompy.cli.parser.fill_defaults(), which is what makeswas_given()distinguish an explicitly passed flag from an absent one.- Raises:
BadArgsError – On any invalid combination.
- datacompy.cli.compare.within_threshold(namespace: Namespace, report_data: ReportData) bool¶
Return
Truewhen the comparison counts as a pass.Without
--max-unequal-rowsthis reproducesmatches(). With it, the datasets pass while the number of differing rows stays at or below the threshold, and while the columns line up unless--ignore-extra-columnswas given.Both branches read report_data, which
build_report_datahas already computed. Callingmatches()here instead would recount straight from the DataFrames, and on Spark and Snowflake each of those counts is a distributed action, so the default invocation would scan the data a second time after the report had already been rendered.
datacompy.cli.errors module¶
Exception hierarchy for the DataComPy command line interface.
Every exception defined here carries an exit_code so that
datacompy.cli.main() can catch CLIError at a single site and
translate it into a friendly message plus the right process exit code.
- exception datacompy.cli.errors.BadArgsError¶
Bases:
CLIErrorRaised when arguments are individually valid but invalid in combination.
- exception datacompy.cli.errors.CLIError¶
Bases:
ExceptionBase class for expected CLI failures. Always maps to exit code 2.
- exit_code: int = 2¶
datacompy.cli.output module¶
Report rendering and delivery for the DataComPy CLI.
Rendering and destination are independent: --report-format chooses between
text, JSON, and HTML, and --output chooses between stdout and a file. All
three renderings come from datacompy.report.ReportData, so the CLI adds
no templating of its own.
- datacompy.cli.output.emit(report_data: ReportData, report_format: str, output: Path | None, *, quiet: bool) None¶
Write the report to stdout, to output, or to both.
quietsuppresses stdout only. A file requested with--outputis always written, since asking for a file is an explicit request for it.- Raises:
OutputError – When the destination file cannot be written.
- datacompy.cli.output.print_error(message: str) None¶
Write message to stderr with a
datacompy:prefix.
- datacompy.cli.output.print_warning(message: str) None¶
Write message to stderr with a
datacompy: warning:prefix.Warnings are diagnostics rather than output, so they ignore
--quiet, which suppresses the report itself.
- datacompy.cli.output.render(report_data: ReportData, report_format: str) str¶
Render report_data in the requested format.
- Parameters:
report_data (datacompy.report.ReportData) – Structured comparison result from
compare.build_report_data().report_format ({"text", "json", "html"}) – Rendering to produce.
- Returns:
The rendered report.
- Return type:
str
datacompy.cli.parser module¶
Declarative argument specification for the DataComPy CLI.
The module holds a single source of truth, OPTIONS, describing every
option the compare subcommand accepts. Each Opt records both how
argparse should register the flag and which *Compare constructor keyword it
maps to, so build_parser() and
datacompy.cli.backends.compare_kwargs() are generated from the same data
rather than maintained as two parallel hand-written lists.
Adding a library keyword argument to the CLI is therefore a single new row, and
tests/cli/test_parser.py checks every Opt.kwarg against the real
constructor signature so the two can never silently drift apart.
- datacompy.cli.parser.GROUP_INPUT = 'input'¶
Argument group headings, in the order they appear in
--help.
- datacompy.cli.parser.OPTIONS_BY_FLAG: dict[str, Opt] = {'--abs-tol': Opt(flags=('--abs-tol',), help='Absolute tolerance for numeric comparisons (default 0). Accepts a single number applied to every column, or repeated COLUMN=VALUE pairs for per column tolerances.', group='comparison', kwarg='abs_tol', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=functools.partial(<function _combine_tolerances>, flag='--abs-tol'), default=None, options={'action': 'append', 'type': <function tolerance>, 'metavar': 'N|COL=N'}), '--backend': Opt(flags=('--backend',), help='Comparison backend. Polars is fast and the default. Use pandas for index based joins, spark for distributed data, or snowflake to compare tables in place.', group='backend', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default='polars', options={'choices': ['pandas', 'polars', 'snowflake', 'spark']}), '--cache-intermediates': Opt(flags=('--cache-intermediates',), help='Cache intermediate DataFrames (default: enabled). Pass --no-cache-intermediates on Databricks Serverless and other environments that do not support caching.', group='backend specific', kwarg='cache_intermediates', backends=frozenset({'spark'}), resolve=None, default=True, options={'action': <class 'argparse.BooleanOptionalAction'>}), '--cast-column-names-lower': Opt(flags=('--cast-column-names-lower',), help='Cast column names to lowercase before comparing (default: enabled). Not applicable to snowflake, which normalises identifiers to uppercase.', group='comparison', kwarg='cast_column_names_lower', backends=frozenset({'polars', 'spark', 'pandas'}), resolve=None, default=True, options={'action': <class 'argparse.BooleanOptionalAction'>}), '--column-count': Opt(flags=('--column-count',), help='Maximum number of columns to show in unique row samples (default 10).', group='report', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=10, options={'type': <function non_negative_int>, 'metavar': 'N'}), '--csv-delimiter': Opt(flags=('--csv-delimiter',), help="Field delimiter for CSV input. Inferred from each file extension, a tab for .tsv and a comma otherwise. This flag overrides inference for both inputs: use '\\t' for a tab separated file with an unusual extension, or ',' to force a comma for a comma separated file named .tsv.", group='input', kwarg=None, backends=frozenset({'polars', 'spark', 'pandas'}), resolve=None, default=None, options={'type': <function single_char>, 'metavar': 'CHAR'}), '--df1-name': Opt(flags=('--df1-name',), help='Label for the left dataset in the report (default: derived from --left).', group='naming', kwarg='df1_name', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=functools.partial(<function _resolve_dataset_name>, side='left'), default=None, options={'metavar': 'NAME'}), '--df2-name': Opt(flags=('--df2-name',), help='Label for the right dataset in the report (default: derived from --right).', group='naming', kwarg='df2_name', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=functools.partial(<function _resolve_dataset_name>, side='right'), default=None, options={'metavar': 'NAME'}), '--ignore-case': Opt(flags=('--ignore-case',), help='Ignore case in string columns.', group='comparison', kwarg='ignore_case', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=False, options={'action': 'store_true'}), '--ignore-extra-columns': Opt(flags=('--ignore-extra-columns',), help='Treat the datasets as matching even when one side has columns the other does not.', group='comparison', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=False, options={'action': 'store_true'}), '--ignore-spaces': Opt(flags=('--ignore-spaces',), help='Ignore leading and trailing whitespace in string columns.', group='comparison', kwarg='ignore_spaces', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=False, options={'action': 'store_true'}), '--ignore-unique-rows': Opt(flags=('--ignore-unique-rows',), help='With --max-unequal-rows, exclude rows that exist in only one dataset from the difference count.', group='report', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=False, options={'action': 'store_true'}), '--input-format': Opt(flags=('--input-format',), help='Force the input file format for both datasets. Omit to infer it from each file extension, which also handles mixed format inputs.', group='input', kwarg=None, backends=frozenset({'polars', 'spark', 'pandas'}), resolve=None, default=None, options={'choices': ['csv', 'parquet', 'json']}), '--left': Opt(flags=('--left',), help='Path, URI, or Snowflake table reference for the left dataset.', group='input', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=None, options={'required': True, 'metavar': 'REF'}), '--max-unequal-rows': Opt(flags=('--max-unequal-rows',), help='Exit 0 when the number of differing rows is at most N, and 1 otherwise. Counts value mismatches plus rows present in only one dataset; pass --ignore-unique-rows to count value mismatches only.', group='report', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=None, options={'type': <function non_negative_int>, 'metavar': 'N'}), '--on': Opt(flags=('--on',), help='Join column. Accepts a comma separated list (--on id,date) or repeated flags (--on id --on date). Use the repeated form for column names that contain a comma.', group='join keys', kwarg='join_columns', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=<function _flatten_join_columns>, default=None, options={'action': 'append', 'type': <function join_column_group>, 'metavar': 'COL[,COL...]'}), '--on-index': Opt(flags=('--on-index',), help='Join on the DataFrame index instead of columns. Pandas backend only.', group='join keys', kwarg='on_index', backends=frozenset({'pandas'}), resolve=None, default=False, options={'action': 'store_true'}), '--output': Opt(flags=('--output',), help='Write the report to this file instead of stdout. Parent directories are created as needed.', group='output', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=None, options={'type': <class 'pathlib.Path'>, 'metavar': 'PATH'}), '--quiet': Opt(flags=('--quiet',), help='Do not print the report to stdout. A file named by --output is still written. The exit code still reflects the result.', group='output', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=False, options={'action': 'store_true'}), '--rel-tol': Opt(flags=('--rel-tol',), help='Relative tolerance for numeric comparisons (default 0). Accepts a single number or repeated COLUMN=VALUE pairs.', group='comparison', kwarg='rel_tol', backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=functools.partial(<function _combine_tolerances>, flag='--rel-tol'), default=None, options={'action': 'append', 'type': <function tolerance>, 'metavar': 'N|COL=N'}), '--report-format': Opt(flags=('--report-format',), help='Report rendering (default: text).', group='output', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default='text', options={'choices': ['text', 'json', 'html']}), '--right': Opt(flags=('--right',), help='Path, URI, or Snowflake table reference for the right dataset.', group='input', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=None, options={'required': True, 'metavar': 'REF'}), '--sample-count': Opt(flags=('--sample-count',), help='Maximum number of sample mismatch rows to show per column (default 10).', group='report', kwarg=None, backends=frozenset({'polars', 'snowflake', 'spark', 'pandas'}), resolve=None, default=10, options={'type': <function non_negative_int>, 'metavar': 'N'}), '--snowflake-config': Opt(flags=('--snowflake-config',), help='Path to a JSON file of Snowflake connection parameters. When omitted the session is built from SNOWFLAKE_ACCOUNT plus one of SNOWFLAKE_TOKEN (OAuth), SNOWFLAKE_AUTHENTICATOR, or SNOWFLAKE_PASSWORD. SNOWFLAKE_USER is required for everything except OAuth, and SNOWFLAKE_ROLE, SNOWFLAKE_WAREHOUSE, SNOWFLAKE_DATABASE, and SNOWFLAKE_SCHEMA are optional.', group='backend specific', kwarg=None, backends=frozenset({'snowflake'}), resolve=None, default=None, options={'type': <class 'pathlib.Path'>, 'metavar': 'PATH'}), '--spark-app-name': Opt(flags=('--spark-app-name',), help='Spark application name.', group='backend specific', kwarg=None, backends=frozenset({'spark'}), resolve=None, default='datacompy-cli', options={'metavar': 'NAME'})}¶
Lookup from primary flag to specification row, for targeted validation.
- class datacompy.cli.parser.Opt(flags: tuple[str, ...], help: str, group: str, kwarg: str | None = None, backends: frozenset[str] = frozenset({'pandas', 'polars', 'snowflake', 'spark'}), resolve: ~collections.abc.Callable[[~typing.Any, ~argparse.Namespace], ~typing.Any] | None = None, default: ~typing.Any = None, options: dict[str, ~typing.Any] = <factory>)¶
Bases:
objectOne command line option and its mapping onto a
*Comparekeyword.- Variables:
flags (tuple of str) – Option strings passed to
argparse.ArgumentParser.add_argument.help (str) – Help text shown in
--help.group (str) – Argument group heading the option is listed under.
kwarg (str, optional) – Name of the
*Compareconstructor keyword this option supplies.Nonemarks the option as CLI only (for example--output).backends (frozenset of str) – Backends that accept this option. Passing the flag with any other backend is rejected by
datacompy.cli.compare.validate_arguments().resolve (callable, optional) – Post-processing applied to the raw parsed value before it is handed to the constructor. Receives
(raw_value, namespace). Used where the parsed shape differs from the library shape, such as flattening repeated--ongroups into a single list.default (Any) – Value used when the flag is absent. Options are registered with
argparse.SUPPRESSso that “left at the default” stays distinguishable from “explicitly passed”.options (dict) – Extra keyword arguments forwarded to
add_argument(action,type,choices,metavar,required).
- backends: frozenset[str] = frozenset({'pandas', 'polars', 'snowflake', 'spark'})¶
- default: Any = None¶
- property dest: str¶
The
argparsedestination attribute, derived from the first flag.
- flags: tuple[str, ...]¶
- group: str¶
- help: str¶
- kwarg: str | None = None¶
- options: dict[str, Any]¶
- resolve: Callable[[Any, Namespace], Any] | None = None¶
- resolved(namespace: Namespace) Any¶
Return the value in the shape the library constructor expects.
- was_given(namespace: Namespace) bool¶
Return
Truewhen the user actually passed this flag.
- datacompy.cli.parser.build_parser() ArgumentParser¶
Build the top level
datacompyargument parser.
- datacompy.cli.parser.default_dataset_name(ref: str, backend: str) str¶
Derive a report label from a file path or Snowflake table reference.
File paths use the stem, so
sales_data.parquetbecomessales_data. Snowflake references use the final segment, soPROD.ANALYTICS.SALESbecomesSALESrather than the misleadingPROD.ANALYTICSthatPath.stemwould produce.
- datacompy.cli.parser.fill_defaults(namespace: Namespace) None¶
Populate namespace in place with the default for every absent option.
Options are registered with
argparse.SUPPRESSso that an absent flag leaves no attribute behind, which is what makesOpt.was_given()meaningful. Calldatacompy.cli.compare.validate_arguments()before this function, because afterwards every option looks as though it was explicitly passed.
- datacompy.cli.parser.join_column_group(value: str) list[str]¶
Split a single
--onvalue on commas.Combined with
action="append"this makes--on id,date,--on id --on dateand any mix of the two equivalent. Column names that genuinely contain a comma must use the repeated form.
- datacompy.cli.parser.non_negative_int(value: str) int¶
Accept a non negative integer.
- datacompy.cli.parser.package_version() str¶
Return the datacompy version.
Read from the package itself rather than from installed distribution metadata, because
pyproject.tomlderives the distribution version fromdatacompy.__version__and an editable install can carry stale metadata.
- datacompy.cli.parser.single_char(value: str) str¶
Accept a one character delimiter, translating a literal
\tto a tab.
- datacompy.cli.parser.tolerance(value: str) float | tuple[str, float]¶
Parse a tolerance as either a bare number or a
COLUMN=VALUEpair.A bare number applies to every numeric column. Repeated
COLUMN=VALUEpairs are collected into the per column dictionary thatdatacompy.base.validate_tolerance_parameter()accepts.
Module contents¶
DataComPy command line interface.
Invoked as datacompy once installed, or as python -m datacompy.
Examples
Compare two CSV files with the polars backend, which is the default:
datacompy compare --left before.csv --right after.csv --on id
Emit a machine readable report for a CI pipeline and rely on the exit code:
datacompy compare --left a.parquet --right b.parquet --on id,date \\
--report-format json --max-unequal-rows 0
Write an HTML report to a file:
datacompy compare --left a.csv --right b.csv --on id \\
--report-format html --output report.html
- datacompy.cli.COMMANDS: dict[str, Callable[[Namespace], int]] = {'compare': <function run_compare>}¶
Subcommand name to handler. Adding a command is additive.
- datacompy.cli.build_parser() ArgumentParser¶
Build the top level
datacompyargument parser.
- datacompy.cli.main(argv: Sequence[str] | None = None) int¶
Parse argv, dispatch the subcommand, and return the exit code.
- Parameters:
argv (sequence of str, optional) – Argument list. When
None, argparse readssys.argv.- Returns:
0on a match,1on a mismatch,2on an expected error, and130on interrupt. Argparse exits with2itself on a parse failure, before this function returns.- Return type:
int