From e8a4dcabe83e42374e289ec804c7eee439ece97a Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Fri, 23 Feb 2024 19:02:12 -0600 Subject: [PATCH 01/62] Add ProveOptions and PrintOptions --- src/pyk/__main__.py | 68 +++++++++++++++++++------------------- src/pyk/cli/args.py | 79 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 110 insertions(+), 37 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 84d340ca6..a65319f48 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -4,7 +4,6 @@ import logging import sys from argparse import ArgumentParser, FileType -from enum import Enum from pathlib import Path from typing import TYPE_CHECKING @@ -13,7 +12,7 @@ from pyk.kast.inner import KInner from pyk.kore.rpc import ExecuteResult -from .cli.args import KCLIArgs +from .cli.args import KCLIArgs, PrintInput, generate_command_options from .cli.utils import LOG_FORMAT, dir_path, loglevel from .coverage import get_rule_by_id, strip_coverage_logger from .cterm import CTerm @@ -39,13 +38,10 @@ from argparse import Namespace from typing import Any, Final - -_LOGGER: Final = logging.getLogger(__name__) + from .cli.args import PrintOptions, ProveOptions -class PrintInput(Enum): - KORE_JSON = 'kore-json' - KAST_JSON = 'kast-json' +_LOGGER: Final = logging.getLogger(__name__) def main() -> None: @@ -57,6 +53,8 @@ def main() -> None: cli_parser = create_argument_parser() args = cli_parser.parse_args() + options = generate_command_options(vars(args)) + logging.basicConfig(level=loglevel(args), format=LOG_FORMAT) executor_name = 'exec_' + args.command.lower().replace('-', '_') @@ -64,29 +62,29 @@ def main() -> None: raise AssertionError(f'Unimplemented command: {args.command}') execute = globals()[executor_name] - execute(args) + execute(options) -def exec_print(args: Namespace) -> None: - kompiled_dir: Path = args.definition_dir +def exec_print(options: PrintOptions) -> None: + kompiled_dir: Path = options.definition_dir printer = KPrint(kompiled_dir) - if args.input == PrintInput.KORE_JSON: - _LOGGER.info(f'Reading Kore JSON from file: {args.term.name}') - kore = Pattern.from_json(args.term.read()) + if options.input == PrintInput.KORE_JSON: + _LOGGER.info(f'Reading Kore JSON from file: {options.term.name}') + kore = Pattern.from_json(options.term.read()) term = printer.kore_to_kast(kore) else: - _LOGGER.info(f'Reading Kast JSON from file: {args.term.name}') - term = KInner.from_json(args.term.read()) + _LOGGER.info(f'Reading Kast JSON from file: {options.term.name}') + term = KInner.from_json(options.term.read()) if is_top(term): - args.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {args.output_file.name}') + options.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {options.output_file.name}') else: - if args.minimize: - if args.omit_labels != '' and args.keep_cells != '': + if options.minimize: + if options.omit_labels != None and options.keep_cells != None: raise ValueError('You cannot use both --omit-labels and --keep-cells.') - abstract_labels = args.omit_labels.split(',') if args.omit_labels != '' else [] - keep_cells = args.keep_cells.split(',') if args.keep_cells != '' else [] + abstract_labels = options.omit_labels.split(',') if options.omit_labels is not None else [] + keep_cells = options.keep_cells.split(',') if options.keep_cells is not None else [] minimized_disjuncts = [] for disjunct in flatten_label('#Or', term): @@ -102,8 +100,8 @@ def exec_print(args: Namespace) -> None: minimized_disjuncts.append(config) term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) - args.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {args.output_file.name}') + options.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {options.output_file.name}') def exec_rpc_print(args: Namespace) -> None: @@ -210,12 +208,12 @@ def exec_rpc_kast(args: Namespace) -> None: args.output_file.write(json.dumps(request)) -def exec_prove(args: Namespace) -> None: - kompiled_dir: Path = args.definition_dir - kprover = KProve(kompiled_dir, args.main_file) - final_state = kprover.prove(Path(args.spec_file), spec_module_name=args.spec_module, args=args.kArgs) - args.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) - _LOGGER.info(f'Wrote file: {args.output_file.name}') +def exec_prove(options: ProveOptions) -> None: + kompiled_dir: Path = options.definition_dir + kprover = KProve(kompiled_dir, options.main_file) + final_state = kprover.prove(Path(options.spec_file), spec_module_name=options.spec_module, args=options.k_args) + options.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) + _LOGGER.info(f'Wrote file: {options.output_file.name}') def exec_graph_imports(args: Namespace) -> None: @@ -274,12 +272,12 @@ def create_argument_parser() -> ArgumentParser: parents=[k_cli_args.logging_args, definition_args, k_cli_args.display_args], ) print_args.add_argument('term', type=FileType('r'), help='Input term (in format specified with --input).') - print_args.add_argument('--input', default=PrintInput.KAST_JSON, type=PrintInput, choices=list(PrintInput)) - print_args.add_argument('--omit-labels', default='', nargs='?', help='List of labels to omit from output.') + print_args.add_argument('--input', default=None, type=PrintInput, choices=list(PrintInput)) + print_args.add_argument('--omit-labels', default=None, nargs='?', help='List of labels to omit from output.') print_args.add_argument( - '--keep-cells', default='', nargs='?', help='List of cells with primitive values to keep in output.' + '--keep-cells', default=None, nargs='?', help='List of cells with primitive values to keep in output.' ) - print_args.add_argument('--output-file', type=FileType('w'), default='-') + print_args.add_argument('--output-file', type=str, default=None) rpc_print_args = pyk_args_command.add_parser( 'rpc-print', @@ -318,8 +316,8 @@ def create_argument_parser() -> ArgumentParser: prove_args.add_argument('main_file', type=str, help='Main file used for kompilation.') prove_args.add_argument('spec_file', type=str, help='File with the specification module.') prove_args.add_argument('spec_module', type=str, help='Module with claims to be proven.') - prove_args.add_argument('--output-file', type=FileType('w'), default='-') - prove_args.add_argument('kArgs', nargs='*', help='Arguments to pass through to K invocation.') + prove_args.add_argument('--output-file', type=str, default=None) + prove_args.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') pyk_args_command.add_parser( 'graph-imports', diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 47b633cf6..64b510b5a 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -1,18 +1,93 @@ from __future__ import annotations +import sys from argparse import ArgumentParser +from enum import Enum from functools import cached_property -from typing import TYPE_CHECKING +from typing import IO, TYPE_CHECKING, Any, Iterable from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path if TYPE_CHECKING: + from pathlib import Path from typing import TypeVar T = TypeVar('T') +class PrintInput(Enum): + KORE_JSON = 'kore-json' + KAST_JSON = 'kast-json' + + +def generate_command_options(args: dict[str, Any]) -> Options: + command = args['command'].lower() + match command: + case 'print': + return PrintOptions(args) + case 'rpc-print': + raise ValueError('Not implemented.') + case 'rpc-kast': + raise ValueError('Not implemented.') + case 'prove': + return ProveOptions(args) + case 'graph-imports': + raise ValueError('Not implemented.') + case 'coverage': + raise ValueError('Not implemented.') + case 'kore-to-json': + raise ValueError('Not implemented.') + case 'json-to-kore': + raise ValueError('Not implemented.') + case _: + raise ValueError('Unrecognized command.') + + +class Options: + ... + + +class PrintOptions(Options): + def __init__(self, args: dict[str, Any]) -> None: + self.definition_dir = args['definition_dir'] + self.term = args['term'] + + self.input = PrintInput.KAST_JSON if args['input'] is None else args['input'] + self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + self.minimize = True if args['minimize'] is None else args['minimize'] + self.omit_labels = args['omit_labels'] + self.keep_cells = args['keep_cells'] + + definition_dir: Path + term: IO[Any] + + input: PrintInput + output_file: IO[Any] + minimize: bool + omit_labels: str | None + keep_cells: str | None + + +class ProveOptions(Options): + def __init__(self, args: dict[str, Any]) -> None: + self.definition_dir = args['definition_dir'] + self.main_file = args['main_file'] + self.spec_file = args['spec_file'] + self.spec_module = args['spec_module'] + + self.k_args = args['k_args'] + + self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + + definition_dir: Path + main_file: Path + spec_file: Path + spec_module: str + k_args: Iterable[str] + output_file: IO[Any] + + class KCLIArgs: @cached_property def logging_args(self) -> ArgumentParser: @@ -112,7 +187,7 @@ def smt_args(self) -> ArgumentParser: @cached_property def display_args(self) -> ArgumentParser: args = ArgumentParser(add_help=False) - args.add_argument('--minimize', dest='minimize', default=True, action='store_true', help='Minimize output.') + args.add_argument('--minimize', dest='minimize', default=None, action='store_true', help='Minimize output.') args.add_argument('--no-minimize', dest='minimize', action='store_false', help='Do not minimize output.') return args From 573ba5d2e437b44888fbe7f07e9c76a6bd1917b9 Mon Sep 17 00:00:00 2001 From: devops Date: Sat, 24 Feb 2024 01:03:12 +0000 Subject: [PATCH 02/62] Set Version: 0.1.652 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c0d5fe413..cb1b74f20 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.651' -release = '0.1.651' +version = '0.1.652' +release = '0.1.652' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index 3b0aef7c2..6f983f2ac 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.651 +0.1.652 diff --git a/pyproject.toml b/pyproject.toml index ec5c676bf..250a351ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.651" +version = "0.1.652" description = "" authors = [ "Runtime Verification, Inc. ", From 281a02738935df650774dd58cb981904185a6b34 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 26 Feb 2024 13:43:48 -0600 Subject: [PATCH 03/62] Add other commands --- src/pyk/__main__.py | 4 ++- src/pyk/cli/args.py | 82 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index a65319f48..15d5016c1 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -271,7 +271,9 @@ def create_argument_parser() -> ArgumentParser: help='Pretty print a term.', parents=[k_cli_args.logging_args, definition_args, k_cli_args.display_args], ) - print_args.add_argument('term', type=FileType('r'), help='Input term (in format specified with --input).') + print_args.add_argument( + 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' + ) print_args.add_argument('--input', default=None, type=PrintInput, choices=list(PrintInput)) print_args.add_argument('--omit-labels', default=None, nargs='?', help='List of labels to omit from output.') print_args.add_argument( diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 64b510b5a..6434a1f31 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -27,19 +27,19 @@ def generate_command_options(args: dict[str, Any]) -> Options: case 'print': return PrintOptions(args) case 'rpc-print': - raise ValueError('Not implemented.') + return RPCPrintOptions(args) case 'rpc-kast': - raise ValueError('Not implemented.') + return RPCKastOptions(args) case 'prove': return ProveOptions(args) case 'graph-imports': - raise ValueError('Not implemented.') + return GraphImportsOptions(args) case 'coverage': - raise ValueError('Not implemented.') + return CoverageOptions(args) case 'kore-to-json': - raise ValueError('Not implemented.') + return Options() case 'json-to-kore': - raise ValueError('Not implemented.') + return Options() case _: raise ValueError('Unrecognized command.') @@ -48,17 +48,51 @@ class Options: ... -class PrintOptions(Options): +class CoverageOptions(Options): + definition_dir: Path + coverage_file: IO[Any] + output: IO[Any] + def __init__(self, args: dict[str, Any]) -> None: self.definition_dir = args['definition_dir'] - self.term = args['term'] + self.coverage_file = args['response_file'] + self.output = sys.stdout if args['output'] is None else args['output'] + + +class GraphImportsOptions(Options): + definition_dir: Path + + def __init__(self, args: dict[str, Any]) -> None: + self.definition_dir = args['definition_dir'] + + +class RPCKastOptions(Options): + reference_request_file: IO[Any] + response_file: IO[Any] + + output_file: IO[Any] + + def __init__(self, args: dict[str, Any]) -> None: + self.reference_request_file = args['reference_request_file'] + self.response_file = args['response_file'] - self.input = PrintInput.KAST_JSON if args['input'] is None else args['input'] self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] - self.minimize = True if args['minimize'] is None else args['minimize'] - self.omit_labels = args['omit_labels'] - self.keep_cells = args['keep_cells'] + +class RPCPrintOptions(Options): + definition_dir: Path + input_file: IO[Any] + + output_file: IO[Any] + + def __init__(self, args: dict[str, Any]) -> None: + self.definition_dir = args['definition_dir'] + self.input_file = args['input_file'] + + self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + + +class PrintOptions(Options): definition_dir: Path term: IO[Any] @@ -68,18 +102,18 @@ def __init__(self, args: dict[str, Any]) -> None: omit_labels: str | None keep_cells: str | None - -class ProveOptions(Options): def __init__(self, args: dict[str, Any]) -> None: self.definition_dir = args['definition_dir'] - self.main_file = args['main_file'] - self.spec_file = args['spec_file'] - self.spec_module = args['spec_module'] - - self.k_args = args['k_args'] + self.term = args['term'] + self.input = PrintInput.KAST_JSON if args['input'] is None else args['input'] self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + self.minimize = True if args['minimize'] is None else args['minimize'] + self.omit_labels = args['omit_labels'] + self.keep_cells = args['keep_cells'] + +class ProveOptions(Options): definition_dir: Path main_file: Path spec_file: Path @@ -87,6 +121,16 @@ def __init__(self, args: dict[str, Any]) -> None: k_args: Iterable[str] output_file: IO[Any] + def __init__(self, args: dict[str, Any]) -> None: + self.definition_dir = args['definition_dir'] + self.main_file = args['main_file'] + self.spec_file = args['spec_file'] + self.spec_module = args['spec_module'] + + self.k_args = args['k_args'] + + self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + class KCLIArgs: @cached_property From c82090f70cf44348ac35012218934ca1ddf649b2 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 26 Feb 2024 13:47:39 -0600 Subject: [PATCH 04/62] Remove default values from add_argument --- src/pyk/__main__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 15d5016c1..26677bd27 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -291,7 +291,7 @@ def create_argument_parser() -> ArgumentParser: type=FileType('r'), help='An input file containing the JSON RPC request or response with KoreJSON payload.', ) - rpc_print_args.add_argument('--output-file', type=FileType('w'), default='-') + rpc_print_args.add_argument('--output-file', type=FileType('w'), default=None) rpc_kast_args = pyk_args_command.add_parser( 'rpc-kast', @@ -308,7 +308,7 @@ def create_argument_parser() -> ArgumentParser: type=FileType('r'), help='An input file containing a JSON RPC response with KoreJSON payload.', ) - rpc_kast_args.add_argument('--output-file', type=FileType('w'), default='-') + rpc_kast_args.add_argument('--output-file', type=FileType('w'), default=None) prove_args = pyk_args_command.add_parser( 'prove', @@ -333,7 +333,7 @@ def create_argument_parser() -> ArgumentParser: parents=[k_cli_args.logging_args, definition_args], ) coverage_args.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') - coverage_args.add_argument('-o', '--output', type=FileType('w'), default='-') + coverage_args.add_argument('-o', '--output', type=FileType('w'), default=None) pyk_args_command.add_parser('kore-to-json', help='Convert textual KORE to JSON', parents=[k_cli_args.logging_args]) From e1c762b545a2344cad261f8fe069ffc88508708e Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 26 Feb 2024 20:28:23 -0600 Subject: [PATCH 05/62] Handle parsing within Options classes --- src/pyk/__main__.py | 103 ++++------------ src/pyk/cli/args.py | 271 +++++++++++++++++++++++++++++++++---------- src/pyk/cli/utils.py | 3 +- 3 files changed, 232 insertions(+), 145 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 26677bd27..2376f1785 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -3,7 +3,7 @@ import json import logging import sys -from argparse import ArgumentParser, FileType +from argparse import ArgumentParser from pathlib import Path from typing import TYPE_CHECKING @@ -12,7 +12,18 @@ from pyk.kast.inner import KInner from pyk.kore.rpc import ExecuteResult -from .cli.args import KCLIArgs, PrintInput, generate_command_options +from .cli.args import ( + CoverageOptions, + GraphImportsOptions, + JsonToKoreOptions, + KoreToJsonOptions, + PrintInput, + PrintOptions, + ProveOptions, + RPCKastOptions, + RPCPrintOptions, + generate_command_options, +) from .cli.utils import LOG_FORMAT, dir_path, loglevel from .coverage import get_rule_by_id, strip_coverage_logger from .cterm import CTerm @@ -38,8 +49,6 @@ from argparse import Namespace from typing import Any, Final - from .cli.args import PrintOptions, ProveOptions - _LOGGER: Final = logging.getLogger(__name__) @@ -53,9 +62,9 @@ def main() -> None: cli_parser = create_argument_parser() args = cli_parser.parse_args() - options = generate_command_options(vars(args)) + options = generate_command_options({key: val for (key, val) in vars(args).items() if val is not None}) - logging.basicConfig(level=loglevel(args), format=LOG_FORMAT) + logging.basicConfig(level=loglevel(options), format=LOG_FORMAT) executor_name = 'exec_' + args.command.lower().replace('-', '_') if executor_name not in globals(): @@ -258,86 +267,20 @@ def exec_json_to_kore(args: dict[str, Any]) -> None: def create_argument_parser() -> ArgumentParser: - k_cli_args = KCLIArgs() - definition_args = ArgumentParser(add_help=False) definition_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.') pyk_args = ArgumentParser() pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) - print_args = pyk_args_command.add_parser( - 'print', - help='Pretty print a term.', - parents=[k_cli_args.logging_args, definition_args, k_cli_args.display_args], - ) - print_args.add_argument( - 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' - ) - print_args.add_argument('--input', default=None, type=PrintInput, choices=list(PrintInput)) - print_args.add_argument('--omit-labels', default=None, nargs='?', help='List of labels to omit from output.') - print_args.add_argument( - '--keep-cells', default=None, nargs='?', help='List of cells with primitive values to keep in output.' - ) - print_args.add_argument('--output-file', type=str, default=None) - - rpc_print_args = pyk_args_command.add_parser( - 'rpc-print', - help='Pretty-print an RPC request/response', - parents=[k_cli_args.logging_args, definition_args], - ) - rpc_print_args.add_argument( - 'input_file', - type=FileType('r'), - help='An input file containing the JSON RPC request or response with KoreJSON payload.', - ) - rpc_print_args.add_argument('--output-file', type=FileType('w'), default=None) - - rpc_kast_args = pyk_args_command.add_parser( - 'rpc-kast', - help='Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.', - parents=[k_cli_args.logging_args], - ) - rpc_kast_args.add_argument( - 'reference_request_file', - type=FileType('r'), - help='An input file containing a JSON RPC request to server as a reference for the new request.', - ) - rpc_kast_args.add_argument( - 'response_file', - type=FileType('r'), - help='An input file containing a JSON RPC response with KoreJSON payload.', - ) - rpc_kast_args.add_argument('--output-file', type=FileType('w'), default=None) - - prove_args = pyk_args_command.add_parser( - 'prove', - help='Prove an input specification (using kprovex).', - parents=[k_cli_args.logging_args, definition_args], - ) - prove_args.add_argument('main_file', type=str, help='Main file used for kompilation.') - prove_args.add_argument('spec_file', type=str, help='File with the specification module.') - prove_args.add_argument('spec_module', type=str, help='Module with claims to be proven.') - prove_args.add_argument('--output-file', type=str, default=None) - prove_args.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') - - pyk_args_command.add_parser( - 'graph-imports', - help='Graph the imports of a given definition.', - parents=[k_cli_args.logging_args, definition_args], - ) - - coverage_args = pyk_args_command.add_parser( - 'coverage', - help='Convert coverage file to human readable log.', - parents=[k_cli_args.logging_args, definition_args], - ) - coverage_args.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') - coverage_args.add_argument('-o', '--output', type=FileType('w'), default=None) - - pyk_args_command.add_parser('kore-to-json', help='Convert textual KORE to JSON', parents=[k_cli_args.logging_args]) - - pyk_args_command.add_parser('json-to-kore', help='Convert JSON to textual KORE', parents=[k_cli_args.logging_args]) + pyk_args_command = PrintOptions.parser(pyk_args_command) + pyk_args_command = RPCPrintOptions.parser(pyk_args_command) + pyk_args_command = RPCKastOptions.parser(pyk_args_command) + pyk_args_command = ProveOptions.parser(pyk_args_command) + pyk_args_command = GraphImportsOptions.parser(pyk_args_command) + pyk_args_command = CoverageOptions.parser(pyk_args_command) + pyk_args_command = KoreToJsonOptions.parser(pyk_args_command) + pyk_args_command = JsonToKoreOptions.parser(pyk_args_command) return pyk_args diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 6434a1f31..d42e9b45b 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -1,15 +1,16 @@ from __future__ import annotations import sys -from argparse import ArgumentParser +from argparse import ArgumentParser, FileType from enum import Enum from functools import cached_property -from typing import IO, TYPE_CHECKING, Any, Iterable +from typing import IO, TYPE_CHECKING, Any, Iterable, Type from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path if TYPE_CHECKING: + from argparse import _SubParsersAction from pathlib import Path from typing import TypeVar @@ -21,7 +22,7 @@ class PrintInput(Enum): KAST_JSON = 'kast-json' -def generate_command_options(args: dict[str, Any]) -> Options: +def generate_command_options(args: dict[str, Any]) -> LoggingOptions: command = args['command'].lower() match command: case 'print': @@ -37,99 +38,248 @@ def generate_command_options(args: dict[str, Any]) -> Options: case 'coverage': return CoverageOptions(args) case 'kore-to-json': - return Options() + return KoreToJsonOptions(args) case 'json-to-kore': - return Options() + return JsonToKoreOptions(args) case _: raise ValueError('Unrecognized command.') -class Options: - ... +class Options(object): + def __init__(self, args: dict[str, Any]) -> None: + defaults: dict[str, Any] = {} + mro = type(self).mro() + mro.reverse() + for cl in mro: + if hasattr(cl, 'default'): + defaults = defaults | cl.default() + + _args = defaults | args + + for attr, val in _args.items(): + self.__setattr__(attr, val) + + @classmethod + def all_args(cls: Type[Options]) -> ArgumentParser: + parser = ArgumentParser(add_help=False) + mro = set(cls.mro()) + for cl in mro: + if hasattr(cl, 'args') and 'args' in cl.__dict__: + parser = cl.args(parser) + return parser + + +class LoggingOptions(Options): + debug: bool + verbose: bool + + @staticmethod + def default() -> dict[str, Any]: + return { + 'verbose': False, + 'debug': False, + } + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('--verbose', '-v', default=None, action='store_true', help='Verbose output.') + parser.add_argument('--debug', default=None, action='store_true', help='Debug output.') + return parser + + +class JsonToKoreOptions(LoggingOptions): + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'json-to-kore', + help='Convert JSON to textual KORE', + parents=[JsonToKoreOptions.all_args()], + ) + return base + + +class KoreToJsonOptions(LoggingOptions): + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'kore-to-json', + help='Convert textual KORE to JSON', + parents=[KoreToJsonOptions.all_args()], + ) + return base + +class OutputFileOptions(Options): + output_file: IO[Any] + + @staticmethod + def default() -> dict[str, Any]: + return { + 'output_file': sys.stdout, + } + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('--output-file', type=FileType('w'), default=None) + return parser -class CoverageOptions(Options): + +class DefinitionOptions(LoggingOptions): definition_dir: Path + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('definition_dir', type=dir_path, help='Path to definition directory.') + return parser + + +class CoverageOptions(DefinitionOptions, OutputFileOptions): coverage_file: IO[Any] - output: IO[Any] - def __init__(self, args: dict[str, Any]) -> None: - self.definition_dir = args['definition_dir'] - self.coverage_file = args['response_file'] - self.output = sys.stdout if args['output'] is None else args['output'] + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'coverage', + help='Convert coverage file to human readable log.', + parents=[CoverageOptions.all_args()], + ) + return base + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') + return parser -class GraphImportsOptions(Options): - definition_dir: Path - def __init__(self, args: dict[str, Any]) -> None: - self.definition_dir = args['definition_dir'] +class GraphImportsOptions(DefinitionOptions): + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'graph-imports', + help='Graph the imports of a given definition.', + parents=[GraphImportsOptions.all_args()], + ) + return base -class RPCKastOptions(Options): +class RPCKastOptions(DefinitionOptions, OutputFileOptions): reference_request_file: IO[Any] response_file: IO[Any] - output_file: IO[Any] - - def __init__(self, args: dict[str, Any]) -> None: - self.reference_request_file = args['reference_request_file'] - self.response_file = args['response_file'] - - self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'rpc-kast', + help='Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.', + parents=[RPCKastOptions.all_args()], + ) + return base + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( + 'reference_request_file', + type=FileType('r'), + help='An input file containing a JSON RPC request to server as a reference for the new request.', + ) + parser.add_argument( + 'response_file', + type=FileType('r'), + help='An input file containing a JSON RPC response with KoreJSON payload.', + ) + return parser -class RPCPrintOptions(Options): - definition_dir: Path +class RPCPrintOptions(DefinitionOptions, OutputFileOptions): input_file: IO[Any] - output_file: IO[Any] + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'rpc-print', + help='Pretty-print an RPC request/response', + parents=[RPCPrintOptions.all_args()], + ) + return base + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( + 'input_file', + type=FileType('r'), + help='An input file containing the JSON RPC request or response with KoreJSON payload.', + ) + return parser - def __init__(self, args: dict[str, Any]) -> None: - self.definition_dir = args['definition_dir'] - self.input_file = args['input_file'] - self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] +class DisplayOptions(Options): + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('--minimize', dest='minimize', default=None, action='store_true', help='Minimize output.') + parser.add_argument('--no-minimize', dest='minimize', action='store_false', help='Do not minimize output.') + return parser -class PrintOptions(Options): - definition_dir: Path +class PrintOptions(DefinitionOptions, OutputFileOptions, DisplayOptions): term: IO[Any] - input: PrintInput - output_file: IO[Any] minimize: bool omit_labels: str | None keep_cells: str | None - def __init__(self, args: dict[str, Any]) -> None: - self.definition_dir = args['definition_dir'] - self.term = args['term'] - - self.input = PrintInput.KAST_JSON if args['input'] is None else args['input'] - self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] - self.minimize = True if args['minimize'] is None else args['minimize'] - self.omit_labels = args['omit_labels'] - self.keep_cells = args['keep_cells'] + @staticmethod + def default() -> dict[str, Any]: + return { + 'input': PrintInput.KAST_JSON, + 'minimize': True, + 'omit_labels': None, + 'keep_cells': None, + } + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( + 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' + ) + parser.add_argument('--input', default=None, type=PrintInput, choices=list(PrintInput)) + parser.add_argument('--omit-labels', default=None, nargs='?', help='List of labels to omit from output.') + parser.add_argument( + '--keep-cells', default=None, nargs='?', help='List of cells with primitive values to keep in output.' + ) + return parser + + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'print', + help='Pretty print a term.', + parents=[PrintOptions.all_args()], + ) + return base -class ProveOptions(Options): - definition_dir: Path +class ProveOptions(DefinitionOptions, OutputFileOptions): main_file: Path spec_file: Path spec_module: str k_args: Iterable[str] - output_file: IO[Any] - - def __init__(self, args: dict[str, Any]) -> None: - self.definition_dir = args['definition_dir'] - self.main_file = args['main_file'] - self.spec_file = args['spec_file'] - self.spec_module = args['spec_module'] - self.k_args = args['k_args'] - - self.output_file = sys.stdout if args['output_file'] is None else args['output_file'] + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('main_file', type=str, help='Main file used for kompilation.') + parser.add_argument('spec_file', type=str, help='File with the specification module.') + parser.add_argument('spec_module', type=str, help='Module with claims to be proven.') + parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') + return parser + + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'prove', + help='Prove an input specification (using kprovex).', + parents=[ProveOptions.all_args()], + ) + return base class KCLIArgs: @@ -228,13 +378,6 @@ def smt_args(self) -> ArgumentParser: ) return args - @cached_property - def display_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('--minimize', dest='minimize', default=None, action='store_true', help='Minimize output.') - args.add_argument('--no-minimize', dest='minimize', action='store_false', help='Do not minimize output.') - return args - @cached_property def definition_args(self) -> ArgumentParser: args = ArgumentParser(add_help=False) diff --git a/src/pyk/cli/utils.py b/src/pyk/cli/utils.py index c98320fdd..4f236d0d5 100644 --- a/src/pyk/cli/utils.py +++ b/src/pyk/cli/utils.py @@ -12,6 +12,7 @@ from typing import Final, TypeVar from ..kcfg.kcfg import NodeIdLike + from .args import LoggingOptions T1 = TypeVar('T1') T2 = TypeVar('T2') @@ -19,7 +20,7 @@ LOG_FORMAT: Final = '%(levelname)s %(asctime)s %(name)s - %(message)s' -def loglevel(args: Namespace) -> int: +def loglevel(args: LoggingOptions | Namespace) -> int: if args.debug: return logging.DEBUG From e34d10996790d79aec0fce67d0b78f82cc03ef08 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 26 Feb 2024 20:34:01 -0600 Subject: [PATCH 06/62] Add comments --- src/pyk/cli/args.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index d42e9b45b..43bc46a4f 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -47,6 +47,7 @@ def generate_command_options(args: dict[str, Any]) -> LoggingOptions: class Options(object): def __init__(self, args: dict[str, Any]) -> None: + # Get defaults from all subclasses that define them, preferring the most specific class defaults: dict[str, Any] = {} mro = type(self).mro() mro.reverse() @@ -54,6 +55,7 @@ def __init__(self, args: dict[str, Any]) -> None: if hasattr(cl, 'default'): defaults = defaults | cl.default() + # Overwrite defaults with args from command line _args = defaults | args for attr, val in _args.items(): @@ -61,6 +63,7 @@ def __init__(self, args: dict[str, Any]) -> None: @classmethod def all_args(cls: Type[Options]) -> ArgumentParser: + # Collect args from all superclasses parser = ArgumentParser(add_help=False) mro = set(cls.mro()) for cl in mro: From 4f75918b015f5fcde3c024750c388f6a05502205 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 26 Feb 2024 20:42:31 -0600 Subject: [PATCH 07/62] Use classes in exec_ functions --- src/pyk/__main__.py | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 2376f1785..3a1261a5a 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -46,7 +46,6 @@ from .prelude.ml import is_top, mlAnd, mlOr if TYPE_CHECKING: - from argparse import Namespace from typing import Any, Final @@ -113,10 +112,10 @@ def exec_print(options: PrintOptions) -> None: _LOGGER.info(f'Wrote file: {options.output_file.name}') -def exec_rpc_print(args: Namespace) -> None: - kompiled_dir: Path = args.definition_dir +def exec_rpc_print(options: RPCPrintOptions) -> None: + kompiled_dir: Path = options.definition_dir printer = KPrint(kompiled_dir) - input_dict = json.loads(args.input_file.read()) + input_dict = json.loads(options.input_file.read()) output_buffer = [] def pretty_print_request(request_params: dict[str, Any]) -> list[str]: @@ -185,8 +184,8 @@ def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: except KeyError as e: _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') exit(1) - if args.output_file is not None: - args.output_file.write('\n'.join(output_buffer)) + if options.output_file is not None: + options.output_file.write('\n'.join(output_buffer)) else: print('\n'.join(output_buffer)) except ValueError as e: @@ -195,13 +194,13 @@ def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: exit(1) -def exec_rpc_kast(args: Namespace) -> None: +def exec_rpc_kast(options: RPCKastOptions) -> None: """ Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, copying parameters from a reference request. """ - reference_request = json.loads(args.reference_request_file.read()) - input_dict = json.loads(args.response_file.read()) + reference_request = json.loads(options.reference_request_file.read()) + input_dict = json.loads(options.response_file.read()) execute_result = ExecuteResult.from_dict(input_dict['result']) non_state_keys = set(reference_request['params'].keys()).difference(['state']) request_params = {} @@ -214,7 +213,7 @@ def exec_rpc_kast(args: Namespace) -> None: 'method': reference_request['method'], 'params': request_params, } - args.output_file.write(json.dumps(request)) + options.output_file.write(json.dumps(request)) def exec_prove(options: ProveOptions) -> None: @@ -225,8 +224,8 @@ def exec_prove(options: ProveOptions) -> None: _LOGGER.info(f'Wrote file: {options.output_file.name}') -def exec_graph_imports(args: Namespace) -> None: - kompiled_dir: Path = args.definition_dir +def exec_graph_imports(options: GraphImportsOptions) -> None: + kompiled_dir: Path = options.definition_dir kprinter = KPrint(kompiled_dir) definition = kprinter.definition import_graph = Digraph() @@ -240,26 +239,26 @@ def exec_graph_imports(args: Namespace) -> None: _LOGGER.info(f'Wrote file: {graph_file}') -def exec_coverage(args: Namespace) -> None: - kompiled_dir: Path = args.definition_dir +def exec_coverage(options: CoverageOptions) -> None: + kompiled_dir: Path = options.definition_dir definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) pretty_printer = PrettyPrinter(definition) - for rid in args.coverage_file: + for rid in options.coverage_file: rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) - args.output.write('\n\n') - args.output.write('Rule: ' + rid.strip()) - args.output.write('\nUnparsed:\n') - args.output.write(pretty_printer.print(rule)) - _LOGGER.info(f'Wrote file: {args.output.name}') + options.output_file.write('\n\n') + options.output_file.write('Rule: ' + rid.strip()) + options.output_file.write('\nUnparsed:\n') + options.output_file.write(pretty_printer.print(rule)) + _LOGGER.info(f'Wrote file: {options.output_file.name}') -def exec_kore_to_json(args: Namespace) -> None: +def exec_kore_to_json(options: KoreToJsonOptions) -> None: text = sys.stdin.read() kore = KoreParser(text).pattern() print(kore.json) -def exec_json_to_kore(args: dict[str, Any]) -> None: +def exec_json_to_kore(options: JsonToKoreOptions) -> None: text = sys.stdin.read() kore = Pattern.from_json(text) kore.write(sys.stdout) From 809470b22224229209946193264fb80d4e09be69 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 27 Feb 2024 02:44:03 +0000 Subject: [PATCH 08/62] Set Version: 0.1.655 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 037f0f369..7beab509f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.654' -release = '0.1.654' +version = '0.1.655' +release = '0.1.655' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index bcd9581b0..c1fd23568 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.654 +0.1.655 diff --git a/pyproject.toml b/pyproject.toml index 48b12009c..b8b2797f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.654" +version = "0.1.655" description = "" authors = [ "Runtime Verification, Inc. ", From d528eaa976d1818d7f399ae5b307681833f1da63 Mon Sep 17 00:00:00 2001 From: Noah Watson <107630091+nwatson22@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:23:52 -0600 Subject: [PATCH 09/62] Update src/pyk/cli/args.py --- src/pyk/cli/args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 43bc46a4f..ad9cf8ebd 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -47,7 +47,7 @@ def generate_command_options(args: dict[str, Any]) -> LoggingOptions: class Options(object): def __init__(self, args: dict[str, Any]) -> None: - # Get defaults from all subclasses that define them, preferring the most specific class + # Get defaults from this and all superclasses that define them, preferring the most specific class defaults: dict[str, Any] = {} mro = type(self).mro() mro.reverse() From f2e5cc69b247edc1b2e7a0265a8987990081a606 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 27 Feb 2024 14:24:09 +0000 Subject: [PATCH 10/62] Set Version: 0.1.656 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 7beab509f..f5d8c9f10 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.655' -release = '0.1.655' +version = '0.1.656' +release = '0.1.656' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index c1fd23568..5b531828a 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.655 +0.1.656 diff --git a/pyproject.toml b/pyproject.toml index b8b2797f8..0f8664df1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.655" +version = "0.1.656" description = "" authors = [ "Runtime Verification, Inc. ", From 031e1413c114ccdb6a84de6adccae866a1a6d4c9 Mon Sep 17 00:00:00 2001 From: Noah Watson <107630091+nwatson22@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:24:14 -0600 Subject: [PATCH 11/62] Update src/pyk/cli/args.py --- src/pyk/cli/args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index ad9cf8ebd..73a4691d6 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -63,7 +63,7 @@ def __init__(self, args: dict[str, Any]) -> None: @classmethod def all_args(cls: Type[Options]) -> ArgumentParser: - # Collect args from all superclasses + # Collect args from this and all superclasses parser = ArgumentParser(add_help=False) mro = set(cls.mro()) for cl in mro: From 6e35eaaad399e627d726ece4126559b4aeb4006f Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 27 Feb 2024 08:41:19 -0600 Subject: [PATCH 12/62] Fix pyupgrade --- src/pyk/cli/args.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 43bc46a4f..860949d4e 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -4,13 +4,14 @@ from argparse import ArgumentParser, FileType from enum import Enum from functools import cached_property -from typing import IO, TYPE_CHECKING, Any, Iterable, Type +from typing import IO, TYPE_CHECKING, Any from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path if TYPE_CHECKING: from argparse import _SubParsersAction + from collections.abc import Iterable from pathlib import Path from typing import TypeVar @@ -45,7 +46,7 @@ def generate_command_options(args: dict[str, Any]) -> LoggingOptions: raise ValueError('Unrecognized command.') -class Options(object): +class Options: def __init__(self, args: dict[str, Any]) -> None: # Get defaults from all subclasses that define them, preferring the most specific class defaults: dict[str, Any] = {} @@ -62,7 +63,7 @@ def __init__(self, args: dict[str, Any]) -> None: self.__setattr__(attr, val) @classmethod - def all_args(cls: Type[Options]) -> ArgumentParser: + def all_args(cls: type[Options]) -> ArgumentParser: # Collect args from all superclasses parser = ArgumentParser(add_help=False) mro = set(cls.mro()) From 7bd95b16a8a99d651556a565dda5ce5095ae0778 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 27 Feb 2024 18:13:45 +0000 Subject: [PATCH 13/62] Set Version: 0.1.658 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 947f7ea84..ec84c841d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.657' -release = '0.1.657' +version = '0.1.658' +release = '0.1.658' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index e47818b0b..cc9feaadf 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.657 +0.1.658 diff --git a/pyproject.toml b/pyproject.toml index f1db3acff..6197822e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.657" +version = "0.1.658" description = "" authors = [ "Runtime Verification, Inc. ", From 2e01912bf2b3c5eb4a1fdc6b8389290af7fedb02 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 27 Feb 2024 14:59:43 -0600 Subject: [PATCH 14/62] Fix rpc-kast gettting definition options, fix changed options ordering --- src/pyk/cli/args.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index bd83ca1ac..cbe383df3 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -66,7 +66,8 @@ def __init__(self, args: dict[str, Any]) -> None: def all_args(cls: type[Options]) -> ArgumentParser: # Collect args from this and all superclasses parser = ArgumentParser(add_help=False) - mro = set(cls.mro()) + mro = cls.mro() + mro.reverse() for cl in mro: if hasattr(cl, 'args') and 'args' in cl.__dict__: parser = cl.args(parser) @@ -166,7 +167,7 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: return base -class RPCKastOptions(DefinitionOptions, OutputFileOptions): +class RPCKastOptions(LoggingOptions, OutputFileOptions): reference_request_file: IO[Any] response_file: IO[Any] From 18f580402224c26bb2c6d9890516eb00a80ad365 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 27 Feb 2024 21:00:55 +0000 Subject: [PATCH 15/62] Set Version: 0.1.660 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 79086c673..b5e8b03ab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.659' -release = '0.1.659' +version = '0.1.660' +release = '0.1.660' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index 794d0dded..37e73e00e 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.659 +0.1.660 diff --git a/pyproject.toml b/pyproject.toml index 289b1cc86..1d333b3dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.659" +version = "0.1.660" description = "" authors = [ "Runtime Verification, Inc. ", From b31ac24013e5855ce48a4424a70945faa341dd60 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 27 Feb 2024 15:30:30 -0600 Subject: [PATCH 16/62] Extend timout for pyk integration tests --- .github/workflows/test-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index 704522d5e..1c657558e 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -146,7 +146,7 @@ jobs: - name: 'Set Python version' run: docker exec --user user pyk-ci poetry env use ${{ matrix.python-version }} - name: 'Build and run integration tests' - run: docker exec --user user pyk-ci make cov-integration COV_ARGS='-n8 --timeout 300' + run: docker exec --user user pyk-ci make cov-integration COV_ARGS='-n8 --timeout 400' - name: 'Tear down Docker container' if: always() run: | From dc906e56cea38238848684cfed69646a622720e8 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 13:32:47 -0600 Subject: [PATCH 17/62] Move definition_args to KDefinitionOptions --- src/pyk/cli/args.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index cbe383df3..616b7fd46 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -287,6 +287,24 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: return base +class KDefinitionOptions: + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( + '-I', type=str, dest='includes', default=[], action='append', help='Directories to lookup K definitions in.' + ) + parser.add_argument('--main-module', default=None, type=str, help='Name of the main module.') + parser.add_argument('--syntax-module', default=None, type=str, help='Name of the syntax module.') + parser.add_argument('--spec-module', default=None, type=str, help='Name of the spec module.') + parser.add_argument('--definition', type=dir_path, dest='definition_dir', help='Path to definition to use.') + parser.add_argument( + '--md-selector', + type=str, + help='Code selector expression to use when reading markdown.', + ) + return parser + + class KCLIArgs: @cached_property def logging_args(self) -> ArgumentParser: @@ -383,23 +401,6 @@ def smt_args(self) -> ArgumentParser: ) return args - @cached_property - def definition_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument( - '-I', type=str, dest='includes', default=[], action='append', help='Directories to lookup K definitions in.' - ) - args.add_argument('--main-module', default=None, type=str, help='Name of the main module.') - args.add_argument('--syntax-module', default=None, type=str, help='Name of the syntax module.') - args.add_argument('--spec-module', default=None, type=str, help='Name of the spec module.') - args.add_argument('--definition', type=dir_path, dest='definition_dir', help='Path to definition to use.') - args.add_argument( - '--md-selector', - type=str, - help='Code selector expression to use when reading markdown.', - ) - return args - @cached_property def spec_args(self) -> ArgumentParser: args = ArgumentParser(add_help=False) From be1754e3e52b117f3232e6a6d350c44f6c744e5c Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 13:40:55 -0600 Subject: [PATCH 18/62] Mmove spec_args to SpecOptions --- src/pyk/cli/args.py | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 616b7fd46..c0e2e28f1 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -305,6 +305,28 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser +class SpecOptions: + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('spec_file', type=file_path, help='Path to spec file.') + parser.add_argument('--save-directory', type=ensure_dir_path, help='Path to where CFGs are stored.') + parser.add_argument( + '--claim', + type=str, + dest='claim_labels', + action='append', + help='Only prove listed claims, MODULE_NAME.claim-id', + ) + parser.add_argument( + '--exclude-claim', + type=str, + dest='exclude_claim_labels', + action='append', + help='Skip listed claims, MODULE_NAME.claim-id', + ) + return parser + + class KCLIArgs: @cached_property def logging_args(self) -> ArgumentParser: @@ -400,24 +422,3 @@ def smt_args(self) -> ArgumentParser: help='Z3 tactic to use when checking satisfiability. Example: (check-sat-using smt)', ) return args - - @cached_property - def spec_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('spec_file', type=file_path, help='Path to spec file.') - args.add_argument('--save-directory', type=ensure_dir_path, help='Path to where CFGs are stored.') - args.add_argument( - '--claim', - type=str, - dest='claim_labels', - action='append', - help='Only prove listed claims, MODULE_NAME.claim-id', - ) - args.add_argument( - '--exclude-claim', - type=str, - dest='exclude_claim_labels', - action='append', - help='Skip listed claims, MODULE_NAME.claim-id', - ) - return args From 3103879271aa70802f5688832014dd509fa6d372 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 13:50:53 -0600 Subject: [PATCH 19/62] Mmove kompile_args to KompileOptions --- src/pyk/cli/args.py | 81 +++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index c0e2e28f1..a043bb266 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -287,7 +287,7 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: return base -class KDefinitionOptions: +class KDefinitionOptions(Options): @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( @@ -305,7 +305,7 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class SpecOptions: +class SpecOptions(Options): @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('spec_file', type=file_path, help='Path to spec file.') @@ -327,82 +327,83 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class KCLIArgs: - @cached_property - def logging_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('--verbose', '-v', default=False, action='store_true', help='Verbose output.') - args.add_argument('--debug', default=False, action='store_true', help='Debug output.') - return args - - @cached_property - def parallel_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('--workers', '-j', default=1, type=int, help='Number of processes to run in parallel.') - return args - - @cached_property - def bug_report_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument( - '--bug-report', - type=bug_report_arg, - help='Generate bug report with given name', - ) - return args - - @cached_property - def kompile_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument( +class KompileOptions(Options): + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( '--emit-json', dest='emit_json', default=True, action='store_true', help='Emit JSON definition after compilation.', ) - args.add_argument( + parser.add_argument( '--no-emit-json', dest='emit_json', action='store_false', help='Do not JSON definition after compilation.' ) - args.add_argument( + parser.add_argument( '-ccopt', dest='ccopts', default=[], action='append', help='Additional arguments to pass to llvm-kompile.', ) - args.add_argument( + parser.add_argument( '--no-llvm-kompile', dest='llvm_kompile', default=True, action='store_false', help='Do not run llvm-kompile process.', ) - args.add_argument( + parser.add_argument( '--with-llvm-library', dest='llvm_library', default=False, action='store_true', help='Make kompile generate a dynamic llvm library.', ) - args.add_argument( + parser.add_argument( '--enable-llvm-debug', dest='enable_llvm_debug', default=False, action='store_true', help='Make kompile generate debug symbols for llvm.', ) - args.add_argument( + parser.add_argument( '--read-only-kompiled-directory', dest='read_only', default=False, action='store_true', help='Generated a kompiled directory that K will not attempt to write to afterwards.', ) - args.add_argument('-O0', dest='o0', default=False, action='store_true', help='Optimization level 0.') - args.add_argument('-O1', dest='o1', default=False, action='store_true', help='Optimization level 1.') - args.add_argument('-O2', dest='o2', default=False, action='store_true', help='Optimization level 2.') - args.add_argument('-O3', dest='o3', default=False, action='store_true', help='Optimization level 3.') + parser.add_argument('-O0', dest='o0', default=False, action='store_true', help='Optimization level 0.') + parser.add_argument('-O1', dest='o1', default=False, action='store_true', help='Optimization level 1.') + parser.add_argument('-O2', dest='o2', default=False, action='store_true', help='Optimization level 2.') + parser.add_argument('-O3', dest='o3', default=False, action='store_true', help='Optimization level 3.') + return parser + + +class KCLIArgs: + @cached_property + def logging_args(self) -> ArgumentParser: + args = ArgumentParser(add_help=False) + args.add_argument('--verbose', '-v', default=False, action='store_true', help='Verbose output.') + args.add_argument('--debug', default=False, action='store_true', help='Debug output.') + return args + + @cached_property + def parallel_args(self) -> ArgumentParser: + args = ArgumentParser(add_help=False) + args.add_argument('--workers', '-j', default=1, type=int, help='Number of processes to run in parallel.') + return args + + @cached_property + def bug_report_args(self) -> ArgumentParser: + args = ArgumentParser(add_help=False) + args.add_argument( + '--bug-report', + type=bug_report_arg, + help='Generate bug report with given name', + ) return args @cached_property From d2c0c8d1e137dd3d3b6ef5fc3d0b58b9580fda17 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 14:58:26 -0600 Subject: [PATCH 20/62] Construct kdist args with Options classes --- src/pyk/cli/args.py | 120 ++++++++++++++++++++++++----------- src/pyk/kdist/__main__.py | 130 ++++++++++++++++++++++++++++++-------- 2 files changed, 187 insertions(+), 63 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index a043bb266..93c4fac33 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -3,7 +3,6 @@ import sys from argparse import ArgumentParser, FileType from enum import Enum -from functools import cached_property from typing import IO, TYPE_CHECKING, Any from ..utils import ensure_dir_path @@ -15,6 +14,8 @@ from pathlib import Path from typing import TypeVar + from ..utils import BugReport + T = TypeVar('T') @@ -218,6 +219,8 @@ def args(parser: ArgumentParser) -> ArgumentParser: class DisplayOptions(Options): + minimize: bool + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('--minimize', dest='minimize', default=None, action='store_true', help='Minimize output.') @@ -288,6 +291,13 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: class KDefinitionOptions(Options): + includes: list[str] + main_module: str + syntax_module: str + spec_module: str + definition_dir: Path + md_selector: str + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( @@ -306,6 +316,11 @@ def args(parser: ArgumentParser) -> ArgumentParser: class SpecOptions(Options): + spec_file: Path + save_directory: Path + claim_labels: list[str] + exclude_claim_labels: list[str] + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('spec_file', type=file_path, help='Path to spec file.') @@ -328,12 +343,37 @@ def args(parser: ArgumentParser) -> ArgumentParser: class KompileOptions(Options): + emit_json: bool + ccopts: list[str] + llvm_kompile: bool + llvm_library: bool + enable_llvm_debug: bool + read_only: bool + o0: bool + o1: bool + o2: bool + o3: bool + + @staticmethod + def default() -> dict[str, Any]: + return { + 'emit_json': True, + 'llvm_kompile': False, + 'llvm_library': False, + 'enable_llvm_debug': False, + 'read_only': False, + 'o0': False, + 'o1': False, + 'o2': False, + 'o3': False, + } + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( '--emit-json', dest='emit_json', - default=True, + default=None, action='store_true', help='Emit JSON definition after compilation.', ) @@ -350,76 +390,84 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( '--no-llvm-kompile', dest='llvm_kompile', - default=True, + default=None, action='store_false', help='Do not run llvm-kompile process.', ) parser.add_argument( '--with-llvm-library', dest='llvm_library', - default=False, + default=None, action='store_true', help='Make kompile generate a dynamic llvm library.', ) parser.add_argument( '--enable-llvm-debug', dest='enable_llvm_debug', - default=False, + default=None, action='store_true', help='Make kompile generate debug symbols for llvm.', ) parser.add_argument( '--read-only-kompiled-directory', dest='read_only', - default=False, + default=None, action='store_true', help='Generated a kompiled directory that K will not attempt to write to afterwards.', ) - parser.add_argument('-O0', dest='o0', default=False, action='store_true', help='Optimization level 0.') - parser.add_argument('-O1', dest='o1', default=False, action='store_true', help='Optimization level 1.') - parser.add_argument('-O2', dest='o2', default=False, action='store_true', help='Optimization level 2.') - parser.add_argument('-O3', dest='o3', default=False, action='store_true', help='Optimization level 3.') + parser.add_argument('-O0', dest='o0', default=None, action='store_true', help='Optimization level 0.') + parser.add_argument('-O1', dest='o1', default=None, action='store_true', help='Optimization level 1.') + parser.add_argument('-O2', dest='o2', default=None, action='store_true', help='Optimization level 2.') + parser.add_argument('-O3', dest='o3', default=None, action='store_true', help='Optimization level 3.') return parser -class KCLIArgs: - @cached_property - def logging_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('--verbose', '-v', default=False, action='store_true', help='Verbose output.') - args.add_argument('--debug', default=False, action='store_true', help='Debug output.') - return args - - @cached_property - def parallel_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('--workers', '-j', default=1, type=int, help='Number of processes to run in parallel.') - return args - - @cached_property - def bug_report_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument( +class ParallelOptions(Options): + workers: int + + @staticmethod + def default() -> dict[str, Any]: + return { + 'workers': 1, + } + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('--workers', '-j', default=None, type=int, help='Number of processes to run in parallel.') + return parser + + +class BugReportOptions(Options): + bug_report: BugReport + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( '--bug-report', type=bug_report_arg, help='Generate bug report with given name', ) - return args + return parser + - @cached_property - def smt_args(self) -> ArgumentParser: - args = ArgumentParser(add_help=False) - args.add_argument('--smt-timeout', dest='smt_timeout', type=int, help='Timeout in ms to use for SMT queries.') - args.add_argument( +class SMTOptions(Options): + smt_timeout: int + smt_retry_limit: int + smt_tactic: str + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('--smt-timeout', dest='smt_timeout', type=int, help='Timeout in ms to use for SMT queries.') + parser.add_argument( '--smt-retry-limit', dest='smt_retry_limit', type=int, help='Number of times to retry SMT queries with scaling timeouts.', ) - args.add_argument( + parser.add_argument( '--smt-tactic', dest='smt_tactic', type=str, help='Z3 tactic to use when checking satisfiability. Example: (check-sat-using smt)', ) - return args + return parser diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index 1a0624310..d371660e9 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -3,15 +3,15 @@ import fnmatch import logging from argparse import ArgumentParser -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any -from pyk.cli.args import KCLIArgs +from pyk.cli.args import LoggingOptions from pyk.cli.utils import loglevel from ..kdist import kdist, target_ids if TYPE_CHECKING: - from argparse import Namespace + from argparse import Namespace, _SubParsersAction from typing import Final @@ -103,41 +103,117 @@ def _exec_list() -> None: print(f'* {target_name}') -def _parse_arguments() -> Namespace: - def add_target_arg(parser: ArgumentParser, help_text: str) -> None: +class KDistBuildOptions(LoggingOptions): + targets: list[str] + force: bool + jobs: int + + @staticmethod + def defaults() -> dict[str, Any]: + return { + 'force': False, + 'jobs': 1, + } + + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'build', + help='build targets', + parents=[KDistBuildOptions.all_args()], + ) + return base + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('targets', metavar='TARGET', nargs='*', default='*', help='target to build') + parser.add_argument( + '-a', + '--arg', + dest='args', + metavar='ARG', + action='append', + default=[], + help='build with argument', + ) + parser.add_argument('-f', '--force', action='store_true', default=None, help='force build') + parser.add_argument('-j', '--jobs', metavar='N', type=int, default=None, help='maximal number of build jobs') + return parser + + +class KDistCleanOptions(LoggingOptions): + target: str + + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'clean', + help='clean targets', + parents=[KDistCleanOptions.all_args()], + ) + return base + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( 'target', metavar='TARGET', nargs='?', - help=help_text, + help='target to clean', ) + return parser - k_cli_args = KCLIArgs() - parser = ArgumentParser(prog='kdist', parents=[k_cli_args.logging_args]) - command_parser = parser.add_subparsers(dest='command', required=True) +class KDistWhichOptions(LoggingOptions): + target: str - build_parser = command_parser.add_parser('build', help='build targets') - build_parser.add_argument('targets', metavar='TARGET', nargs='*', default='*', help='target to build') - build_parser.add_argument( - '-a', - '--arg', - dest='args', - metavar='ARG', - action='append', - default=[], - help='build with argument', - ) - build_parser.add_argument('-f', '--force', action='store_true', default=False, help='force build') - build_parser.add_argument('-j', '--jobs', metavar='N', type=int, default=1, help='maximal number of build jobs') + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'which', + help='print target location', + parents=[KDistCleanOptions.all_args()], + ) + return base + + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument( + 'target', + metavar='TARGET', + nargs='?', + help='target to print directory for', + ) + return parser - clean_parser = command_parser.add_parser('clean', help='clean targets') - add_target_arg(clean_parser, 'target to clean') - which_parser = command_parser.add_parser('which', help='print target location') - add_target_arg(which_parser, 'target to print directory for') +class KDistListOptions(LoggingOptions): + @staticmethod + def parser(base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + 'list', + help='print list of available targets', + parents=[KDistCleanOptions.all_args()], + ) + return base + + +def _parse_arguments() -> Namespace: + def add_target_arg(parser: ArgumentParser, help_text: str) -> None: + parser.add_argument( + 'target', + metavar='TARGET', + nargs='?', + help=help_text, + ) + + parser = ArgumentParser(prog='kdist', parents=[]) + command_parser = parser.add_subparsers(dest='command', required=True) - command_parser.add_parser('list', help='print list of available targets') + command_parser = KDistBuildOptions.parser(command_parser) + command_parser = KDistCleanOptions.parser(command_parser) + command_parser = KDistWhichOptions.parser(command_parser) + command_parser = KDistListOptions.parser(command_parser) return parser.parse_args() From 08b3648321bae37343cfa1afefe1b8273ea79991 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 18:13:50 -0600 Subject: [PATCH 21/62] Restore logging optinos to kdist --- src/pyk/kdist/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index d371660e9..4489d9f12 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -207,7 +207,7 @@ def add_target_arg(parser: ArgumentParser, help_text: str) -> None: help=help_text, ) - parser = ArgumentParser(prog='kdist', parents=[]) + parser = ArgumentParser(prog='kdist', parents=[LoggingOptions.all_args()]) command_parser = parser.add_subparsers(dest='command', required=True) command_parser = KDistBuildOptions.parser(command_parser) From f124b5aff9cd7b7fd9e40fd1cf3d462e89cc0288 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 18:52:22 -0600 Subject: [PATCH 22/62] Add default value --- src/pyk/cli/args.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 93c4fac33..5b51aa98a 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -5,6 +5,8 @@ from enum import Enum from typing import IO, TYPE_CHECKING, Any +from pyk.kdist import kdist + from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path @@ -298,6 +300,12 @@ class KDefinitionOptions(Options): definition_dir: Path md_selector: str + @staticmethod + def default() -> dict[str, Any]: + return { + 'definition_dir': kdist.get('evm-semantics.haskell'), + } + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( @@ -317,7 +325,7 @@ def args(parser: ArgumentParser) -> ArgumentParser: class SpecOptions(Options): spec_file: Path - save_directory: Path + save_directory: Path | None claim_labels: list[str] exclude_claim_labels: list[str] From 96a2b6a01a4a3c89e1d44b863332766f2ca07557 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 18:56:07 -0600 Subject: [PATCH 23/62] Remove default value for save_directory --- src/pyk/cli/args.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 5b51aa98a..0b4594916 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -5,8 +5,6 @@ from enum import Enum from typing import IO, TYPE_CHECKING, Any -from pyk.kdist import kdist - from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path @@ -297,15 +295,9 @@ class KDefinitionOptions(Options): main_module: str syntax_module: str spec_module: str - definition_dir: Path + definition_dir: Path | None md_selector: str - @staticmethod - def default() -> dict[str, Any]: - return { - 'definition_dir': kdist.get('evm-semantics.haskell'), - } - @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( From c8ab6df41613aa3988cccbdb66c15ada62c5b11b Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 18:59:25 -0600 Subject: [PATCH 24/62] Make default save_directory None --- src/pyk/cli/args.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 0b4594916..626d9bc32 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -321,6 +321,12 @@ class SpecOptions(Options): claim_labels: list[str] exclude_claim_labels: list[str] + @staticmethod + def default() -> dict[str, Any]: + return { + 'save_directory': None, + } + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('spec_file', type=file_path, help='Path to spec file.') From 8da0fdd00ca911f9d4cac4d4a4121364407b4d08 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 19:02:08 -0600 Subject: [PATCH 25/62] Make default spec_module None --- src/pyk/cli/args.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 626d9bc32..886befb39 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -269,9 +269,15 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: class ProveOptions(DefinitionOptions, OutputFileOptions): main_file: Path spec_file: Path - spec_module: str + spec_module: str | None k_args: Iterable[str] + @staticmethod + def default() -> dict[str, Any]: + return { + 'spec_module': None, + } + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('main_file', type=str, help='Main file used for kompilation.') From 750b59ffcac9491dfd56d53f20387925bf2f3e57 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 28 Feb 2024 19:03:26 -0600 Subject: [PATCH 26/62] Make default spec_module None --- src/pyk/cli/args.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 886befb39..e6ea42bad 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -269,15 +269,9 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: class ProveOptions(DefinitionOptions, OutputFileOptions): main_file: Path spec_file: Path - spec_module: str | None + spec_module: str k_args: Iterable[str] - @staticmethod - def default() -> dict[str, Any]: - return { - 'spec_module': None, - } - @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('main_file', type=str, help='Main file used for kompilation.') @@ -300,10 +294,16 @@ class KDefinitionOptions(Options): includes: list[str] main_module: str syntax_module: str - spec_module: str + spec_module: str | None definition_dir: Path | None md_selector: str + @staticmethod + def default() -> dict[str, Any]: + return { + 'spec_module': None, + } + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( From f587319f6514366333aeb87dd93cdfb802ac5eb2 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Thu, 29 Feb 2024 14:43:42 -0600 Subject: [PATCH 27/62] Add some missing default args --- src/pyk/cli/args.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index e6ea42bad..03a363d2a 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -221,6 +221,12 @@ def args(parser: ArgumentParser) -> ArgumentParser: class DisplayOptions(Options): minimize: bool + @staticmethod + def default() -> dict[str, Any]: + return { + 'minimize': True, + } + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('--minimize', dest='minimize', default=None, action='store_true', help='Minimize output.') @@ -239,7 +245,6 @@ class PrintOptions(DefinitionOptions, OutputFileOptions, DisplayOptions): def default() -> dict[str, Any]: return { 'input': PrintInput.KAST_JSON, - 'minimize': True, 'omit_labels': None, 'keep_cells': None, } @@ -292,8 +297,8 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: class KDefinitionOptions(Options): includes: list[str] - main_module: str - syntax_module: str + main_module: str | None + syntax_module: str | None spec_module: str | None definition_dir: Path | None md_selector: str @@ -302,6 +307,10 @@ class KDefinitionOptions(Options): def default() -> dict[str, Any]: return { 'spec_module': None, + 'main_module': None, + 'syntax_module': None, + 'definition_dir': None, + 'md_selector': 'k', } @staticmethod @@ -450,7 +459,11 @@ def args(parser: ArgumentParser) -> ArgumentParser: class BugReportOptions(Options): - bug_report: BugReport + bug_report: BugReport | None + + @staticmethod + def default() -> dict[str, Any]: + return {'bug_report': None} @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: @@ -465,7 +478,15 @@ def args(parser: ArgumentParser) -> ArgumentParser: class SMTOptions(Options): smt_timeout: int smt_retry_limit: int - smt_tactic: str + smt_tactic: str | None + + @staticmethod + def default() -> dict[str, Any]: + return { + 'smt_timeout': 300, + 'smt_retry_limit': 10, + 'smt_tactic': None, + } @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: From 778bb1410102ebf7db483ce00027e0966c8de08d Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Thu, 29 Feb 2024 17:10:33 -0600 Subject: [PATCH 28/62] Break off SaveDirOptions --- src/pyk/cli/args.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 03a363d2a..944281115 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -329,23 +329,35 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) return parser +class SaveDirOptions(Options): + save_directory: Path | None + + @staticmethod + def default() -> dict[str, Any]: + return { + 'save_directory': None, + } -class SpecOptions(Options): + @staticmethod + def args(parser: ArgumentParser) -> ArgumentParser: + parser.add_argument('--save-directory', type=ensure_dir_path, help='Path to where CFGs are stored.') + return parser + +class SpecOptions(SaveDirOptions): spec_file: Path - save_directory: Path | None - claim_labels: list[str] + claim_labels: list[str] | None exclude_claim_labels: list[str] @staticmethod def default() -> dict[str, Any]: return { - 'save_directory': None, + 'claim_labels': None, + 'exclude_claim_labels': [], } @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('spec_file', type=file_path, help='Path to spec file.') - parser.add_argument('--save-directory', type=ensure_dir_path, help='Path to where CFGs are stored.') parser.add_argument( '--claim', type=str, From 91469d980302b5a795f31ab2ed35289e5c21ecfd Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Thu, 29 Feb 2024 17:11:01 -0600 Subject: [PATCH 29/62] Fix formatting --- src/pyk/cli/args.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 944281115..9ce61232e 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -329,6 +329,7 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) return parser + class SaveDirOptions(Options): save_directory: Path | None @@ -343,6 +344,7 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('--save-directory', type=ensure_dir_path, help='Path to where CFGs are stored.') return parser + class SpecOptions(SaveDirOptions): spec_file: Path claim_labels: list[str] | None From 085b11936e99024ba3173d4f2f4f822d3eff2685 Mon Sep 17 00:00:00 2001 From: devops Date: Fri, 1 Mar 2024 22:55:20 +0000 Subject: [PATCH 30/62] Set Version: 0.1.676 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 009aef2b8..7cdd1c300 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.675' -release = '0.1.675' +version = '0.1.676' +release = '0.1.676' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index 9ef797d95..f82cf7df8 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.675 +0.1.676 diff --git a/pyproject.toml b/pyproject.toml index 12127092d..247ddc032 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.675" +version = "0.1.676" description = "" authors = [ "Runtime Verification, Inc. ", From 9f6574681d58d787c63ee484cbf02b26410096ad Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Fri, 1 Mar 2024 17:38:58 -0600 Subject: [PATCH 31/62] Add Command and CommandHandler classes so commands only have to be listed once. parser() made generic to all Command subclasses. --- src/pyk/__main__.py | 30 ++++--- src/pyk/cli/args.py | 188 ++++++++++++++++++++++++-------------------- 2 files changed, 119 insertions(+), 99 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 3a1261a5a..c7326ee09 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -13,6 +13,7 @@ from pyk.kore.rpc import ExecuteResult from .cli.args import ( + CommandHandler, CoverageOptions, GraphImportsOptions, JsonToKoreOptions, @@ -22,7 +23,6 @@ ProveOptions, RPCKastOptions, RPCPrintOptions, - generate_command_options, ) from .cli.utils import LOG_FORMAT, dir_path, loglevel from .coverage import get_rule_by_id, strip_coverage_logger @@ -58,10 +58,23 @@ def main() -> None: # This change makes it so that in most cases, by default, pyk doesn't run out of stack space. sys.setrecursionlimit(10**7) - cli_parser = create_argument_parser() + cmd_handler = CommandHandler( + [ + CoverageOptions, + GraphImportsOptions, + JsonToKoreOptions, + KoreToJsonOptions, + PrintOptions, + ProveOptions, + RPCKastOptions, + RPCPrintOptions, + ] + ) + + cli_parser = create_argument_parser(cmd_handler) args = cli_parser.parse_args() - options = generate_command_options({key: val for (key, val) in vars(args).items() if val is not None}) + options = cmd_handler.generate_options({key: val for (key, val) in vars(args).items() if val is not None}) logging.basicConfig(level=loglevel(options), format=LOG_FORMAT) @@ -265,21 +278,14 @@ def exec_json_to_kore(options: JsonToKoreOptions) -> None: sys.stdout.write('\n') -def create_argument_parser() -> ArgumentParser: +def create_argument_parser(cmd_handler: CommandHandler) -> ArgumentParser: definition_args = ArgumentParser(add_help=False) definition_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.') pyk_args = ArgumentParser() pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) - pyk_args_command = PrintOptions.parser(pyk_args_command) - pyk_args_command = RPCPrintOptions.parser(pyk_args_command) - pyk_args_command = RPCKastOptions.parser(pyk_args_command) - pyk_args_command = ProveOptions.parser(pyk_args_command) - pyk_args_command = GraphImportsOptions.parser(pyk_args_command) - pyk_args_command = CoverageOptions.parser(pyk_args_command) - pyk_args_command = KoreToJsonOptions.parser(pyk_args_command) - pyk_args_command = JsonToKoreOptions.parser(pyk_args_command) + pyk_args_command = cmd_handler.add_parsers(pyk_args_command) return pyk_args diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 9ce61232e..3e2b055a7 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -1,9 +1,10 @@ from __future__ import annotations import sys +from abc import abstractmethod from argparse import ArgumentParser, FileType from enum import Enum -from typing import IO, TYPE_CHECKING, Any +from typing import IO, TYPE_CHECKING, Any, Type from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path @@ -24,27 +25,26 @@ class PrintInput(Enum): KAST_JSON = 'kast-json' -def generate_command_options(args: dict[str, Any]) -> LoggingOptions: - command = args['command'].lower() - match command: - case 'print': - return PrintOptions(args) - case 'rpc-print': - return RPCPrintOptions(args) - case 'rpc-kast': - return RPCKastOptions(args) - case 'prove': - return ProveOptions(args) - case 'graph-imports': - return GraphImportsOptions(args) - case 'coverage': - return CoverageOptions(args) - case 'kore-to-json': - return KoreToJsonOptions(args) - case 'json-to-kore': - return JsonToKoreOptions(args) - case _: - raise ValueError('Unrecognized command.') +class CommandHandler: + commands: list[Type[Command]] + + # Input a list of all Command types to be used + def __init__(self, commands: Iterable[Type[Command]]): + self.commands = list(commands) + + # Return an instance of the correct Options subclass by matching its name with the requested command + def generate_options(self, args: dict[str, Any]) -> LoggingOptions: + command = args['command'].lower() + for cmd_type in self.commands: + if cmd_type.name() == command: + return cmd_type(args) + raise ValueError(f'Unrecognized command: {command}') + + # Generate the parsers for all commands + def add_parsers(self, base: _SubParsersAction) -> _SubParsersAction: + for cmd_type in self.commands: + base = cmd_type.parser(base) + return base class Options: @@ -93,26 +93,46 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class JsonToKoreOptions(LoggingOptions): +class Command(LoggingOptions): @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: + @abstractmethod + def name() -> str: + ... + + @staticmethod + @staticmethod + @abstractmethod + def help_str() -> str: + ... + + @classmethod + def parser(cls, base: _SubParsersAction) -> _SubParsersAction: base.add_parser( - 'json-to-kore', - help='Convert JSON to textual KORE', - parents=[JsonToKoreOptions.all_args()], + name=cls.name(), + help=cls.help_str(), + parents=[cls.all_args()], ) return base -class KoreToJsonOptions(LoggingOptions): +class JsonToKoreOptions(Command): @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'kore-to-json', - help='Convert textual KORE to JSON', - parents=[KoreToJsonOptions.all_args()], - ) - return base + def name() -> str: + return 'json-to-kore' + + @staticmethod + def help_str() -> str: + return 'Convert JSON to textual KORE' + + +class KoreToJsonOptions(Command): + @staticmethod + def name() -> str: + return 'kore-to-json' + + @staticmethod + def help_str() -> str: + return 'Convert textual KORE to JSON' class OutputFileOptions(Options): @@ -139,17 +159,16 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class CoverageOptions(DefinitionOptions, OutputFileOptions): +class CoverageOptions(Command, DefinitionOptions, OutputFileOptions): coverage_file: IO[Any] @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'coverage', - help='Convert coverage file to human readable log.', - parents=[CoverageOptions.all_args()], - ) - return base + def name() -> str: + return 'coverage' + + @staticmethod + def help_str() -> str: + return 'Convert coverage file to human readable log.' @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: @@ -157,29 +176,27 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class GraphImportsOptions(DefinitionOptions): +class GraphImportsOptions(Command, DefinitionOptions): @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'graph-imports', - help='Graph the imports of a given definition.', - parents=[GraphImportsOptions.all_args()], - ) - return base + def name() -> str: + return 'graph-imports' + + @staticmethod + def help_str() -> str: + return 'Graph the imports of a given definition.' -class RPCKastOptions(LoggingOptions, OutputFileOptions): +class RPCKastOptions(Command, OutputFileOptions): reference_request_file: IO[Any] response_file: IO[Any] @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'rpc-kast', - help='Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.', - parents=[RPCKastOptions.all_args()], - ) - return base + def name() -> str: + return 'rpc-kast' + + @staticmethod + def help_str() -> str: + return 'Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.' @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: @@ -196,17 +213,16 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class RPCPrintOptions(DefinitionOptions, OutputFileOptions): +class RPCPrintOptions(Command, DefinitionOptions, OutputFileOptions): input_file: IO[Any] @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'rpc-print', - help='Pretty-print an RPC request/response', - parents=[RPCPrintOptions.all_args()], - ) - return base + def name() -> str: + return 'rpc-print' + + @staticmethod + def help_str() -> str: + return 'Pretty-print an RPC request/response' @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: @@ -234,13 +250,21 @@ def args(parser: ArgumentParser) -> ArgumentParser: return parser -class PrintOptions(DefinitionOptions, OutputFileOptions, DisplayOptions): +class PrintOptions(Command, DefinitionOptions, OutputFileOptions, DisplayOptions): term: IO[Any] input: PrintInput minimize: bool omit_labels: str | None keep_cells: str | None + @staticmethod + def name() -> str: + return 'print' + + @staticmethod + def help_str() -> str: + return 'Pretty print a term.' + @staticmethod def default() -> dict[str, Any]: return { @@ -261,22 +285,21 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) return parser - @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'print', - help='Pretty print a term.', - parents=[PrintOptions.all_args()], - ) - return base - -class ProveOptions(DefinitionOptions, OutputFileOptions): +class ProveOptions(Command, DefinitionOptions, OutputFileOptions): main_file: Path spec_file: Path spec_module: str k_args: Iterable[str] + @staticmethod + def name() -> str: + return 'prove' + + @staticmethod + def help_str() -> str: + return 'Prove an input specification (using kprovex).' + @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('main_file', type=str, help='Main file used for kompilation.') @@ -285,15 +308,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') return parser - @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'prove', - help='Prove an input specification (using kprovex).', - parents=[ProveOptions.all_args()], - ) - return base - class KDefinitionOptions(Options): includes: list[str] From cc8545668229137a9711e9957754532dd0159968 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 12:32:22 -0600 Subject: [PATCH 32/62] Fix syntax --- src/pyk/cli/args.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 3e2b055a7..17488501f 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -26,10 +26,10 @@ class PrintInput(Enum): class CommandHandler: - commands: list[Type[Command]] + commands: list[type[Command]] # Input a list of all Command types to be used - def __init__(self, commands: Iterable[Type[Command]]): + def __init__(self, commands: Iterable[type[Command]]): self.commands = list(commands) # Return an instance of the correct Options subclass by matching its name with the requested command From a03d77f6d93ce0b55f43e859879cca75731757ab Mon Sep 17 00:00:00 2001 From: devops Date: Mon, 4 Mar 2024 18:32:40 +0000 Subject: [PATCH 33/62] Set Version: 0.1.677 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 7cdd1c300..e0dcb7e90 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.676' -release = '0.1.676' +version = '0.1.677' +release = '0.1.677' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index f82cf7df8..ca1ea1c1b 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.676 +0.1.677 diff --git a/pyproject.toml b/pyproject.toml index 247ddc032..b40c625e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.676" +version = "0.1.677" description = "" authors = [ "Runtime Verification, Inc. ", From 2adbf2d1b162dddfb4c5298609cab06f8a0131c8 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 13:47:35 -0600 Subject: [PATCH 34/62] Move command exec logic into their own classes --- src/pyk/__main__.py | 254 ++------------------------------------------ src/pyk/cli/args.py | 230 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 233 insertions(+), 251 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index c7326ee09..d17a70753 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -1,52 +1,24 @@ from __future__ import annotations -import json import logging import sys -from argparse import ArgumentParser -from pathlib import Path from typing import TYPE_CHECKING -from graphviz import Digraph - -from pyk.kast.inner import KInner -from pyk.kore.rpc import ExecuteResult - from .cli.args import ( - CommandHandler, + KEVMCLI, CoverageOptions, GraphImportsOptions, JsonToKoreOptions, KoreToJsonOptions, - PrintInput, PrintOptions, ProveOptions, RPCKastOptions, RPCPrintOptions, ) -from .cli.utils import LOG_FORMAT, dir_path, loglevel -from .coverage import get_rule_by_id, strip_coverage_logger -from .cterm import CTerm -from .kast.manip import ( - flatten_label, - minimize_rule, - minimize_term, - propagate_up_constraints, - remove_source_map, - split_config_and_constraints, -) -from .kast.outer import read_kast_definition -from .kast.pretty import PrettyPrinter -from .kore.parser import KoreParser -from .kore.rpc import StopReason -from .kore.syntax import Pattern, kore_term -from .ktool.kprint import KPrint -from .ktool.kprove import KProve -from .prelude.k import GENERATED_TOP_CELL -from .prelude.ml import is_top, mlAnd, mlOr +from .cli.utils import LOG_FORMAT, loglevel if TYPE_CHECKING: - from typing import Any, Final + from typing import Final _LOGGER: Final = logging.getLogger(__name__) @@ -58,7 +30,7 @@ def main() -> None: # This change makes it so that in most cases, by default, pyk doesn't run out of stack space. sys.setrecursionlimit(10**7) - cmd_handler = CommandHandler( + cli = KEVMCLI( [ CoverageOptions, GraphImportsOptions, @@ -71,223 +43,13 @@ def main() -> None: ] ) - cli_parser = create_argument_parser(cmd_handler) + cli_parser = cli.create_argument_parser() args = cli_parser.parse_args() - options = cmd_handler.generate_options({key: val for (key, val) in vars(args).items() if val is not None}) - - logging.basicConfig(level=loglevel(options), format=LOG_FORMAT) - - executor_name = 'exec_' + args.command.lower().replace('-', '_') - if executor_name not in globals(): - raise AssertionError(f'Unimplemented command: {args.command}') - - execute = globals()[executor_name] - execute(options) - - -def exec_print(options: PrintOptions) -> None: - kompiled_dir: Path = options.definition_dir - printer = KPrint(kompiled_dir) - if options.input == PrintInput.KORE_JSON: - _LOGGER.info(f'Reading Kore JSON from file: {options.term.name}') - kore = Pattern.from_json(options.term.read()) - term = printer.kore_to_kast(kore) - else: - _LOGGER.info(f'Reading Kast JSON from file: {options.term.name}') - term = KInner.from_json(options.term.read()) - if is_top(term): - options.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {options.output_file.name}') - else: - if options.minimize: - if options.omit_labels != None and options.keep_cells != None: - raise ValueError('You cannot use both --omit-labels and --keep-cells.') - - abstract_labels = options.omit_labels.split(',') if options.omit_labels is not None else [] - keep_cells = options.keep_cells.split(',') if options.keep_cells is not None else [] - minimized_disjuncts = [] - - for disjunct in flatten_label('#Or', term): - try: - minimized = minimize_term(disjunct, abstract_labels=abstract_labels, keep_cells=keep_cells) - config, constraint = split_config_and_constraints(minimized) - except ValueError as err: - raise ValueError('The minimized term does not contain a config cell.') from err - - if not is_top(constraint): - minimized_disjuncts.append(mlAnd([config, constraint], sort=GENERATED_TOP_CELL)) - else: - minimized_disjuncts.append(config) - term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) - - options.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {options.output_file.name}') - - -def exec_rpc_print(options: RPCPrintOptions) -> None: - kompiled_dir: Path = options.definition_dir - printer = KPrint(kompiled_dir) - input_dict = json.loads(options.input_file.read()) - output_buffer = [] - - def pretty_print_request(request_params: dict[str, Any]) -> list[str]: - output_buffer = [] - non_state_keys = set(request_params.keys()).difference(['state']) - for key in non_state_keys: - output_buffer.append(f'{key}: {request_params[key]}') - state = CTerm.from_kast(printer.kore_to_kast(kore_term(request_params['state']))) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - return output_buffer - - def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: - output_buffer = [] - output_buffer.append(f'Depth: {execute_result.depth}') - output_buffer.append(f'Stop reason: {execute_result.reason.value}') - if execute_result.reason == StopReason.TERMINAL_RULE or execute_result.reason == StopReason.CUT_POINT_RULE: - output_buffer.append(f'Stop rule: {execute_result.rule}') - output_buffer.append( - f'Number of next states: {len(execute_result.next_states) if execute_result.next_states is not None else 0}' - ) - state = CTerm.from_kast(printer.kore_to_kast(execute_result.state.kore)) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - if execute_result.next_states is not None: - next_states = [CTerm.from_kast(printer.kore_to_kast(s.kore)) for s in execute_result.next_states] - for i, s in enumerate(next_states): - output_buffer.append(f'Next state #{i}:') - output_buffer.append(printer.pretty_print(s.kast, sort_collections=True)) - return output_buffer - - try: - if 'method' in input_dict: - output_buffer.append('JSON RPC request') - output_buffer.append(f'id: {input_dict["id"]}') - output_buffer.append(f'Method: {input_dict["method"]}') - try: - if 'state' in input_dict['params']: - output_buffer += pretty_print_request(input_dict['params']) - else: # this is an "add-module" request, skip trying to print state - for key in input_dict['params'].keys(): - output_buffer.append(f'{key}: {input_dict["params"][key]}') - except KeyError as e: - _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') - exit(1) - else: - if not 'result' in input_dict: - _LOGGER.critical('The input is neither a request not a resonse') - exit(1) - output_buffer.append('JSON RPC Response') - output_buffer.append(f'id: {input_dict["id"]}') - if list(input_dict['result'].keys()) == ['state']: # this is a "simplify" response - output_buffer.append('Method: simplify') - state = CTerm.from_kast(printer.kore_to_kast(kore_term(input_dict['result']['state']))) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - elif list(input_dict['result'].keys()) == ['module']: # this is an "add-module" response - output_buffer.append('Method: add-module') - output_buffer.append('Module:') - output_buffer.append(input_dict['result']['module']) - else: - try: # assume it is an "execute" response - output_buffer.append('Method: execute') - execute_result = ExecuteResult.from_dict(input_dict['result']) - output_buffer += pretty_print_execute_response(execute_result) - except KeyError as e: - _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') - exit(1) - if options.output_file is not None: - options.output_file.write('\n'.join(output_buffer)) - else: - print('\n'.join(output_buffer)) - except ValueError as e: - # shorten and print the error message in case kore_to_kast throws ValueError - _LOGGER.critical(str(e)[:200]) - exit(1) - - -def exec_rpc_kast(options: RPCKastOptions) -> None: - """ - Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, - copying parameters from a reference request. - """ - reference_request = json.loads(options.reference_request_file.read()) - input_dict = json.loads(options.response_file.read()) - execute_result = ExecuteResult.from_dict(input_dict['result']) - non_state_keys = set(reference_request['params'].keys()).difference(['state']) - request_params = {} - for key in non_state_keys: - request_params[key] = reference_request['params'][key] - request_params['state'] = {'format': 'KORE', 'version': 1, 'term': execute_result.state.kore.dict} - request = { - 'jsonrpc': reference_request['jsonrpc'], - 'id': reference_request['id'], - 'method': reference_request['method'], - 'params': request_params, - } - options.output_file.write(json.dumps(request)) - - -def exec_prove(options: ProveOptions) -> None: - kompiled_dir: Path = options.definition_dir - kprover = KProve(kompiled_dir, options.main_file) - final_state = kprover.prove(Path(options.spec_file), spec_module_name=options.spec_module, args=options.k_args) - options.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) - _LOGGER.info(f'Wrote file: {options.output_file.name}') - - -def exec_graph_imports(options: GraphImportsOptions) -> None: - kompiled_dir: Path = options.definition_dir - kprinter = KPrint(kompiled_dir) - definition = kprinter.definition - import_graph = Digraph() - graph_file = kompiled_dir / 'import-graph' - for module in definition.modules: - module_name = module.name - import_graph.node(module_name) - for module_import in module.imports: - import_graph.edge(module_name, module_import.name) - import_graph.render(graph_file) - _LOGGER.info(f'Wrote file: {graph_file}') - - -def exec_coverage(options: CoverageOptions) -> None: - kompiled_dir: Path = options.definition_dir - definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) - pretty_printer = PrettyPrinter(definition) - for rid in options.coverage_file: - rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) - options.output_file.write('\n\n') - options.output_file.write('Rule: ' + rid.strip()) - options.output_file.write('\nUnparsed:\n') - options.output_file.write(pretty_printer.print(rule)) - _LOGGER.info(f'Wrote file: {options.output_file.name}') - - -def exec_kore_to_json(options: KoreToJsonOptions) -> None: - text = sys.stdin.read() - kore = KoreParser(text).pattern() - print(kore.json) - - -def exec_json_to_kore(options: JsonToKoreOptions) -> None: - text = sys.stdin.read() - kore = Pattern.from_json(text) - kore.write(sys.stdout) - sys.stdout.write('\n') - - -def create_argument_parser(cmd_handler: CommandHandler) -> ArgumentParser: - definition_args = ArgumentParser(add_help=False) - definition_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.') - - pyk_args = ArgumentParser() - pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) - - pyk_args_command = cmd_handler.add_parsers(pyk_args_command) + command = cli.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) + command.exec() - return pyk_args + logging.basicConfig(level=loglevel(command), format=LOG_FORMAT) if __name__ == '__main__': diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 17488501f..262d5371a 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -1,18 +1,42 @@ from __future__ import annotations +import json import sys from abc import abstractmethod from argparse import ArgumentParser, FileType from enum import Enum -from typing import IO, TYPE_CHECKING, Any, Type +from pathlib import Path +from typing import IO, TYPE_CHECKING, Any + +from graphviz import Digraph + +from pyk.coverage import get_rule_by_id, strip_coverage_logger +from pyk.cterm import CTerm +from pyk.kast.inner import KInner +from pyk.kast.manip import ( + flatten_label, + minimize_rule, + minimize_term, + propagate_up_constraints, + remove_source_map, + split_config_and_constraints, +) +from pyk.kast.outer import read_kast_definition +from pyk.kast.pretty import PrettyPrinter +from pyk.kore.parser import KoreParser +from pyk.kore.rpc import ExecuteResult, StopReason +from pyk.kore.syntax import Pattern, kore_term +from pyk.ktool.kprint import KPrint +from pyk.ktool.kprove import KProve +from pyk.prelude.k import GENERATED_TOP_CELL +from pyk.prelude.ml import is_top, mlAnd, mlOr +from pyk.utils import _LOGGER, ensure_dir_path -from ..utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path if TYPE_CHECKING: from argparse import _SubParsersAction from collections.abc import Iterable - from pathlib import Path from typing import TypeVar from ..utils import BugReport @@ -25,7 +49,7 @@ class PrintInput(Enum): KAST_JSON = 'kast-json' -class CommandHandler: +class KEVMCLI: commands: list[type[Command]] # Input a list of all Command types to be used @@ -33,7 +57,7 @@ def __init__(self, commands: Iterable[type[Command]]): self.commands = list(commands) # Return an instance of the correct Options subclass by matching its name with the requested command - def generate_options(self, args: dict[str, Any]) -> LoggingOptions: + def generate_command(self, args: dict[str, Any]) -> Command: command = args['command'].lower() for cmd_type in self.commands: if cmd_type.name() == command: @@ -46,6 +70,14 @@ def add_parsers(self, base: _SubParsersAction) -> _SubParsersAction: base = cmd_type.parser(base) return base + def create_argument_parser(self) -> ArgumentParser: + pyk_args = ArgumentParser() + pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) + + pyk_args_command = self.add_parsers(pyk_args_command) + + return pyk_args + class Options: def __init__(self, args: dict[str, Any]) -> None: @@ -105,6 +137,10 @@ def name() -> str: def help_str() -> str: ... + @abstractmethod + def exec(self) -> None: + ... + @classmethod def parser(cls, base: _SubParsersAction) -> _SubParsersAction: base.add_parser( @@ -124,6 +160,12 @@ def name() -> str: def help_str() -> str: return 'Convert JSON to textual KORE' + def exec(self) -> None: + text = sys.stdin.read() + kore = Pattern.from_json(text) + kore.write(sys.stdout) + sys.stdout.write('\n') + class KoreToJsonOptions(Command): @staticmethod @@ -134,6 +176,11 @@ def name() -> str: def help_str() -> str: return 'Convert textual KORE to JSON' + def exec(self) -> None: + text = sys.stdin.read() + kore = KoreParser(text).pattern() + print(kore.json) + class OutputFileOptions(Options): output_file: IO[Any] @@ -175,6 +222,18 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') return parser + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) + pretty_printer = PrettyPrinter(definition) + for rid in self.coverage_file: + rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) + self.output_file.write('\n\n') + self.output_file.write('Rule: ' + rid.strip()) + self.output_file.write('\nUnparsed:\n') + self.output_file.write(pretty_printer.print(rule)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + class GraphImportsOptions(Command, DefinitionOptions): @staticmethod @@ -185,6 +244,20 @@ def name() -> str: def help_str() -> str: return 'Graph the imports of a given definition.' + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + kprinter = KPrint(kompiled_dir) + definition = kprinter.definition + import_graph = Digraph() + graph_file = kompiled_dir / 'import-graph' + for module in definition.modules: + module_name = module.name + import_graph.node(module_name) + for module_import in module.imports: + import_graph.edge(module_name, module_import.name) + import_graph.render(graph_file) + _LOGGER.info(f'Wrote file: {graph_file}') + class RPCKastOptions(Command, OutputFileOptions): reference_request_file: IO[Any] @@ -212,6 +285,27 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) return parser + def exec(self) -> None: + """ + Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, + copying parameters from a reference request. + """ + reference_request = json.loads(self.reference_request_file.read()) + input_dict = json.loads(self.response_file.read()) + execute_result = ExecuteResult.from_dict(input_dict['result']) + non_state_keys = set(reference_request['params'].keys()).difference(['state']) + request_params = {} + for key in non_state_keys: + request_params[key] = reference_request['params'][key] + request_params['state'] = {'format': 'KORE', 'version': 1, 'term': execute_result.state.kore.dict} + request = { + 'jsonrpc': reference_request['jsonrpc'], + 'id': reference_request['id'], + 'method': reference_request['method'], + 'params': request_params, + } + self.output_file.write(json.dumps(request)) + class RPCPrintOptions(Command, DefinitionOptions, OutputFileOptions): input_file: IO[Any] @@ -233,6 +327,87 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) return parser + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + printer = KPrint(kompiled_dir) + input_dict = json.loads(self.input_file.read()) + output_buffer = [] + + def pretty_print_request(request_params: dict[str, Any]) -> list[str]: + output_buffer = [] + non_state_keys = set(request_params.keys()).difference(['state']) + for key in non_state_keys: + output_buffer.append(f'{key}: {request_params[key]}') + state = CTerm.from_kast(printer.kore_to_kast(kore_term(request_params['state']))) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + return output_buffer + + def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: + output_buffer = [] + output_buffer.append(f'Depth: {execute_result.depth}') + output_buffer.append(f'Stop reason: {execute_result.reason.value}') + if execute_result.reason == StopReason.TERMINAL_RULE or execute_result.reason == StopReason.CUT_POINT_RULE: + output_buffer.append(f'Stop rule: {execute_result.rule}') + output_buffer.append( + f'Number of next states: {len(execute_result.next_states) if execute_result.next_states is not None else 0}' + ) + state = CTerm.from_kast(printer.kore_to_kast(execute_result.state.kore)) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + if execute_result.next_states is not None: + next_states = [CTerm.from_kast(printer.kore_to_kast(s.kore)) for s in execute_result.next_states] + for i, s in enumerate(next_states): + output_buffer.append(f'Next state #{i}:') + output_buffer.append(printer.pretty_print(s.kast, sort_collections=True)) + return output_buffer + + try: + if 'method' in input_dict: + output_buffer.append('JSON RPC request') + output_buffer.append(f'id: {input_dict["id"]}') + output_buffer.append(f'Method: {input_dict["method"]}') + try: + if 'state' in input_dict['params']: + output_buffer += pretty_print_request(input_dict['params']) + else: # this is an "add-module" request, skip trying to print state + for key in input_dict['params'].keys(): + output_buffer.append(f'{key}: {input_dict["params"][key]}') + except KeyError as e: + _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') + exit(1) + else: + if not 'result' in input_dict: + _LOGGER.critical('The input is neither a request not a resonse') + exit(1) + output_buffer.append('JSON RPC Response') + output_buffer.append(f'id: {input_dict["id"]}') + if list(input_dict['result'].keys()) == ['state']: # this is a "simplify" response + output_buffer.append('Method: simplify') + state = CTerm.from_kast(printer.kore_to_kast(kore_term(input_dict['result']['state']))) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + elif list(input_dict['result'].keys()) == ['module']: # this is an "add-module" response + output_buffer.append('Method: add-module') + output_buffer.append('Module:') + output_buffer.append(input_dict['result']['module']) + else: + try: # assume it is an "execute" response + output_buffer.append('Method: execute') + execute_result = ExecuteResult.from_dict(input_dict['result']) + output_buffer += pretty_print_execute_response(execute_result) + except KeyError as e: + _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') + exit(1) + if self.output_file is not None: + self.output_file.write('\n'.join(output_buffer)) + else: + print('\n'.join(output_buffer)) + except ValueError as e: + # shorten and print the error message in case kore_to_kast throws ValueError + _LOGGER.critical(str(e)[:200]) + exit(1) + class DisplayOptions(Options): minimize: bool @@ -285,6 +460,44 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) return parser + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + printer = KPrint(kompiled_dir) + if self.input == PrintInput.KORE_JSON: + _LOGGER.info(f'Reading Kore JSON from file: {self.term.name}') + kore = Pattern.from_json(self.term.read()) + term = printer.kore_to_kast(kore) + else: + _LOGGER.info(f'Reading Kast JSON from file: {self.term.name}') + term = KInner.from_json(self.term.read()) + if is_top(term): + self.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + else: + if self.minimize: + if self.omit_labels != None and self.keep_cells != None: + raise ValueError('You cannot use both --omit-labels and --keep-cells.') + + abstract_labels = self.omit_labels.split(',') if self.omit_labels is not None else [] + keep_cells = self.keep_cells.split(',') if self.keep_cells is not None else [] + minimized_disjuncts = [] + + for disjunct in flatten_label('#Or', term): + try: + minimized = minimize_term(disjunct, abstract_labels=abstract_labels, keep_cells=keep_cells) + config, constraint = split_config_and_constraints(minimized) + except ValueError as err: + raise ValueError('The minimized term does not contain a config cell.') from err + + if not is_top(constraint): + minimized_disjuncts.append(mlAnd([config, constraint], sort=GENERATED_TOP_CELL)) + else: + minimized_disjuncts.append(config) + term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) + + self.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + class ProveOptions(Command, DefinitionOptions, OutputFileOptions): main_file: Path @@ -308,6 +521,13 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') return parser + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + kprover = KProve(kompiled_dir, self.main_file) + final_state = kprover.prove(Path(self.spec_file), spec_module_name=self.spec_module, args=self.k_args) + self.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + class KDefinitionOptions(Options): includes: list[str] From 59e702fb1768e56325975eb8b013a1d4d0191d42 Mon Sep 17 00:00:00 2001 From: devops Date: Mon, 4 Mar 2024 19:48:16 +0000 Subject: [PATCH 35/62] Set Version: 0.1.678 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index e0dcb7e90..5c3160af5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.677' -release = '0.1.677' +version = '0.1.678' +release = '0.1.678' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index ca1ea1c1b..dd6d3c1fd 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.677 +0.1.678 diff --git a/pyproject.toml b/pyproject.toml index b40c625e0..1f1f18cbb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.677" +version = "0.1.678" description = "" authors = [ "Runtime Verification, Inc. ", From b4c6a97b27389b9a2e25375937b89d3e12e6a536 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 15:13:40 -0600 Subject: [PATCH 36/62] Remove default=None, use default() for lists --- src/pyk/cli/args.py | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 262d5371a..fe5c9ef40 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -120,8 +120,8 @@ def default() -> dict[str, Any]: @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: - parser.add_argument('--verbose', '-v', default=None, action='store_true', help='Verbose output.') - parser.add_argument('--debug', default=None, action='store_true', help='Debug output.') + parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output.') + parser.add_argument('--debug', action='store_true', help='Debug output.') return parser @@ -193,7 +193,7 @@ def default() -> dict[str, Any]: @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: - parser.add_argument('--output-file', type=FileType('w'), default=None) + parser.add_argument('--output-file', type=FileType('w')) return parser @@ -420,7 +420,7 @@ def default() -> dict[str, Any]: @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: - parser.add_argument('--minimize', dest='minimize', default=None, action='store_true', help='Minimize output.') + parser.add_argument('--minimize', dest='minimize', action='store_true', help='Minimize output.') parser.add_argument('--no-minimize', dest='minimize', action='store_false', help='Do not minimize output.') return parser @@ -453,11 +453,9 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' ) - parser.add_argument('--input', default=None, type=PrintInput, choices=list(PrintInput)) - parser.add_argument('--omit-labels', default=None, nargs='?', help='List of labels to omit from output.') - parser.add_argument( - '--keep-cells', default=None, nargs='?', help='List of cells with primitive values to keep in output.' - ) + parser.add_argument('--input', type=PrintInput, choices=list(PrintInput)) + parser.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.') + parser.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.') return parser def exec(self) -> None: @@ -545,16 +543,17 @@ def default() -> dict[str, Any]: 'syntax_module': None, 'definition_dir': None, 'md_selector': 'k', + 'includes': [], } @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( - '-I', type=str, dest='includes', default=[], action='append', help='Directories to lookup K definitions in.' + '-I', type=str, dest='includes', action='append', help='Directories to lookup K definitions in.' ) - parser.add_argument('--main-module', default=None, type=str, help='Name of the main module.') - parser.add_argument('--syntax-module', default=None, type=str, help='Name of the syntax module.') - parser.add_argument('--spec-module', default=None, type=str, help='Name of the spec module.') + parser.add_argument('--main-module', type=str, help='Name of the main module.') + parser.add_argument('--syntax-module', type=str, help='Name of the syntax module.') + parser.add_argument('--spec-module', type=str, help='Name of the spec module.') parser.add_argument('--definition', type=dir_path, dest='definition_dir', help='Path to definition to use.') parser.add_argument( '--md-selector', @@ -635,6 +634,7 @@ def default() -> dict[str, Any]: 'o1': False, 'o2': False, 'o3': False, + 'ccopt': [], } @staticmethod @@ -642,7 +642,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( '--emit-json', dest='emit_json', - default=None, action='store_true', help='Emit JSON definition after compilation.', ) @@ -652,42 +651,37 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument( '-ccopt', dest='ccopts', - default=[], action='append', help='Additional arguments to pass to llvm-kompile.', ) parser.add_argument( '--no-llvm-kompile', dest='llvm_kompile', - default=None, action='store_false', help='Do not run llvm-kompile process.', ) parser.add_argument( '--with-llvm-library', dest='llvm_library', - default=None, action='store_true', help='Make kompile generate a dynamic llvm library.', ) parser.add_argument( '--enable-llvm-debug', dest='enable_llvm_debug', - default=None, action='store_true', help='Make kompile generate debug symbols for llvm.', ) parser.add_argument( '--read-only-kompiled-directory', dest='read_only', - default=None, action='store_true', help='Generated a kompiled directory that K will not attempt to write to afterwards.', ) - parser.add_argument('-O0', dest='o0', default=None, action='store_true', help='Optimization level 0.') - parser.add_argument('-O1', dest='o1', default=None, action='store_true', help='Optimization level 1.') - parser.add_argument('-O2', dest='o2', default=None, action='store_true', help='Optimization level 2.') - parser.add_argument('-O3', dest='o3', default=None, action='store_true', help='Optimization level 3.') + parser.add_argument('-O0', dest='o0', action='store_true', help='Optimization level 0.') + parser.add_argument('-O1', dest='o1', action='store_true', help='Optimization level 1.') + parser.add_argument('-O2', dest='o2', action='store_true', help='Optimization level 2.') + parser.add_argument('-O3', dest='o3', action='store_true', help='Optimization level 3.') return parser @@ -702,7 +696,7 @@ def default() -> dict[str, Any]: @staticmethod def args(parser: ArgumentParser) -> ArgumentParser: - parser.add_argument('--workers', '-j', default=None, type=int, help='Number of processes to run in parallel.') + parser.add_argument('--workers', '-j', type=int, help='Number of processes to run in parallel.') return parser From 3e6d4048a6068583b0933d7fb0a42ff3d8c4a086 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 15:23:03 -0600 Subject: [PATCH 37/62] Fix naming --- src/pyk/__main__.py | 4 ++-- src/pyk/cli/args.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index d17a70753..358e1e01e 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from .cli.args import ( - KEVMCLI, + CLI, CoverageOptions, GraphImportsOptions, JsonToKoreOptions, @@ -30,7 +30,7 @@ def main() -> None: # This change makes it so that in most cases, by default, pyk doesn't run out of stack space. sys.setrecursionlimit(10**7) - cli = KEVMCLI( + cli = CLI( [ CoverageOptions, GraphImportsOptions, diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index fe5c9ef40..f3140e6f9 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -49,7 +49,7 @@ class PrintInput(Enum): KAST_JSON = 'kast-json' -class KEVMCLI: +class CLI: commands: list[type[Command]] # Input a list of all Command types to be used From 2f67838918cba851e903ff3378a0d3ba7c663ace Mon Sep 17 00:00:00 2001 From: devops Date: Mon, 4 Mar 2024 21:23:45 +0000 Subject: [PATCH 38/62] Set Version: 0.1.679 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 5c3160af5..0ba92f173 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.678' -release = '0.1.678' +version = '0.1.679' +release = '0.1.679' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index dd6d3c1fd..f6e1bcd56 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.678 +0.1.679 diff --git a/pyproject.toml b/pyproject.toml index 1f1f18cbb..4a6b84e43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.678" +version = "0.1.679" description = "" authors = [ "Runtime Verification, Inc. ", From 9d30d23072feef7015fbeb13294270389cc8b139 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 18:09:03 -0600 Subject: [PATCH 39/62] Rename args to update_args, don't return ArgumentParser when updating --- src/pyk/cli/args.py | 52 ++++++++++++++------------------------- src/pyk/kdist/__main__.py | 9 +++---- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index f3140e6f9..05d7963ce 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -102,8 +102,8 @@ def all_args(cls: type[Options]) -> ArgumentParser: mro = cls.mro() mro.reverse() for cl in mro: - if hasattr(cl, 'args') and 'args' in cl.__dict__: - parser = cl.args(parser) + if hasattr(cl, 'update_args') and 'update_args' in cl.__dict__: + parser = cl.update_args(parser) return parser @@ -119,10 +119,9 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output.') parser.add_argument('--debug', action='store_true', help='Debug output.') - return parser class Command(LoggingOptions): @@ -192,18 +191,16 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('--output-file', type=FileType('w')) - return parser class DefinitionOptions(LoggingOptions): definition_dir: Path @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('definition_dir', type=dir_path, help='Path to definition directory.') - return parser class CoverageOptions(Command, DefinitionOptions, OutputFileOptions): @@ -218,9 +215,8 @@ def help_str() -> str: return 'Convert coverage file to human readable log.' @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') - return parser def exec(self) -> None: kompiled_dir: Path = self.definition_dir @@ -272,7 +268,7 @@ def help_str() -> str: return 'Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.' @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( 'reference_request_file', type=FileType('r'), @@ -283,7 +279,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: type=FileType('r'), help='An input file containing a JSON RPC response with KoreJSON payload.', ) - return parser def exec(self) -> None: """ @@ -319,13 +314,12 @@ def help_str() -> str: return 'Pretty-print an RPC request/response' @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( 'input_file', type=FileType('r'), help='An input file containing the JSON RPC request or response with KoreJSON payload.', ) - return parser def exec(self) -> None: kompiled_dir: Path = self.definition_dir @@ -419,10 +413,9 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('--minimize', dest='minimize', action='store_true', help='Minimize output.') parser.add_argument('--no-minimize', dest='minimize', action='store_false', help='Do not minimize output.') - return parser class PrintOptions(Command, DefinitionOptions, OutputFileOptions, DisplayOptions): @@ -449,14 +442,13 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' ) parser.add_argument('--input', type=PrintInput, choices=list(PrintInput)) parser.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.') parser.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.') - return parser def exec(self) -> None: kompiled_dir: Path = self.definition_dir @@ -512,12 +504,11 @@ def help_str() -> str: return 'Prove an input specification (using kprovex).' @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('main_file', type=str, help='Main file used for kompilation.') parser.add_argument('spec_file', type=str, help='File with the specification module.') parser.add_argument('spec_module', type=str, help='Module with claims to be proven.') parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') - return parser def exec(self) -> None: kompiled_dir: Path = self.definition_dir @@ -547,7 +538,7 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( '-I', type=str, dest='includes', action='append', help='Directories to lookup K definitions in.' ) @@ -560,7 +551,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: type=str, help='Code selector expression to use when reading markdown.', ) - return parser class SaveDirOptions(Options): @@ -573,9 +563,8 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('--save-directory', type=ensure_dir_path, help='Path to where CFGs are stored.') - return parser class SpecOptions(SaveDirOptions): @@ -591,7 +580,7 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('spec_file', type=file_path, help='Path to spec file.') parser.add_argument( '--claim', @@ -607,7 +596,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: action='append', help='Skip listed claims, MODULE_NAME.claim-id', ) - return parser class KompileOptions(Options): @@ -638,7 +626,7 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( '--emit-json', dest='emit_json', @@ -682,7 +670,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: parser.add_argument('-O1', dest='o1', action='store_true', help='Optimization level 1.') parser.add_argument('-O2', dest='o2', action='store_true', help='Optimization level 2.') parser.add_argument('-O3', dest='o3', action='store_true', help='Optimization level 3.') - return parser class ParallelOptions(Options): @@ -695,9 +682,8 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('--workers', '-j', type=int, help='Number of processes to run in parallel.') - return parser class BugReportOptions(Options): @@ -708,13 +694,12 @@ def default() -> dict[str, Any]: return {'bug_report': None} @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( '--bug-report', type=bug_report_arg, help='Generate bug report with given name', ) - return parser class SMTOptions(Options): @@ -731,7 +716,7 @@ def default() -> dict[str, Any]: } @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('--smt-timeout', dest='smt_timeout', type=int, help='Timeout in ms to use for SMT queries.') parser.add_argument( '--smt-retry-limit', @@ -745,4 +730,3 @@ def args(parser: ArgumentParser) -> ArgumentParser: type=str, help='Z3 tactic to use when checking satisfiability. Example: (check-sat-using smt)', ) - return parser diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index 4489d9f12..8a1c96c3e 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -125,7 +125,7 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: return base @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument('targets', metavar='TARGET', nargs='*', default='*', help='target to build') parser.add_argument( '-a', @@ -138,7 +138,6 @@ def args(parser: ArgumentParser) -> ArgumentParser: ) parser.add_argument('-f', '--force', action='store_true', default=None, help='force build') parser.add_argument('-j', '--jobs', metavar='N', type=int, default=None, help='maximal number of build jobs') - return parser class KDistCleanOptions(LoggingOptions): @@ -154,14 +153,13 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: return base @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( 'target', metavar='TARGET', nargs='?', help='target to clean', ) - return parser class KDistWhichOptions(LoggingOptions): @@ -177,14 +175,13 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: return base @staticmethod - def args(parser: ArgumentParser) -> ArgumentParser: + def update_args(parser: ArgumentParser) -> None: parser.add_argument( 'target', metavar='TARGET', nargs='?', help='target to print directory for', ) - return parser class KDistListOptions(LoggingOptions): From 4d61d2ffdde39e84d2d4e335764a4fbe25d87557 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 5 Mar 2024 00:09:31 +0000 Subject: [PATCH 40/62] Set Version: 0.1.680 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 0ba92f173..298d674b1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.679' -release = '0.1.679' +version = '0.1.680' +release = '0.1.680' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index f6e1bcd56..94e7ee86e 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.679 +0.1.680 diff --git a/pyproject.toml b/pyproject.toml index 4a6b84e43..e172f2a87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.679" +version = "0.1.680" description = "" authors = [ "Runtime Verification, Inc. ", From ec84092c0b0a96e3d4e5a6ec7e3b933d322cde60 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 18:22:49 -0600 Subject: [PATCH 41/62] Fix all_args --- src/pyk/cli/args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 05d7963ce..7e5e8cbc2 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -103,7 +103,7 @@ def all_args(cls: type[Options]) -> ArgumentParser: mro.reverse() for cl in mro: if hasattr(cl, 'update_args') and 'update_args' in cl.__dict__: - parser = cl.update_args(parser) + cl.update_args(parser) return parser From 3cfcf6bf1164fcae5a26616715193d0932e2ded9 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Mon, 4 Mar 2024 19:37:19 -0600 Subject: [PATCH 42/62] Remove default values from add_argument in kdist --- src/pyk/kdist/__main__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index 8a1c96c3e..40a234153 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -113,6 +113,8 @@ def defaults() -> dict[str, Any]: return { 'force': False, 'jobs': 1, + 'targets': [], + 'args': [], } @staticmethod @@ -126,18 +128,17 @@ def parser(base: _SubParsersAction) -> _SubParsersAction: @staticmethod def update_args(parser: ArgumentParser) -> None: - parser.add_argument('targets', metavar='TARGET', nargs='*', default='*', help='target to build') + parser.add_argument('targets', metavar='TARGET', nargs='*', help='target to build') parser.add_argument( '-a', '--arg', dest='args', metavar='ARG', action='append', - default=[], help='build with argument', ) - parser.add_argument('-f', '--force', action='store_true', default=None, help='force build') - parser.add_argument('-j', '--jobs', metavar='N', type=int, default=None, help='maximal number of build jobs') + parser.add_argument('-f', '--force', action='store_true', help='force build') + parser.add_argument('-j', '--jobs', metavar='N', type=int, help='maximal number of build jobs') class KDistCleanOptions(LoggingOptions): From 181e45e4c13987ff4dfded72bae80f0d03610e3a Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 14:09:22 -0600 Subject: [PATCH 43/62] Fix kdist commands --- src/pyk/kdist/__main__.py | 185 ++++++++++++++------------------------ 1 file changed, 68 insertions(+), 117 deletions(-) diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index 40a234153..ce627d2b7 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -2,16 +2,14 @@ import fnmatch import logging -from argparse import ArgumentParser from typing import TYPE_CHECKING, Any -from pyk.cli.args import LoggingOptions -from pyk.cli.utils import loglevel +from pyk.cli.args import CLI, Command from ..kdist import kdist, target_ids if TYPE_CHECKING: - from argparse import Namespace, _SubParsersAction + from argparse import ArgumentParser from typing import Final @@ -20,42 +18,12 @@ def main() -> None: - args = _parse_arguments() - - logging.basicConfig(level=loglevel(args), format=_LOG_FORMAT) - - if args.command == 'build': - _exec_build(**vars(args)) - - elif args.command == 'clean': - _exec_clean(args.target) - - elif args.command == 'which': - _exec_which(args.target) - - elif args.command == 'list': - _exec_list() - - else: - raise AssertionError() - - -def _exec_build( - command: str, - targets: list[str], - args: list[str], - jobs: int, - force: bool, - verbose: bool, - debug: bool, -) -> None: - kdist.build( - target_ids=_process_targets(targets), - args=_process_args(args), - jobs=jobs, - force=force, - verbose=verbose or debug, - ) + kdist_cli = CLI({KDistBuildCommand, KDistCleanCommand, KDistWhichCommand, KDistListCommand}) + parser = kdist_cli.create_argument_parser() + parser.parse_args() + args = parser.parse_args() + command = kdist_cli.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) + command.exec() def _process_targets(targets: list[str]) -> list[str]: @@ -80,36 +48,22 @@ def _process_args(args: list[str]) -> dict[str, str]: return res -def _exec_clean(target: str | None) -> None: - res = kdist.clean(target) - print(res) - - -def _exec_which(target: str | None) -> None: - res = kdist.which(target) - print(res) - - -def _exec_list() -> None: - targets_by_plugin: dict[str, list[str]] = {} - for plugin_name, target_name in target_ids(): - targets = targets_by_plugin.get(plugin_name, []) - targets.append(target_name) - targets_by_plugin[plugin_name] = targets - - for plugin_name in targets_by_plugin: - print(plugin_name) - for target_name in targets_by_plugin[plugin_name]: - print(f'* {target_name}') - - -class KDistBuildOptions(LoggingOptions): +class KDistBuildCommand(Command): targets: list[str] force: bool jobs: int + args: list[str] + + @staticmethod + def name() -> str: + return 'build' @staticmethod - def defaults() -> dict[str, Any]: + def help_str() -> str: + return 'build targets' + + @staticmethod + def default() -> dict[str, Any]: return { 'force': False, 'jobs': 1, @@ -117,15 +71,6 @@ def defaults() -> dict[str, Any]: 'args': [], } - @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'build', - help='build targets', - parents=[KDistBuildOptions.all_args()], - ) - return base - @staticmethod def update_args(parser: ArgumentParser) -> None: parser.add_argument('targets', metavar='TARGET', nargs='*', help='target to build') @@ -140,18 +85,26 @@ def update_args(parser: ArgumentParser) -> None: parser.add_argument('-f', '--force', action='store_true', help='force build') parser.add_argument('-j', '--jobs', metavar='N', type=int, help='maximal number of build jobs') + def exec(self) -> None: + kdist.build( + target_ids=_process_targets(self.targets), + args=_process_args(self.args), + jobs=self.jobs, + force=self.force, + verbose=self.verbose or self.debug, + ) + -class KDistCleanOptions(LoggingOptions): +class KDistCleanCommand(Command): target: str @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'clean', - help='clean targets', - parents=[KDistCleanOptions.all_args()], - ) - return base + def name() -> str: + return 'clean' + + @staticmethod + def help_str() -> str: + return 'clean targets' @staticmethod def update_args(parser: ArgumentParser) -> None: @@ -162,18 +115,21 @@ def update_args(parser: ArgumentParser) -> None: help='target to clean', ) + def exec(self) -> None: + res = kdist.clean(self.target) + print(res) + -class KDistWhichOptions(LoggingOptions): +class KDistWhichCommand(Command): target: str @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'which', - help='print target location', - parents=[KDistCleanOptions.all_args()], - ) - return base + def name() -> str: + return 'which' + + @staticmethod + def help_str() -> str: + return 'print target location' @staticmethod def update_args(parser: ArgumentParser) -> None: @@ -184,36 +140,31 @@ def update_args(parser: ArgumentParser) -> None: help='target to print directory for', ) + def exec(self) -> None: + res = kdist.which(self.target) + print(res) -class KDistListOptions(LoggingOptions): - @staticmethod - def parser(base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - 'list', - help='print list of available targets', - parents=[KDistCleanOptions.all_args()], - ) - return base +class KDistListCommand(Command): + @staticmethod + def name() -> str: + return 'list' -def _parse_arguments() -> Namespace: - def add_target_arg(parser: ArgumentParser, help_text: str) -> None: - parser.add_argument( - 'target', - metavar='TARGET', - nargs='?', - help=help_text, - ) - - parser = ArgumentParser(prog='kdist', parents=[LoggingOptions.all_args()]) - command_parser = parser.add_subparsers(dest='command', required=True) - - command_parser = KDistBuildOptions.parser(command_parser) - command_parser = KDistCleanOptions.parser(command_parser) - command_parser = KDistWhichOptions.parser(command_parser) - command_parser = KDistListOptions.parser(command_parser) - - return parser.parse_args() + @staticmethod + def help_str() -> str: + return 'print list of available targets' + + def exec(self) -> None: + targets_by_plugin: dict[str, list[str]] = {} + for plugin_name, target_name in target_ids(): + targets = targets_by_plugin.get(plugin_name, []) + targets.append(target_name) + targets_by_plugin[plugin_name] = targets + + for plugin_name in targets_by_plugin: + print(plugin_name) + for target_name in targets_by_plugin[plugin_name]: + print(f'* {target_name}') if __name__ == '__main__': From b8315cdfe828f06d436989e76c76a218d5a4dfca Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 14:25:02 -0600 Subject: [PATCH 44/62] Fix typo --- src/pyk/cli/args.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 7e5e8cbc2..2bd5dd6da 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -130,7 +130,6 @@ class Command(LoggingOptions): def name() -> str: ... - @staticmethod @staticmethod @abstractmethod def help_str() -> str: From 0aac0f2046b5f338d5b065211c898735b69102ee Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 14:28:05 -0600 Subject: [PATCH 45/62] Use reversed instead of reverse --- src/pyk/cli/args.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 2bd5dd6da..b59b4f8c0 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -83,9 +83,7 @@ class Options: def __init__(self, args: dict[str, Any]) -> None: # Get defaults from this and all superclasses that define them, preferring the most specific class defaults: dict[str, Any] = {} - mro = type(self).mro() - mro.reverse() - for cl in mro: + for cl in reversed(type(self).mro()): if hasattr(cl, 'default'): defaults = defaults | cl.default() From 7b2628b92d0b9e2e6aff91d56e0d8e89db77f56f Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 14:39:27 -0600 Subject: [PATCH 46/62] Move commands into separate module --- src/pyk/__main__.py | 34 +-- src/pyk/cli/args.py | 422 +------------------------------------ src/pyk/cli/cli.py | 430 ++++++++++++++++++++++++++++++++++++++ src/pyk/kdist/__main__.py | 2 +- 4 files changed, 450 insertions(+), 438 deletions(-) create mode 100644 src/pyk/cli/cli.py diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 358e1e01e..c88a18bc1 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -4,16 +4,16 @@ import sys from typing import TYPE_CHECKING -from .cli.args import ( +from .cli.cli import ( CLI, - CoverageOptions, - GraphImportsOptions, - JsonToKoreOptions, - KoreToJsonOptions, - PrintOptions, - ProveOptions, - RPCKastOptions, - RPCPrintOptions, + CoverageCommand, + GraphImportsCommand, + JsonToKoreCommand, + KoreToJsonCommand, + PrintCommand, + ProveCommand, + RPCKastCommand, + RPCPrintCommand, ) from .cli.utils import LOG_FORMAT, loglevel @@ -32,14 +32,14 @@ def main() -> None: cli = CLI( [ - CoverageOptions, - GraphImportsOptions, - JsonToKoreOptions, - KoreToJsonOptions, - PrintOptions, - ProveOptions, - RPCKastOptions, - RPCPrintOptions, + CoverageCommand, + GraphImportsCommand, + JsonToKoreCommand, + KoreToJsonCommand, + PrintCommand, + ProveCommand, + RPCKastCommand, + RPCPrintCommand, ] ) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index b59b4f8c0..4f577c707 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -1,42 +1,15 @@ from __future__ import annotations -import json import sys -from abc import abstractmethod from argparse import ArgumentParser, FileType -from enum import Enum -from pathlib import Path from typing import IO, TYPE_CHECKING, Any -from graphviz import Digraph - -from pyk.coverage import get_rule_by_id, strip_coverage_logger -from pyk.cterm import CTerm -from pyk.kast.inner import KInner -from pyk.kast.manip import ( - flatten_label, - minimize_rule, - minimize_term, - propagate_up_constraints, - remove_source_map, - split_config_and_constraints, -) -from pyk.kast.outer import read_kast_definition -from pyk.kast.pretty import PrettyPrinter -from pyk.kore.parser import KoreParser -from pyk.kore.rpc import ExecuteResult, StopReason -from pyk.kore.syntax import Pattern, kore_term -from pyk.ktool.kprint import KPrint -from pyk.ktool.kprove import KProve -from pyk.prelude.k import GENERATED_TOP_CELL -from pyk.prelude.ml import is_top, mlAnd, mlOr -from pyk.utils import _LOGGER, ensure_dir_path +from pyk.utils import ensure_dir_path from .utils import bug_report_arg, dir_path, file_path if TYPE_CHECKING: - from argparse import _SubParsersAction - from collections.abc import Iterable + from pathlib import Path from typing import TypeVar from ..utils import BugReport @@ -44,41 +17,6 @@ T = TypeVar('T') -class PrintInput(Enum): - KORE_JSON = 'kore-json' - KAST_JSON = 'kast-json' - - -class CLI: - commands: list[type[Command]] - - # Input a list of all Command types to be used - def __init__(self, commands: Iterable[type[Command]]): - self.commands = list(commands) - - # Return an instance of the correct Options subclass by matching its name with the requested command - def generate_command(self, args: dict[str, Any]) -> Command: - command = args['command'].lower() - for cmd_type in self.commands: - if cmd_type.name() == command: - return cmd_type(args) - raise ValueError(f'Unrecognized command: {command}') - - # Generate the parsers for all commands - def add_parsers(self, base: _SubParsersAction) -> _SubParsersAction: - for cmd_type in self.commands: - base = cmd_type.parser(base) - return base - - def create_argument_parser(self) -> ArgumentParser: - pyk_args = ArgumentParser() - pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) - - pyk_args_command = self.add_parsers(pyk_args_command) - - return pyk_args - - class Options: def __init__(self, args: dict[str, Any]) -> None: # Get defaults from this and all superclasses that define them, preferring the most specific class @@ -122,62 +60,6 @@ def update_args(parser: ArgumentParser) -> None: parser.add_argument('--debug', action='store_true', help='Debug output.') -class Command(LoggingOptions): - @staticmethod - @abstractmethod - def name() -> str: - ... - - @staticmethod - @abstractmethod - def help_str() -> str: - ... - - @abstractmethod - def exec(self) -> None: - ... - - @classmethod - def parser(cls, base: _SubParsersAction) -> _SubParsersAction: - base.add_parser( - name=cls.name(), - help=cls.help_str(), - parents=[cls.all_args()], - ) - return base - - -class JsonToKoreOptions(Command): - @staticmethod - def name() -> str: - return 'json-to-kore' - - @staticmethod - def help_str() -> str: - return 'Convert JSON to textual KORE' - - def exec(self) -> None: - text = sys.stdin.read() - kore = Pattern.from_json(text) - kore.write(sys.stdout) - sys.stdout.write('\n') - - -class KoreToJsonOptions(Command): - @staticmethod - def name() -> str: - return 'kore-to-json' - - @staticmethod - def help_str() -> str: - return 'Convert textual KORE to JSON' - - def exec(self) -> None: - text = sys.stdin.read() - kore = KoreParser(text).pattern() - print(kore.json) - - class OutputFileOptions(Options): output_file: IO[Any] @@ -200,206 +82,6 @@ def update_args(parser: ArgumentParser) -> None: parser.add_argument('definition_dir', type=dir_path, help='Path to definition directory.') -class CoverageOptions(Command, DefinitionOptions, OutputFileOptions): - coverage_file: IO[Any] - - @staticmethod - def name() -> str: - return 'coverage' - - @staticmethod - def help_str() -> str: - return 'Convert coverage file to human readable log.' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) - pretty_printer = PrettyPrinter(definition) - for rid in self.coverage_file: - rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) - self.output_file.write('\n\n') - self.output_file.write('Rule: ' + rid.strip()) - self.output_file.write('\nUnparsed:\n') - self.output_file.write(pretty_printer.print(rule)) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - - -class GraphImportsOptions(Command, DefinitionOptions): - @staticmethod - def name() -> str: - return 'graph-imports' - - @staticmethod - def help_str() -> str: - return 'Graph the imports of a given definition.' - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - kprinter = KPrint(kompiled_dir) - definition = kprinter.definition - import_graph = Digraph() - graph_file = kompiled_dir / 'import-graph' - for module in definition.modules: - module_name = module.name - import_graph.node(module_name) - for module_import in module.imports: - import_graph.edge(module_name, module_import.name) - import_graph.render(graph_file) - _LOGGER.info(f'Wrote file: {graph_file}') - - -class RPCKastOptions(Command, OutputFileOptions): - reference_request_file: IO[Any] - response_file: IO[Any] - - @staticmethod - def name() -> str: - return 'rpc-kast' - - @staticmethod - def help_str() -> str: - return 'Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument( - 'reference_request_file', - type=FileType('r'), - help='An input file containing a JSON RPC request to server as a reference for the new request.', - ) - parser.add_argument( - 'response_file', - type=FileType('r'), - help='An input file containing a JSON RPC response with KoreJSON payload.', - ) - - def exec(self) -> None: - """ - Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, - copying parameters from a reference request. - """ - reference_request = json.loads(self.reference_request_file.read()) - input_dict = json.loads(self.response_file.read()) - execute_result = ExecuteResult.from_dict(input_dict['result']) - non_state_keys = set(reference_request['params'].keys()).difference(['state']) - request_params = {} - for key in non_state_keys: - request_params[key] = reference_request['params'][key] - request_params['state'] = {'format': 'KORE', 'version': 1, 'term': execute_result.state.kore.dict} - request = { - 'jsonrpc': reference_request['jsonrpc'], - 'id': reference_request['id'], - 'method': reference_request['method'], - 'params': request_params, - } - self.output_file.write(json.dumps(request)) - - -class RPCPrintOptions(Command, DefinitionOptions, OutputFileOptions): - input_file: IO[Any] - - @staticmethod - def name() -> str: - return 'rpc-print' - - @staticmethod - def help_str() -> str: - return 'Pretty-print an RPC request/response' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument( - 'input_file', - type=FileType('r'), - help='An input file containing the JSON RPC request or response with KoreJSON payload.', - ) - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - printer = KPrint(kompiled_dir) - input_dict = json.loads(self.input_file.read()) - output_buffer = [] - - def pretty_print_request(request_params: dict[str, Any]) -> list[str]: - output_buffer = [] - non_state_keys = set(request_params.keys()).difference(['state']) - for key in non_state_keys: - output_buffer.append(f'{key}: {request_params[key]}') - state = CTerm.from_kast(printer.kore_to_kast(kore_term(request_params['state']))) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - return output_buffer - - def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: - output_buffer = [] - output_buffer.append(f'Depth: {execute_result.depth}') - output_buffer.append(f'Stop reason: {execute_result.reason.value}') - if execute_result.reason == StopReason.TERMINAL_RULE or execute_result.reason == StopReason.CUT_POINT_RULE: - output_buffer.append(f'Stop rule: {execute_result.rule}') - output_buffer.append( - f'Number of next states: {len(execute_result.next_states) if execute_result.next_states is not None else 0}' - ) - state = CTerm.from_kast(printer.kore_to_kast(execute_result.state.kore)) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - if execute_result.next_states is not None: - next_states = [CTerm.from_kast(printer.kore_to_kast(s.kore)) for s in execute_result.next_states] - for i, s in enumerate(next_states): - output_buffer.append(f'Next state #{i}:') - output_buffer.append(printer.pretty_print(s.kast, sort_collections=True)) - return output_buffer - - try: - if 'method' in input_dict: - output_buffer.append('JSON RPC request') - output_buffer.append(f'id: {input_dict["id"]}') - output_buffer.append(f'Method: {input_dict["method"]}') - try: - if 'state' in input_dict['params']: - output_buffer += pretty_print_request(input_dict['params']) - else: # this is an "add-module" request, skip trying to print state - for key in input_dict['params'].keys(): - output_buffer.append(f'{key}: {input_dict["params"][key]}') - except KeyError as e: - _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') - exit(1) - else: - if not 'result' in input_dict: - _LOGGER.critical('The input is neither a request not a resonse') - exit(1) - output_buffer.append('JSON RPC Response') - output_buffer.append(f'id: {input_dict["id"]}') - if list(input_dict['result'].keys()) == ['state']: # this is a "simplify" response - output_buffer.append('Method: simplify') - state = CTerm.from_kast(printer.kore_to_kast(kore_term(input_dict['result']['state']))) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - elif list(input_dict['result'].keys()) == ['module']: # this is an "add-module" response - output_buffer.append('Method: add-module') - output_buffer.append('Module:') - output_buffer.append(input_dict['result']['module']) - else: - try: # assume it is an "execute" response - output_buffer.append('Method: execute') - execute_result = ExecuteResult.from_dict(input_dict['result']) - output_buffer += pretty_print_execute_response(execute_result) - except KeyError as e: - _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') - exit(1) - if self.output_file is not None: - self.output_file.write('\n'.join(output_buffer)) - else: - print('\n'.join(output_buffer)) - except ValueError as e: - # shorten and print the error message in case kore_to_kast throws ValueError - _LOGGER.critical(str(e)[:200]) - exit(1) - - class DisplayOptions(Options): minimize: bool @@ -415,106 +97,6 @@ def update_args(parser: ArgumentParser) -> None: parser.add_argument('--no-minimize', dest='minimize', action='store_false', help='Do not minimize output.') -class PrintOptions(Command, DefinitionOptions, OutputFileOptions, DisplayOptions): - term: IO[Any] - input: PrintInput - minimize: bool - omit_labels: str | None - keep_cells: str | None - - @staticmethod - def name() -> str: - return 'print' - - @staticmethod - def help_str() -> str: - return 'Pretty print a term.' - - @staticmethod - def default() -> dict[str, Any]: - return { - 'input': PrintInput.KAST_JSON, - 'omit_labels': None, - 'keep_cells': None, - } - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument( - 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' - ) - parser.add_argument('--input', type=PrintInput, choices=list(PrintInput)) - parser.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.') - parser.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.') - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - printer = KPrint(kompiled_dir) - if self.input == PrintInput.KORE_JSON: - _LOGGER.info(f'Reading Kore JSON from file: {self.term.name}') - kore = Pattern.from_json(self.term.read()) - term = printer.kore_to_kast(kore) - else: - _LOGGER.info(f'Reading Kast JSON from file: {self.term.name}') - term = KInner.from_json(self.term.read()) - if is_top(term): - self.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - else: - if self.minimize: - if self.omit_labels != None and self.keep_cells != None: - raise ValueError('You cannot use both --omit-labels and --keep-cells.') - - abstract_labels = self.omit_labels.split(',') if self.omit_labels is not None else [] - keep_cells = self.keep_cells.split(',') if self.keep_cells is not None else [] - minimized_disjuncts = [] - - for disjunct in flatten_label('#Or', term): - try: - minimized = minimize_term(disjunct, abstract_labels=abstract_labels, keep_cells=keep_cells) - config, constraint = split_config_and_constraints(minimized) - except ValueError as err: - raise ValueError('The minimized term does not contain a config cell.') from err - - if not is_top(constraint): - minimized_disjuncts.append(mlAnd([config, constraint], sort=GENERATED_TOP_CELL)) - else: - minimized_disjuncts.append(config) - term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) - - self.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - - -class ProveOptions(Command, DefinitionOptions, OutputFileOptions): - main_file: Path - spec_file: Path - spec_module: str - k_args: Iterable[str] - - @staticmethod - def name() -> str: - return 'prove' - - @staticmethod - def help_str() -> str: - return 'Prove an input specification (using kprovex).' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument('main_file', type=str, help='Main file used for kompilation.') - parser.add_argument('spec_file', type=str, help='File with the specification module.') - parser.add_argument('spec_module', type=str, help='Module with claims to be proven.') - parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - kprover = KProve(kompiled_dir, self.main_file) - final_state = kprover.prove(Path(self.spec_file), spec_module_name=self.spec_module, args=self.k_args) - self.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - - class KDefinitionOptions(Options): includes: list[str] main_module: str | None diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py new file mode 100644 index 000000000..aed124746 --- /dev/null +++ b/src/pyk/cli/cli.py @@ -0,0 +1,430 @@ +from __future__ import annotations + +import json +import sys +from abc import abstractmethod +from argparse import ArgumentParser, FileType +from enum import Enum +from pathlib import Path +from typing import IO, TYPE_CHECKING, Any + +from graphviz import Digraph + +from pyk.coverage import get_rule_by_id, strip_coverage_logger +from pyk.cterm import CTerm +from pyk.kast.inner import KInner +from pyk.kast.manip import ( + flatten_label, + minimize_rule, + minimize_term, + propagate_up_constraints, + remove_source_map, + split_config_and_constraints, +) +from pyk.kast.outer import read_kast_definition +from pyk.kast.pretty import PrettyPrinter +from pyk.kore.parser import KoreParser +from pyk.kore.rpc import ExecuteResult, StopReason +from pyk.kore.syntax import Pattern, kore_term +from pyk.ktool.kprint import KPrint +from pyk.ktool.kprove import KProve +from pyk.prelude.k import GENERATED_TOP_CELL +from pyk.prelude.ml import is_top, mlAnd, mlOr +from pyk.utils import _LOGGER + +from .args import DefinitionOptions, DisplayOptions, LoggingOptions, OutputFileOptions + +if TYPE_CHECKING: + from argparse import _SubParsersAction + from collections.abc import Iterable + + +class PrintInput(Enum): + KORE_JSON = 'kore-json' + KAST_JSON = 'kast-json' + + +class CLI: + commands: list[type[Command]] + + # Input a list of all Command types to be used + def __init__(self, commands: Iterable[type[Command]]): + self.commands = list(commands) + + # Return an instance of the correct Options subclass by matching its name with the requested command + def generate_command(self, args: dict[str, Any]) -> Command: + command = args['command'].lower() + for cmd_type in self.commands: + if cmd_type.name() == command: + return cmd_type(args) + raise ValueError(f'Unrecognized command: {command}') + + # Generate the parsers for all commands + def add_parsers(self, base: _SubParsersAction) -> _SubParsersAction: + for cmd_type in self.commands: + base = cmd_type.parser(base) + return base + + def create_argument_parser(self) -> ArgumentParser: + pyk_args = ArgumentParser() + pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) + + pyk_args_command = self.add_parsers(pyk_args_command) + + return pyk_args + + +class Command(LoggingOptions): + @staticmethod + @abstractmethod + def name() -> str: + ... + + @staticmethod + @abstractmethod + def help_str() -> str: + ... + + @abstractmethod + def exec(self) -> None: + ... + + @classmethod + def parser(cls, base: _SubParsersAction) -> _SubParsersAction: + base.add_parser( + name=cls.name(), + help=cls.help_str(), + parents=[cls.all_args()], + ) + return base + + +class JsonToKoreCommand(Command): + @staticmethod + def name() -> str: + return 'json-to-kore' + + @staticmethod + def help_str() -> str: + return 'Convert JSON to textual KORE' + + def exec(self) -> None: + text = sys.stdin.read() + kore = Pattern.from_json(text) + kore.write(sys.stdout) + sys.stdout.write('\n') + + +class KoreToJsonCommand(Command): + @staticmethod + def name() -> str: + return 'kore-to-json' + + @staticmethod + def help_str() -> str: + return 'Convert textual KORE to JSON' + + def exec(self) -> None: + text = sys.stdin.read() + kore = KoreParser(text).pattern() + print(kore.json) + + +class CoverageCommand(Command, DefinitionOptions, OutputFileOptions): + coverage_file: IO[Any] + + @staticmethod + def name() -> str: + return 'coverage' + + @staticmethod + def help_str() -> str: + return 'Convert coverage file to human readable log.' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) + pretty_printer = PrettyPrinter(definition) + for rid in self.coverage_file: + rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) + self.output_file.write('\n\n') + self.output_file.write('Rule: ' + rid.strip()) + self.output_file.write('\nUnparsed:\n') + self.output_file.write(pretty_printer.print(rule)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + + +class GraphImportsCommand(Command, DefinitionOptions): + @staticmethod + def name() -> str: + return 'graph-imports' + + @staticmethod + def help_str() -> str: + return 'Graph the imports of a given definition.' + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + kprinter = KPrint(kompiled_dir) + definition = kprinter.definition + import_graph = Digraph() + graph_file = kompiled_dir / 'import-graph' + for module in definition.modules: + module_name = module.name + import_graph.node(module_name) + for module_import in module.imports: + import_graph.edge(module_name, module_import.name) + import_graph.render(graph_file) + _LOGGER.info(f'Wrote file: {graph_file}') + + +class RPCKastCommand(Command, OutputFileOptions): + reference_request_file: IO[Any] + response_file: IO[Any] + + @staticmethod + def name() -> str: + return 'rpc-kast' + + @staticmethod + def help_str() -> str: + return 'Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument( + 'reference_request_file', + type=FileType('r'), + help='An input file containing a JSON RPC request to server as a reference for the new request.', + ) + parser.add_argument( + 'response_file', + type=FileType('r'), + help='An input file containing a JSON RPC response with KoreJSON payload.', + ) + + def exec(self) -> None: + """ + Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, + copying parameters from a reference request. + """ + reference_request = json.loads(self.reference_request_file.read()) + input_dict = json.loads(self.response_file.read()) + execute_result = ExecuteResult.from_dict(input_dict['result']) + non_state_keys = set(reference_request['params'].keys()).difference(['state']) + request_params = {} + for key in non_state_keys: + request_params[key] = reference_request['params'][key] + request_params['state'] = {'format': 'KORE', 'version': 1, 'term': execute_result.state.kore.dict} + request = { + 'jsonrpc': reference_request['jsonrpc'], + 'id': reference_request['id'], + 'method': reference_request['method'], + 'params': request_params, + } + self.output_file.write(json.dumps(request)) + + +class RPCPrintCommand(Command, DefinitionOptions, OutputFileOptions): + input_file: IO[Any] + + @staticmethod + def name() -> str: + return 'rpc-print' + + @staticmethod + def help_str() -> str: + return 'Pretty-print an RPC request/response' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument( + 'input_file', + type=FileType('r'), + help='An input file containing the JSON RPC request or response with KoreJSON payload.', + ) + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + printer = KPrint(kompiled_dir) + input_dict = json.loads(self.input_file.read()) + output_buffer = [] + + def pretty_print_request(request_params: dict[str, Any]) -> list[str]: + output_buffer = [] + non_state_keys = set(request_params.keys()).difference(['state']) + for key in non_state_keys: + output_buffer.append(f'{key}: {request_params[key]}') + state = CTerm.from_kast(printer.kore_to_kast(kore_term(request_params['state']))) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + return output_buffer + + def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: + output_buffer = [] + output_buffer.append(f'Depth: {execute_result.depth}') + output_buffer.append(f'Stop reason: {execute_result.reason.value}') + if execute_result.reason == StopReason.TERMINAL_RULE or execute_result.reason == StopReason.CUT_POINT_RULE: + output_buffer.append(f'Stop rule: {execute_result.rule}') + output_buffer.append( + f'Number of next states: {len(execute_result.next_states) if execute_result.next_states is not None else 0}' + ) + state = CTerm.from_kast(printer.kore_to_kast(execute_result.state.kore)) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + if execute_result.next_states is not None: + next_states = [CTerm.from_kast(printer.kore_to_kast(s.kore)) for s in execute_result.next_states] + for i, s in enumerate(next_states): + output_buffer.append(f'Next state #{i}:') + output_buffer.append(printer.pretty_print(s.kast, sort_collections=True)) + return output_buffer + + try: + if 'method' in input_dict: + output_buffer.append('JSON RPC request') + output_buffer.append(f'id: {input_dict["id"]}') + output_buffer.append(f'Method: {input_dict["method"]}') + try: + if 'state' in input_dict['params']: + output_buffer += pretty_print_request(input_dict['params']) + else: # this is an "add-module" request, skip trying to print state + for key in input_dict['params'].keys(): + output_buffer.append(f'{key}: {input_dict["params"][key]}') + except KeyError as e: + _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') + exit(1) + else: + if not 'result' in input_dict: + _LOGGER.critical('The input is neither a request not a resonse') + exit(1) + output_buffer.append('JSON RPC Response') + output_buffer.append(f'id: {input_dict["id"]}') + if list(input_dict['result'].keys()) == ['state']: # this is a "simplify" response + output_buffer.append('Method: simplify') + state = CTerm.from_kast(printer.kore_to_kast(kore_term(input_dict['result']['state']))) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + elif list(input_dict['result'].keys()) == ['module']: # this is an "add-module" response + output_buffer.append('Method: add-module') + output_buffer.append('Module:') + output_buffer.append(input_dict['result']['module']) + else: + try: # assume it is an "execute" response + output_buffer.append('Method: execute') + execute_result = ExecuteResult.from_dict(input_dict['result']) + output_buffer += pretty_print_execute_response(execute_result) + except KeyError as e: + _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') + exit(1) + if self.output_file is not None: + self.output_file.write('\n'.join(output_buffer)) + else: + print('\n'.join(output_buffer)) + except ValueError as e: + # shorten and print the error message in case kore_to_kast throws ValueError + _LOGGER.critical(str(e)[:200]) + exit(1) + + +class PrintCommand(Command, DefinitionOptions, OutputFileOptions, DisplayOptions): + term: IO[Any] + input: PrintInput + minimize: bool + omit_labels: str | None + keep_cells: str | None + + @staticmethod + def name() -> str: + return 'print' + + @staticmethod + def help_str() -> str: + return 'Pretty print a term.' + + @staticmethod + def default() -> dict[str, Any]: + return { + 'input': PrintInput.KAST_JSON, + 'omit_labels': None, + 'keep_cells': None, + } + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument( + 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' + ) + parser.add_argument('--input', type=PrintInput, choices=list(PrintInput)) + parser.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.') + parser.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.') + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + printer = KPrint(kompiled_dir) + if self.input == PrintInput.KORE_JSON: + _LOGGER.info(f'Reading Kore JSON from file: {self.term.name}') + kore = Pattern.from_json(self.term.read()) + term = printer.kore_to_kast(kore) + else: + _LOGGER.info(f'Reading Kast JSON from file: {self.term.name}') + term = KInner.from_json(self.term.read()) + if is_top(term): + self.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + else: + if self.minimize: + if self.omit_labels != None and self.keep_cells != None: + raise ValueError('You cannot use both --omit-labels and --keep-cells.') + + abstract_labels = self.omit_labels.split(',') if self.omit_labels is not None else [] + keep_cells = self.keep_cells.split(',') if self.keep_cells is not None else [] + minimized_disjuncts = [] + + for disjunct in flatten_label('#Or', term): + try: + minimized = minimize_term(disjunct, abstract_labels=abstract_labels, keep_cells=keep_cells) + config, constraint = split_config_and_constraints(minimized) + except ValueError as err: + raise ValueError('The minimized term does not contain a config cell.') from err + + if not is_top(constraint): + minimized_disjuncts.append(mlAnd([config, constraint], sort=GENERATED_TOP_CELL)) + else: + minimized_disjuncts.append(config) + term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) + + self.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + + +class ProveCommand(Command, DefinitionOptions, OutputFileOptions): + main_file: Path + spec_file: Path + spec_module: str + k_args: Iterable[str] + + @staticmethod + def name() -> str: + return 'prove' + + @staticmethod + def help_str() -> str: + return 'Prove an input specification (using kprovex).' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument('main_file', type=str, help='Main file used for kompilation.') + parser.add_argument('spec_file', type=str, help='File with the specification module.') + parser.add_argument('spec_module', type=str, help='Module with claims to be proven.') + parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + kprover = KProve(kompiled_dir, self.main_file) + final_state = kprover.prove(Path(self.spec_file), spec_module_name=self.spec_module, args=self.k_args) + self.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) + _LOGGER.info(f'Wrote file: {self.output_file.name}') diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index ce627d2b7..d82862df7 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -4,7 +4,7 @@ import logging from typing import TYPE_CHECKING, Any -from pyk.cli.args import CLI, Command +from pyk.cli.cli import CLI, Command from ..kdist import kdist, target_ids From fdbfc37112780718afd0039fe82af960a65e6da2 Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 5 Mar 2024 20:40:56 +0000 Subject: [PATCH 47/62] Set Version: 0.1.682 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index b4e60ddcb..989042b7f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.681' -release = '0.1.681' +version = '0.1.682' +release = '0.1.682' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index 5c0a992fe..559df8b89 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.681 +0.1.682 diff --git a/pyproject.toml b/pyproject.toml index 95037cd80..b58bfd96f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.681" +version = "0.1.682" description = "" authors = [ "Runtime Verification, Inc. ", From 28568a7cc099f2da0f6acac97da91f93169321fe Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 15:25:15 -0600 Subject: [PATCH 48/62] Update poetry.lock --- poetry.lock | 582 +++++++++++++++++++++++++++------------------------- 1 file changed, 297 insertions(+), 285 deletions(-) diff --git a/poetry.lock b/poetry.lock index b947020b8..bc016d08a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "alabaster" @@ -13,31 +13,32 @@ files = [ [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] +dev = ["attrs[tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "autoflake" -version = "2.2.1" +version = "2.3.0" description = "Removes unused imports and unused variables" optional = false python-versions = ">=3.8" files = [ - {file = "autoflake-2.2.1-py3-none-any.whl", hash = "sha256:265cde0a43c1f44ecfb4f30d95b0437796759d07be7706a2f70e4719234c0f79"}, - {file = "autoflake-2.2.1.tar.gz", hash = "sha256:62b7b6449a692c3c9b0c916919bbc21648da7281e8506bcf8d3f8280e431ebc1"}, + {file = "autoflake-2.3.0-py3-none-any.whl", hash = "sha256:79a51eb8c0744759d2efe052455ab20aa6a314763510c3fd897499a402126327"}, + {file = "autoflake-2.3.0.tar.gz", hash = "sha256:8c2011fa34701b9d7dcf05b9873bc4859d4fce4e62dfea90dffefd1576f5f01d"}, ] [package.dependencies] @@ -60,29 +61,33 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "black" -version = "23.10.1" +version = "24.2.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"}, - {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"}, - {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"}, - {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"}, - {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"}, - {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"}, - {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"}, - {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"}, - {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"}, - {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"}, - {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"}, - {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"}, - {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"}, - {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"}, - {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"}, - {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"}, - {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"}, - {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"}, + {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, + {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, + {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, + {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, + {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, + {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, + {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, + {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, + {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, + {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, + {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, + {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, + {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, + {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, + {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, + {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, + {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, + {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, + {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, + {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, + {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, + {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, ] [package.dependencies] @@ -96,19 +101,19 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] @@ -287,63 +292,63 @@ cron = ["capturer (>=2.4)"] [[package]] name = "coverage" -version = "7.3.2" +version = "7.4.3" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, - {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, - {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, - {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, - {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, - {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, - {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, - {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, - {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, - {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, - {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, - {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, - {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, - {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, + {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, + {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, + {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, + {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, + {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, + {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, + {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, + {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, + {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, + {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, + {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, + {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, ] [package.dependencies] @@ -365,13 +370,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.1.3" +version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] @@ -393,13 +398,13 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "filelock" -version = "3.13.0" +version = "3.13.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.0-py3-none-any.whl", hash = "sha256:a552f4fde758f4eab33191e9548f671970f8b06d436d31388c9aa1e5861a710f"}, - {file = "filelock-3.13.0.tar.gz", hash = "sha256:63c6052c82a1a24c873a549fbd39a26982e8f35a3016da231ead11a5be9dad44"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] @@ -409,29 +414,29 @@ typing = ["typing-extensions (>=4.8)"] [[package]] name = "flake8" -version = "6.1.0" +version = "7.0.0" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, + {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, + {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, ] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" +pyflakes = ">=3.2.0,<3.3.0" [[package]] name = "flake8-bugbear" -version = "23.9.16" +version = "24.2.6" description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-bugbear-23.9.16.tar.gz", hash = "sha256:90cf04b19ca02a682feb5aac67cae8de742af70538590509941ab10ae8351f71"}, - {file = "flake8_bugbear-23.9.16-py3-none-any.whl", hash = "sha256:b182cf96ea8f7a8595b2f87321d7d9b28728f4d9c3318012d896543d19742cb5"}, + {file = "flake8-bugbear-24.2.6.tar.gz", hash = "sha256:f9cb5f2a9e792dd80ff68e89a14c12eed8620af8b41a49d823b7a33064ac9658"}, + {file = "flake8_bugbear-24.2.6-py3-none-any.whl", hash = "sha256:663ef5de80cd32aacd39d362212983bc4636435a6f83700b4ed35acbd0b7d1b8"}, ] [package.dependencies] @@ -457,26 +462,27 @@ flake8 = ">=3.0,<3.2.0 || >3.2.0" [[package]] name = "flake8-quotes" -version = "3.3.2" +version = "3.4.0" description = "Flake8 lint for quotes." optional = false python-versions = "*" files = [ - {file = "flake8-quotes-3.3.2.tar.gz", hash = "sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1"}, + {file = "flake8-quotes-3.4.0.tar.gz", hash = "sha256:aad8492fb710a2d3eabe68c5f86a1428de650c8484127e14c43d0504ba30276c"}, ] [package.dependencies] flake8 = "*" +setuptools = "*" [[package]] name = "flake8-type-checking" -version = "2.5.1" +version = "2.9.0" description = "A flake8 plugin for managing type-checking imports & forward references" optional = false python-versions = ">=3.8" files = [ - {file = "flake8_type_checking-2.5.1-py3-none-any.whl", hash = "sha256:1cd5cd9731f34921b33640751455643ca1cf7ee4a347a45cd94d3af328a3dd64"}, - {file = "flake8_type_checking-2.5.1.tar.gz", hash = "sha256:bfc51dd6e09a26662ab19191f44102f0606377ec0271a0e764ae993346a206d6"}, + {file = "flake8_type_checking-2.9.0-py3-none-any.whl", hash = "sha256:b63e1745f6e7deee1403d7e0150a5bca378315e9fe4d4cdaa7b71338034dbcc3"}, + {file = "flake8_type_checking-2.9.0.tar.gz", hash = "sha256:6fcc0e8a63f6a87b5b26b776388c21907e66c4efbd15dcc1bcbd96fe884da93d"}, ] [package.dependencies] @@ -537,20 +543,20 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.8.0" +version = "7.0.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, + {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, + {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] @@ -567,20 +573,17 @@ files = [ [[package]] name = "isort" -version = "5.12.0" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] name = "jinja2" @@ -601,13 +604,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "linkify-it-py" -version = "2.0.2" +version = "2.0.3" description = "Links recognition library with FULL unicode support." optional = false python-versions = ">=3.7" files = [ - {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, - {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, + {file = "linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048"}, + {file = "linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79"}, ] [package.dependencies] @@ -647,71 +650,71 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] @@ -757,38 +760,38 @@ files = [ [[package]] name = "mypy" -version = "1.6.1" +version = "1.8.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"}, - {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"}, - {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"}, - {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"}, - {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"}, - {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"}, - {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"}, - {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"}, - {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"}, - {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"}, - {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"}, - {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"}, - {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"}, - {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"}, - {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"}, - {file = "mypy-1.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:41697773aa0bf53ff917aa077e2cde7aa50254f28750f9b88884acea38a16169"}, - {file = "mypy-1.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7274b0c57737bd3476d2229c6389b2ec9eefeb090bbaf77777e9d6b1b5a9d143"}, - {file = "mypy-1.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbaf4662e498c8c2e352da5f5bca5ab29d378895fa2d980630656178bd607c46"}, - {file = "mypy-1.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bb8ccb4724f7d8601938571bf3f24da0da791fe2db7be3d9e79849cb64e0ae85"}, - {file = "mypy-1.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:68351911e85145f582b5aa6cd9ad666c8958bcae897a1bfda8f4940472463c45"}, - {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"}, - {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"}, - {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"}, - {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"}, - {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"}, - {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"}, - {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, + {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, + {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, + {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, + {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, + {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, + {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, + {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, + {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, + {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, + {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, + {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, + {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, + {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, + {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, + {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, + {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, + {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, ] [package.dependencies] @@ -799,6 +802,7 @@ typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] +mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] @@ -825,13 +829,13 @@ files = [ [[package]] name = "pathspec" -version = "0.11.2" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] @@ -850,28 +854,28 @@ flake8 = ">=5.0.0" [[package]] name = "platformdirs" -version = "3.11.0" +version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, - {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" -version = "1.3.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] @@ -931,28 +935,29 @@ files = [ [[package]] name = "pyflakes" -version = "3.1.0" +version = "3.2.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.8" files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, + {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, + {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, ] [[package]] name = "pygments" -version = "2.16.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyperclip" @@ -977,13 +982,13 @@ files = [ [[package]] name = "pytest" -version = "7.4.3" +version = "8.0.2" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, + {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, + {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, ] [package.dependencies] @@ -991,7 +996,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" +pluggy = ">=1.3.0,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] @@ -1048,13 +1053,13 @@ pytest = ">=5.0.0" [[package]] name = "pytest-xdist" -version = "3.3.1" +version = "3.5.0" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-xdist-3.3.1.tar.gz", hash = "sha256:d5ee0520eb1b7bcca50a60a518ab7a7707992812c578198f8b44fdfac78e8c93"}, - {file = "pytest_xdist-3.3.1-py3-none-any.whl", hash = "sha256:ff9daa7793569e6a68544850fd3927cd257cc03a7ef76c95e86915355e82b5f2"}, + {file = "pytest-xdist-3.5.0.tar.gz", hash = "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a"}, + {file = "pytest_xdist-3.5.0-py3-none-any.whl", hash = "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24"}, ] [package.dependencies] @@ -1068,13 +1073,13 @@ testing = ["filelock"] [[package]] name = "pyupgrade" -version = "3.15.0" +version = "3.15.1" description = "A tool to automatically upgrade syntax for newer versions." optional = false python-versions = ">=3.8.1" files = [ - {file = "pyupgrade-3.15.0-py2.py3-none-any.whl", hash = "sha256:8dc8ebfaed43566e2c65994162795017c7db11f531558a74bc8aa077907bc305"}, - {file = "pyupgrade-3.15.0.tar.gz", hash = "sha256:a7fde381060d7c224f55aef7a30fae5ac93bbc428367d27e70a603bc2acd4f00"}, + {file = "pyupgrade-3.15.1-py2.py3-none-any.whl", hash = "sha256:c5e005de2805edcd333d1deb04553200ec69da85e4bc9db37b16345ed9e27ed9"}, + {file = "pyupgrade-3.15.1.tar.gz", hash = "sha256:7690857cae0f6253f39241dcd2e57118c333c438b78609fc3c17a5aa61227b7d"}, ] [package.dependencies] @@ -1103,13 +1108,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.6.0" +version = "13.7.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, - {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, ] [package.dependencies] @@ -1119,6 +1124,22 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "setuptools" +version = "69.1.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, + {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "snowballstemmer" version = "2.2.0" @@ -1166,56 +1187,50 @@ test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.7" +version = "1.0.8" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, - {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, + {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, + {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.5" +version = "1.0.6" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, - {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, + {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, + {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.4" +version = "2.0.5" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, - {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, + {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, + {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] @@ -1234,38 +1249,34 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.6" +version = "1.0.7" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, - {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, + {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, + {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.9" +version = "1.1.10" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, - {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, + {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, + {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, ] -[package.dependencies] -Sphinx = ">=5" - [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] @@ -1312,35 +1323,35 @@ files = [ [[package]] name = "types-psutil" -version = "5.9.5.17" +version = "5.9.5.20240205" description = "Typing stubs for psutil" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "types-psutil-5.9.5.17.tar.gz", hash = "sha256:f7d8769812d72a4b513d7ec9eb5580fe2f6013fc270394a603cb6534811f3e4d"}, - {file = "types_psutil-5.9.5.17-py3-none-any.whl", hash = "sha256:2161d166256084acf629d30aaf6bda8bee726ae1fea530559650281056b491fc"}, + {file = "types-psutil-5.9.5.20240205.tar.gz", hash = "sha256:51df36a361aa597bf483dcc5b58f2ab7aa87452a36d2da97c90994d6a81ef743"}, + {file = "types_psutil-5.9.5.20240205-py3-none-any.whl", hash = "sha256:3ec9bd8b95a64fe1269241d3ffb74b94a45df2d0391da1402423cd33f29745ca"}, ] [[package]] name = "typing-extensions" -version = "4.8.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] name = "uc-micro-py" -version = "1.0.2" +version = "1.0.3" description = "Micro subset of unicode data files for linkify-it-py projects." optional = false python-versions = ">=3.7" files = [ - {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, - {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, + {file = "uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a"}, + {file = "uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5"}, ] [package.extras] @@ -1348,29 +1359,30 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.1.0" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, - {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcwidth" -version = "0.2.8" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"}, - {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"}, + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] [[package]] From 2e6885fdaf813b3fe130f4651346e8f77983e86a Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 15:26:48 -0600 Subject: [PATCH 49/62] Update poetry.lock --- poetry.lock | 582 +++++++++++++++++++++++++--------------------------- 1 file changed, 285 insertions(+), 297 deletions(-) diff --git a/poetry.lock b/poetry.lock index bc016d08a..b947020b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "alabaster" @@ -13,32 +13,31 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "23.1.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] +dev = ["attrs[docs,tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] [[package]] name = "autoflake" -version = "2.3.0" +version = "2.2.1" description = "Removes unused imports and unused variables" optional = false python-versions = ">=3.8" files = [ - {file = "autoflake-2.3.0-py3-none-any.whl", hash = "sha256:79a51eb8c0744759d2efe052455ab20aa6a314763510c3fd897499a402126327"}, - {file = "autoflake-2.3.0.tar.gz", hash = "sha256:8c2011fa34701b9d7dcf05b9873bc4859d4fce4e62dfea90dffefd1576f5f01d"}, + {file = "autoflake-2.2.1-py3-none-any.whl", hash = "sha256:265cde0a43c1f44ecfb4f30d95b0437796759d07be7706a2f70e4719234c0f79"}, + {file = "autoflake-2.2.1.tar.gz", hash = "sha256:62b7b6449a692c3c9b0c916919bbc21648da7281e8506bcf8d3f8280e431ebc1"}, ] [package.dependencies] @@ -61,33 +60,29 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "black" -version = "24.2.0" +version = "23.10.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, - {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, - {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, - {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, - {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, - {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, - {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, - {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, - {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, - {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, - {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, - {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, - {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, - {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, - {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, - {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, - {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, - {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, - {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, - {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, - {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, - {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, + {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"}, + {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"}, + {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"}, + {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"}, + {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"}, + {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"}, + {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"}, + {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"}, + {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"}, + {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"}, + {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"}, + {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"}, + {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"}, + {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"}, + {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"}, + {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"}, + {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"}, + {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"}, ] [package.dependencies] @@ -101,19 +96,19 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] [[package]] @@ -292,63 +287,63 @@ cron = ["capturer (>=2.4)"] [[package]] name = "coverage" -version = "7.4.3" +version = "7.3.2" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, - {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, - {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, - {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, - {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, - {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, - {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, - {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, - {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, - {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, - {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, - {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, - {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, - {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, + {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, + {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, + {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, + {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, + {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, + {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, + {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, + {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, + {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, + {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, + {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, + {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, + {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, + {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, ] [package.dependencies] @@ -370,13 +365,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.1.3" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, ] [package.extras] @@ -398,13 +393,13 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "filelock" -version = "3.13.1" +version = "3.13.0" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, + {file = "filelock-3.13.0-py3-none-any.whl", hash = "sha256:a552f4fde758f4eab33191e9548f671970f8b06d436d31388c9aa1e5861a710f"}, + {file = "filelock-3.13.0.tar.gz", hash = "sha256:63c6052c82a1a24c873a549fbd39a26982e8f35a3016da231ead11a5be9dad44"}, ] [package.extras] @@ -414,29 +409,29 @@ typing = ["typing-extensions (>=4.8)"] [[package]] name = "flake8" -version = "7.0.0" +version = "6.1.0" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, - {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, + {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, + {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, ] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.2.0,<3.3.0" +pyflakes = ">=3.1.0,<3.2.0" [[package]] name = "flake8-bugbear" -version = "24.2.6" +version = "23.9.16" description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-bugbear-24.2.6.tar.gz", hash = "sha256:f9cb5f2a9e792dd80ff68e89a14c12eed8620af8b41a49d823b7a33064ac9658"}, - {file = "flake8_bugbear-24.2.6-py3-none-any.whl", hash = "sha256:663ef5de80cd32aacd39d362212983bc4636435a6f83700b4ed35acbd0b7d1b8"}, + {file = "flake8-bugbear-23.9.16.tar.gz", hash = "sha256:90cf04b19ca02a682feb5aac67cae8de742af70538590509941ab10ae8351f71"}, + {file = "flake8_bugbear-23.9.16-py3-none-any.whl", hash = "sha256:b182cf96ea8f7a8595b2f87321d7d9b28728f4d9c3318012d896543d19742cb5"}, ] [package.dependencies] @@ -462,27 +457,26 @@ flake8 = ">=3.0,<3.2.0 || >3.2.0" [[package]] name = "flake8-quotes" -version = "3.4.0" +version = "3.3.2" description = "Flake8 lint for quotes." optional = false python-versions = "*" files = [ - {file = "flake8-quotes-3.4.0.tar.gz", hash = "sha256:aad8492fb710a2d3eabe68c5f86a1428de650c8484127e14c43d0504ba30276c"}, + {file = "flake8-quotes-3.3.2.tar.gz", hash = "sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1"}, ] [package.dependencies] flake8 = "*" -setuptools = "*" [[package]] name = "flake8-type-checking" -version = "2.9.0" +version = "2.5.1" description = "A flake8 plugin for managing type-checking imports & forward references" optional = false python-versions = ">=3.8" files = [ - {file = "flake8_type_checking-2.9.0-py3-none-any.whl", hash = "sha256:b63e1745f6e7deee1403d7e0150a5bca378315e9fe4d4cdaa7b71338034dbcc3"}, - {file = "flake8_type_checking-2.9.0.tar.gz", hash = "sha256:6fcc0e8a63f6a87b5b26b776388c21907e66c4efbd15dcc1bcbd96fe884da93d"}, + {file = "flake8_type_checking-2.5.1-py3-none-any.whl", hash = "sha256:1cd5cd9731f34921b33640751455643ca1cf7ee4a347a45cd94d3af328a3dd64"}, + {file = "flake8_type_checking-2.5.1.tar.gz", hash = "sha256:bfc51dd6e09a26662ab19191f44102f0606377ec0271a0e764ae993346a206d6"}, ] [package.dependencies] @@ -543,20 +537,20 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.0.1" +version = "6.8.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] @@ -573,17 +567,20 @@ files = [ [[package]] name = "isort" -version = "5.13.2" +version = "5.12.0" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, ] [package.extras] -colors = ["colorama (>=0.4.6)"] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jinja2" @@ -604,13 +601,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "linkify-it-py" -version = "2.0.3" +version = "2.0.2" description = "Links recognition library with FULL unicode support." optional = false python-versions = ">=3.7" files = [ - {file = "linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048"}, - {file = "linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79"}, + {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, + {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, ] [package.dependencies] @@ -650,71 +647,71 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] [[package]] @@ -760,38 +757,38 @@ files = [ [[package]] name = "mypy" -version = "1.8.0" +version = "1.6.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, - {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, - {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, - {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, - {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, - {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, - {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, - {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, - {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, - {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, - {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, - {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, - {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, - {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, - {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, - {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, - {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, - {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, - {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, + {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"}, + {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"}, + {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"}, + {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"}, + {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"}, + {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"}, + {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"}, + {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"}, + {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"}, + {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"}, + {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"}, + {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"}, + {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"}, + {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"}, + {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"}, + {file = "mypy-1.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:41697773aa0bf53ff917aa077e2cde7aa50254f28750f9b88884acea38a16169"}, + {file = "mypy-1.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7274b0c57737bd3476d2229c6389b2ec9eefeb090bbaf77777e9d6b1b5a9d143"}, + {file = "mypy-1.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbaf4662e498c8c2e352da5f5bca5ab29d378895fa2d980630656178bd607c46"}, + {file = "mypy-1.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bb8ccb4724f7d8601938571bf3f24da0da791fe2db7be3d9e79849cb64e0ae85"}, + {file = "mypy-1.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:68351911e85145f582b5aa6cd9ad666c8958bcae897a1bfda8f4940472463c45"}, + {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"}, + {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"}, + {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"}, + {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"}, + {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"}, + {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"}, + {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"}, ] [package.dependencies] @@ -802,7 +799,6 @@ typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] -mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] @@ -829,13 +825,13 @@ files = [ [[package]] name = "pathspec" -version = "0.12.1" +version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, ] [[package]] @@ -854,28 +850,28 @@ flake8 = ">=5.0.0" [[package]] name = "platformdirs" -version = "4.2.0" +version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, + {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "pluggy" -version = "1.4.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] @@ -935,29 +931,28 @@ files = [ [[package]] name = "pyflakes" -version = "3.2.0" +version = "3.1.0" description = "passive checker of Python programs" optional = false python-versions = ">=3.8" files = [ - {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, - {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, + {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, + {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, ] [[package]] name = "pygments" -version = "2.17.2" +version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, ] [package.extras] plugins = ["importlib-metadata"] -windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyperclip" @@ -982,13 +977,13 @@ files = [ [[package]] name = "pytest" -version = "8.0.2" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, - {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] @@ -996,7 +991,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.3.0,<2.0" +pluggy = ">=0.12,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] @@ -1053,13 +1048,13 @@ pytest = ">=5.0.0" [[package]] name = "pytest-xdist" -version = "3.5.0" +version = "3.3.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-xdist-3.5.0.tar.gz", hash = "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a"}, - {file = "pytest_xdist-3.5.0-py3-none-any.whl", hash = "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24"}, + {file = "pytest-xdist-3.3.1.tar.gz", hash = "sha256:d5ee0520eb1b7bcca50a60a518ab7a7707992812c578198f8b44fdfac78e8c93"}, + {file = "pytest_xdist-3.3.1-py3-none-any.whl", hash = "sha256:ff9daa7793569e6a68544850fd3927cd257cc03a7ef76c95e86915355e82b5f2"}, ] [package.dependencies] @@ -1073,13 +1068,13 @@ testing = ["filelock"] [[package]] name = "pyupgrade" -version = "3.15.1" +version = "3.15.0" description = "A tool to automatically upgrade syntax for newer versions." optional = false python-versions = ">=3.8.1" files = [ - {file = "pyupgrade-3.15.1-py2.py3-none-any.whl", hash = "sha256:c5e005de2805edcd333d1deb04553200ec69da85e4bc9db37b16345ed9e27ed9"}, - {file = "pyupgrade-3.15.1.tar.gz", hash = "sha256:7690857cae0f6253f39241dcd2e57118c333c438b78609fc3c17a5aa61227b7d"}, + {file = "pyupgrade-3.15.0-py2.py3-none-any.whl", hash = "sha256:8dc8ebfaed43566e2c65994162795017c7db11f531558a74bc8aa077907bc305"}, + {file = "pyupgrade-3.15.0.tar.gz", hash = "sha256:a7fde381060d7c224f55aef7a30fae5ac93bbc428367d27e70a603bc2acd4f00"}, ] [package.dependencies] @@ -1108,13 +1103,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.7.1" +version = "13.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, + {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, + {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, ] [package.dependencies] @@ -1124,22 +1119,6 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] -[[package]] -name = "setuptools" -version = "69.1.1" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, - {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "snowballstemmer" version = "2.2.0" @@ -1187,50 +1166,56 @@ test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.8" +version = "1.0.7" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, - {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, + {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, + {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.6" +version = "1.0.5" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, - {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, + {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, + {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.5" +version = "2.0.4" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, - {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, + {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, + {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] @@ -1249,34 +1234,38 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.7" +version = "1.0.6" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, - {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, + {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, + {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.10" +version = "1.1.9" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, - {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, + {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, + {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, ] +[package.dependencies] +Sphinx = ">=5" + [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] -standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] @@ -1323,35 +1312,35 @@ files = [ [[package]] name = "types-psutil" -version = "5.9.5.20240205" +version = "5.9.5.17" description = "Typing stubs for psutil" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "types-psutil-5.9.5.20240205.tar.gz", hash = "sha256:51df36a361aa597bf483dcc5b58f2ab7aa87452a36d2da97c90994d6a81ef743"}, - {file = "types_psutil-5.9.5.20240205-py3-none-any.whl", hash = "sha256:3ec9bd8b95a64fe1269241d3ffb74b94a45df2d0391da1402423cd33f29745ca"}, + {file = "types-psutil-5.9.5.17.tar.gz", hash = "sha256:f7d8769812d72a4b513d7ec9eb5580fe2f6013fc270394a603cb6534811f3e4d"}, + {file = "types_psutil-5.9.5.17-py3-none-any.whl", hash = "sha256:2161d166256084acf629d30aaf6bda8bee726ae1fea530559650281056b491fc"}, ] [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.8.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [[package]] name = "uc-micro-py" -version = "1.0.3" +version = "1.0.2" description = "Micro subset of unicode data files for linkify-it-py projects." optional = false python-versions = ">=3.7" files = [ - {file = "uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a"}, - {file = "uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5"}, + {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, + {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, ] [package.extras] @@ -1359,30 +1348,29 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.2.1" +version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, + {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcwidth" -version = "0.2.13" +version = "0.2.8" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, + {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"}, + {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"}, ] [[package]] From 9ed92a8c9f09e616d0e23c24cfe5bdfefee3eded Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Tue, 5 Mar 2024 15:44:12 -0600 Subject: [PATCH 50/62] Add logging options back to top level of kdist --- src/pyk/cli/cli.py | 6 ++++-- src/pyk/kdist/__main__.py | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index aed124746..163d44d4a 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -38,6 +38,8 @@ from argparse import _SubParsersAction from collections.abc import Iterable + from pyk.cli.args import Options + class PrintInput(Enum): KORE_JSON = 'kore-json' @@ -65,8 +67,8 @@ def add_parsers(self, base: _SubParsersAction) -> _SubParsersAction: base = cmd_type.parser(base) return base - def create_argument_parser(self) -> ArgumentParser: - pyk_args = ArgumentParser() + def create_argument_parser(self, top_level_args: Iterable[type[Options]] = ()) -> ArgumentParser: + pyk_args = ArgumentParser(parents=[tla.all_args() for tla in top_level_args]) pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) pyk_args_command = self.add_parsers(pyk_args_command) diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index d82862df7..95ff343ce 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -4,7 +4,7 @@ import logging from typing import TYPE_CHECKING, Any -from pyk.cli.cli import CLI, Command +from pyk.cli.cli import CLI, Command, LoggingOptions from ..kdist import kdist, target_ids @@ -19,7 +19,7 @@ def main() -> None: kdist_cli = CLI({KDistBuildCommand, KDistCleanCommand, KDistWhichCommand, KDistListCommand}) - parser = kdist_cli.create_argument_parser() + parser = kdist_cli.create_argument_parser(top_level_args=[LoggingOptions]) parser.parse_args() args = parser.parse_args() command = kdist_cli.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) From 6546289c2c74d3c874e38d7dd53b3ebedd3dce5d Mon Sep 17 00:00:00 2001 From: devops Date: Tue, 5 Mar 2024 22:40:20 +0000 Subject: [PATCH 51/62] Set Version: 0.1.683 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 989042b7f..3ee1c6df6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.682' -release = '0.1.682' +version = '0.1.683' +release = '0.1.683' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index 559df8b89..36fc716eb 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.682 +0.1.683 diff --git a/pyproject.toml b/pyproject.toml index b58bfd96f..2e484992e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.682" +version = "0.1.683" description = "" authors = [ "Runtime Verification, Inc. ", From 09b4179ffa47381b4a1ce77bbd6e143c83ebbc60 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 6 Mar 2024 12:43:45 -0600 Subject: [PATCH 52/62] Command is now no longer automatically also an Options, CLI can handle creating argument parser, removing None values from dict, and initializing and executing Command all in one go, logging for pyk commands fixed --- src/pyk/__main__.py | 11 ++++------ src/pyk/cli/args.py | 2 +- src/pyk/cli/cli.py | 46 +++++++++++++++++++++++++-------------- src/pyk/kdist/__main__.py | 21 +++++++++--------- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index c88a18bc1..9e112749f 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -4,6 +4,7 @@ import sys from typing import TYPE_CHECKING +from .cli.args import LoggingOptions from .cli.cli import ( CLI, CoverageCommand, @@ -42,14 +43,10 @@ def main() -> None: RPCPrintCommand, ] ) - - cli_parser = cli.create_argument_parser() - args = cli_parser.parse_args() - - command = cli.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) - command.exec() - + command = cli.get_command() + assert isinstance(command, LoggingOptions) logging.basicConfig(level=loglevel(command), format=LOG_FORMAT) + command.exec() if __name__ == '__main__': diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 4f577c707..7089bb455 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -74,7 +74,7 @@ def update_args(parser: ArgumentParser) -> None: parser.add_argument('--output-file', type=FileType('w')) -class DefinitionOptions(LoggingOptions): +class DefinitionOptions(Options): definition_dir: Path @staticmethod diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index 163d44d4a..e7b180526 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -10,6 +10,7 @@ from graphviz import Digraph +from pyk.cli.args import Options from pyk.coverage import get_rule_by_id, strip_coverage_logger from pyk.cterm import CTerm from pyk.kast.inner import KInner @@ -38,8 +39,6 @@ from argparse import _SubParsersAction from collections.abc import Iterable - from pyk.cli.args import Options - class PrintInput(Enum): KORE_JSON = 'kore-json' @@ -48,17 +47,22 @@ class PrintInput(Enum): class CLI: commands: list[type[Command]] + top_level_args: Iterable[type[Options]] # Input a list of all Command types to be used - def __init__(self, commands: Iterable[type[Command]]): + def __init__(self, commands: Iterable[type[Command]], top_level_args: Iterable[type[Options]] = ()): self.commands = list(commands) + self.top_level_args = top_level_args # Return an instance of the correct Options subclass by matching its name with the requested command def generate_command(self, args: dict[str, Any]) -> Command: command = args['command'].lower() for cmd_type in self.commands: if cmd_type.name() == command: - return cmd_type(args) + if issubclass(cmd_type, Options): + return cmd_type(args) + else: + return cmd_type() raise ValueError(f'Unrecognized command: {command}') # Generate the parsers for all commands @@ -67,16 +71,25 @@ def add_parsers(self, base: _SubParsersAction) -> _SubParsersAction: base = cmd_type.parser(base) return base - def create_argument_parser(self, top_level_args: Iterable[type[Options]] = ()) -> ArgumentParser: - pyk_args = ArgumentParser(parents=[tla.all_args() for tla in top_level_args]) + def create_argument_parser(self) -> ArgumentParser: + pyk_args = ArgumentParser(parents=[tla.all_args() for tla in self.top_level_args]) pyk_args_command = pyk_args.add_subparsers(dest='command', required=True) pyk_args_command = self.add_parsers(pyk_args_command) return pyk_args + def get_command(self) -> Command: + parser = self.create_argument_parser() + args = parser.parse_args() + return self.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) + + def get_and_exec_command(self) -> None: + cmd = self.get_command() + cmd.exec() + -class Command(LoggingOptions): +class Command: @staticmethod @abstractmethod def name() -> str: @@ -93,15 +106,16 @@ def exec(self) -> None: @classmethod def parser(cls, base: _SubParsersAction) -> _SubParsersAction: + all_args = [cls.all_args()] if issubclass(cls, Options) else [] base.add_parser( name=cls.name(), help=cls.help_str(), - parents=[cls.all_args()], + parents=all_args, ) return base -class JsonToKoreCommand(Command): +class JsonToKoreCommand(Command, LoggingOptions): @staticmethod def name() -> str: return 'json-to-kore' @@ -117,7 +131,7 @@ def exec(self) -> None: sys.stdout.write('\n') -class KoreToJsonCommand(Command): +class KoreToJsonCommand(Command, LoggingOptions): @staticmethod def name() -> str: return 'kore-to-json' @@ -132,7 +146,7 @@ def exec(self) -> None: print(kore.json) -class CoverageCommand(Command, DefinitionOptions, OutputFileOptions): +class CoverageCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): coverage_file: IO[Any] @staticmethod @@ -160,7 +174,7 @@ def exec(self) -> None: _LOGGER.info(f'Wrote file: {self.output_file.name}') -class GraphImportsCommand(Command, DefinitionOptions): +class GraphImportsCommand(Command, DefinitionOptions, LoggingOptions): @staticmethod def name() -> str: return 'graph-imports' @@ -184,7 +198,7 @@ def exec(self) -> None: _LOGGER.info(f'Wrote file: {graph_file}') -class RPCKastCommand(Command, OutputFileOptions): +class RPCKastCommand(Command, OutputFileOptions, LoggingOptions): reference_request_file: IO[Any] response_file: IO[Any] @@ -231,7 +245,7 @@ def exec(self) -> None: self.output_file.write(json.dumps(request)) -class RPCPrintCommand(Command, DefinitionOptions, OutputFileOptions): +class RPCPrintCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): input_file: IO[Any] @staticmethod @@ -332,7 +346,7 @@ def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: exit(1) -class PrintCommand(Command, DefinitionOptions, OutputFileOptions, DisplayOptions): +class PrintCommand(Command, DefinitionOptions, OutputFileOptions, DisplayOptions, LoggingOptions): term: IO[Any] input: PrintInput minimize: bool @@ -403,7 +417,7 @@ def exec(self) -> None: _LOGGER.info(f'Wrote file: {self.output_file.name}') -class ProveCommand(Command, DefinitionOptions, OutputFileOptions): +class ProveCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): main_file: Path spec_file: Path spec_module: str diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index 95ff343ce..7a7c02f9c 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -4,7 +4,8 @@ import logging from typing import TYPE_CHECKING, Any -from pyk.cli.cli import CLI, Command, LoggingOptions +from pyk.cli.args import LoggingOptions, Options +from pyk.cli.cli import CLI, Command from ..kdist import kdist, target_ids @@ -18,12 +19,10 @@ def main() -> None: - kdist_cli = CLI({KDistBuildCommand, KDistCleanCommand, KDistWhichCommand, KDistListCommand}) - parser = kdist_cli.create_argument_parser(top_level_args=[LoggingOptions]) - parser.parse_args() - args = parser.parse_args() - command = kdist_cli.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) - command.exec() + kdist_cli = CLI( + {KDistBuildCommand, KDistCleanCommand, KDistWhichCommand, KDistListCommand}, top_level_args=[LoggingOptions] + ) + kdist_cli.get_and_exec_command() def _process_targets(targets: list[str]) -> list[str]: @@ -48,7 +47,7 @@ def _process_args(args: list[str]) -> dict[str, str]: return res -class KDistBuildCommand(Command): +class KDistBuildCommand(Command, LoggingOptions): targets: list[str] force: bool jobs: int @@ -95,7 +94,7 @@ def exec(self) -> None: ) -class KDistCleanCommand(Command): +class KDistCleanCommand(Command, Options): target: str @staticmethod @@ -120,7 +119,7 @@ def exec(self) -> None: print(res) -class KDistWhichCommand(Command): +class KDistWhichCommand(Command, Options): target: str @staticmethod @@ -145,7 +144,7 @@ def exec(self) -> None: print(res) -class KDistListCommand(Command): +class KDistListCommand(Command, Options): @staticmethod def name() -> str: return 'list' From 84b8679f02365612ee0f4079c0efe02234107c48 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 6 Mar 2024 12:53:02 -0600 Subject: [PATCH 53/62] Move pyk-specific Commands into separate module --- src/pyk/__main__.py | 4 +- src/pyk/cli/cli.py | 369 +------------------------------------------ src/pyk/cli/pyk.py | 375 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 379 insertions(+), 369 deletions(-) create mode 100644 src/pyk/cli/pyk.py diff --git a/src/pyk/__main__.py b/src/pyk/__main__.py index 9e112749f..3ee7c734a 100644 --- a/src/pyk/__main__.py +++ b/src/pyk/__main__.py @@ -5,8 +5,8 @@ from typing import TYPE_CHECKING from .cli.args import LoggingOptions -from .cli.cli import ( - CLI, +from .cli.cli import CLI +from .cli.pyk import ( CoverageCommand, GraphImportsCommand, JsonToKoreCommand, diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index e7b180526..e084c9558 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -1,50 +1,16 @@ from __future__ import annotations -import json -import sys from abc import abstractmethod -from argparse import ArgumentParser, FileType -from enum import Enum -from pathlib import Path -from typing import IO, TYPE_CHECKING, Any - -from graphviz import Digraph +from argparse import ArgumentParser +from typing import TYPE_CHECKING, Any from pyk.cli.args import Options -from pyk.coverage import get_rule_by_id, strip_coverage_logger -from pyk.cterm import CTerm -from pyk.kast.inner import KInner -from pyk.kast.manip import ( - flatten_label, - minimize_rule, - minimize_term, - propagate_up_constraints, - remove_source_map, - split_config_and_constraints, -) -from pyk.kast.outer import read_kast_definition -from pyk.kast.pretty import PrettyPrinter -from pyk.kore.parser import KoreParser -from pyk.kore.rpc import ExecuteResult, StopReason -from pyk.kore.syntax import Pattern, kore_term -from pyk.ktool.kprint import KPrint -from pyk.ktool.kprove import KProve -from pyk.prelude.k import GENERATED_TOP_CELL -from pyk.prelude.ml import is_top, mlAnd, mlOr -from pyk.utils import _LOGGER - -from .args import DefinitionOptions, DisplayOptions, LoggingOptions, OutputFileOptions if TYPE_CHECKING: from argparse import _SubParsersAction from collections.abc import Iterable -class PrintInput(Enum): - KORE_JSON = 'kore-json' - KAST_JSON = 'kast-json' - - class CLI: commands: list[type[Command]] top_level_args: Iterable[type[Options]] @@ -113,334 +79,3 @@ def parser(cls, base: _SubParsersAction) -> _SubParsersAction: parents=all_args, ) return base - - -class JsonToKoreCommand(Command, LoggingOptions): - @staticmethod - def name() -> str: - return 'json-to-kore' - - @staticmethod - def help_str() -> str: - return 'Convert JSON to textual KORE' - - def exec(self) -> None: - text = sys.stdin.read() - kore = Pattern.from_json(text) - kore.write(sys.stdout) - sys.stdout.write('\n') - - -class KoreToJsonCommand(Command, LoggingOptions): - @staticmethod - def name() -> str: - return 'kore-to-json' - - @staticmethod - def help_str() -> str: - return 'Convert textual KORE to JSON' - - def exec(self) -> None: - text = sys.stdin.read() - kore = KoreParser(text).pattern() - print(kore.json) - - -class CoverageCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): - coverage_file: IO[Any] - - @staticmethod - def name() -> str: - return 'coverage' - - @staticmethod - def help_str() -> str: - return 'Convert coverage file to human readable log.' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) - pretty_printer = PrettyPrinter(definition) - for rid in self.coverage_file: - rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) - self.output_file.write('\n\n') - self.output_file.write('Rule: ' + rid.strip()) - self.output_file.write('\nUnparsed:\n') - self.output_file.write(pretty_printer.print(rule)) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - - -class GraphImportsCommand(Command, DefinitionOptions, LoggingOptions): - @staticmethod - def name() -> str: - return 'graph-imports' - - @staticmethod - def help_str() -> str: - return 'Graph the imports of a given definition.' - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - kprinter = KPrint(kompiled_dir) - definition = kprinter.definition - import_graph = Digraph() - graph_file = kompiled_dir / 'import-graph' - for module in definition.modules: - module_name = module.name - import_graph.node(module_name) - for module_import in module.imports: - import_graph.edge(module_name, module_import.name) - import_graph.render(graph_file) - _LOGGER.info(f'Wrote file: {graph_file}') - - -class RPCKastCommand(Command, OutputFileOptions, LoggingOptions): - reference_request_file: IO[Any] - response_file: IO[Any] - - @staticmethod - def name() -> str: - return 'rpc-kast' - - @staticmethod - def help_str() -> str: - return 'Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument( - 'reference_request_file', - type=FileType('r'), - help='An input file containing a JSON RPC request to server as a reference for the new request.', - ) - parser.add_argument( - 'response_file', - type=FileType('r'), - help='An input file containing a JSON RPC response with KoreJSON payload.', - ) - - def exec(self) -> None: - """ - Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, - copying parameters from a reference request. - """ - reference_request = json.loads(self.reference_request_file.read()) - input_dict = json.loads(self.response_file.read()) - execute_result = ExecuteResult.from_dict(input_dict['result']) - non_state_keys = set(reference_request['params'].keys()).difference(['state']) - request_params = {} - for key in non_state_keys: - request_params[key] = reference_request['params'][key] - request_params['state'] = {'format': 'KORE', 'version': 1, 'term': execute_result.state.kore.dict} - request = { - 'jsonrpc': reference_request['jsonrpc'], - 'id': reference_request['id'], - 'method': reference_request['method'], - 'params': request_params, - } - self.output_file.write(json.dumps(request)) - - -class RPCPrintCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): - input_file: IO[Any] - - @staticmethod - def name() -> str: - return 'rpc-print' - - @staticmethod - def help_str() -> str: - return 'Pretty-print an RPC request/response' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument( - 'input_file', - type=FileType('r'), - help='An input file containing the JSON RPC request or response with KoreJSON payload.', - ) - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - printer = KPrint(kompiled_dir) - input_dict = json.loads(self.input_file.read()) - output_buffer = [] - - def pretty_print_request(request_params: dict[str, Any]) -> list[str]: - output_buffer = [] - non_state_keys = set(request_params.keys()).difference(['state']) - for key in non_state_keys: - output_buffer.append(f'{key}: {request_params[key]}') - state = CTerm.from_kast(printer.kore_to_kast(kore_term(request_params['state']))) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - return output_buffer - - def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: - output_buffer = [] - output_buffer.append(f'Depth: {execute_result.depth}') - output_buffer.append(f'Stop reason: {execute_result.reason.value}') - if execute_result.reason == StopReason.TERMINAL_RULE or execute_result.reason == StopReason.CUT_POINT_RULE: - output_buffer.append(f'Stop rule: {execute_result.rule}') - output_buffer.append( - f'Number of next states: {len(execute_result.next_states) if execute_result.next_states is not None else 0}' - ) - state = CTerm.from_kast(printer.kore_to_kast(execute_result.state.kore)) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - if execute_result.next_states is not None: - next_states = [CTerm.from_kast(printer.kore_to_kast(s.kore)) for s in execute_result.next_states] - for i, s in enumerate(next_states): - output_buffer.append(f'Next state #{i}:') - output_buffer.append(printer.pretty_print(s.kast, sort_collections=True)) - return output_buffer - - try: - if 'method' in input_dict: - output_buffer.append('JSON RPC request') - output_buffer.append(f'id: {input_dict["id"]}') - output_buffer.append(f'Method: {input_dict["method"]}') - try: - if 'state' in input_dict['params']: - output_buffer += pretty_print_request(input_dict['params']) - else: # this is an "add-module" request, skip trying to print state - for key in input_dict['params'].keys(): - output_buffer.append(f'{key}: {input_dict["params"][key]}') - except KeyError as e: - _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') - exit(1) - else: - if not 'result' in input_dict: - _LOGGER.critical('The input is neither a request not a resonse') - exit(1) - output_buffer.append('JSON RPC Response') - output_buffer.append(f'id: {input_dict["id"]}') - if list(input_dict['result'].keys()) == ['state']: # this is a "simplify" response - output_buffer.append('Method: simplify') - state = CTerm.from_kast(printer.kore_to_kast(kore_term(input_dict['result']['state']))) - output_buffer.append('State:') - output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) - elif list(input_dict['result'].keys()) == ['module']: # this is an "add-module" response - output_buffer.append('Method: add-module') - output_buffer.append('Module:') - output_buffer.append(input_dict['result']['module']) - else: - try: # assume it is an "execute" response - output_buffer.append('Method: execute') - execute_result = ExecuteResult.from_dict(input_dict['result']) - output_buffer += pretty_print_execute_response(execute_result) - except KeyError as e: - _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') - exit(1) - if self.output_file is not None: - self.output_file.write('\n'.join(output_buffer)) - else: - print('\n'.join(output_buffer)) - except ValueError as e: - # shorten and print the error message in case kore_to_kast throws ValueError - _LOGGER.critical(str(e)[:200]) - exit(1) - - -class PrintCommand(Command, DefinitionOptions, OutputFileOptions, DisplayOptions, LoggingOptions): - term: IO[Any] - input: PrintInput - minimize: bool - omit_labels: str | None - keep_cells: str | None - - @staticmethod - def name() -> str: - return 'print' - - @staticmethod - def help_str() -> str: - return 'Pretty print a term.' - - @staticmethod - def default() -> dict[str, Any]: - return { - 'input': PrintInput.KAST_JSON, - 'omit_labels': None, - 'keep_cells': None, - } - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument( - 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' - ) - parser.add_argument('--input', type=PrintInput, choices=list(PrintInput)) - parser.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.') - parser.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.') - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - printer = KPrint(kompiled_dir) - if self.input == PrintInput.KORE_JSON: - _LOGGER.info(f'Reading Kore JSON from file: {self.term.name}') - kore = Pattern.from_json(self.term.read()) - term = printer.kore_to_kast(kore) - else: - _LOGGER.info(f'Reading Kast JSON from file: {self.term.name}') - term = KInner.from_json(self.term.read()) - if is_top(term): - self.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - else: - if self.minimize: - if self.omit_labels != None and self.keep_cells != None: - raise ValueError('You cannot use both --omit-labels and --keep-cells.') - - abstract_labels = self.omit_labels.split(',') if self.omit_labels is not None else [] - keep_cells = self.keep_cells.split(',') if self.keep_cells is not None else [] - minimized_disjuncts = [] - - for disjunct in flatten_label('#Or', term): - try: - minimized = minimize_term(disjunct, abstract_labels=abstract_labels, keep_cells=keep_cells) - config, constraint = split_config_and_constraints(minimized) - except ValueError as err: - raise ValueError('The minimized term does not contain a config cell.') from err - - if not is_top(constraint): - minimized_disjuncts.append(mlAnd([config, constraint], sort=GENERATED_TOP_CELL)) - else: - minimized_disjuncts.append(config) - term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) - - self.output_file.write(printer.pretty_print(term)) - _LOGGER.info(f'Wrote file: {self.output_file.name}') - - -class ProveCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): - main_file: Path - spec_file: Path - spec_module: str - k_args: Iterable[str] - - @staticmethod - def name() -> str: - return 'prove' - - @staticmethod - def help_str() -> str: - return 'Prove an input specification (using kprovex).' - - @staticmethod - def update_args(parser: ArgumentParser) -> None: - parser.add_argument('main_file', type=str, help='Main file used for kompilation.') - parser.add_argument('spec_file', type=str, help='File with the specification module.') - parser.add_argument('spec_module', type=str, help='Module with claims to be proven.') - parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') - - def exec(self) -> None: - kompiled_dir: Path = self.definition_dir - kprover = KProve(kompiled_dir, self.main_file) - final_state = kprover.prove(Path(self.spec_file), spec_module_name=self.spec_module, args=self.k_args) - self.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) - _LOGGER.info(f'Wrote file: {self.output_file.name}') diff --git a/src/pyk/cli/pyk.py b/src/pyk/cli/pyk.py new file mode 100644 index 000000000..68c327cfb --- /dev/null +++ b/src/pyk/cli/pyk.py @@ -0,0 +1,375 @@ +from __future__ import annotations + +import json +import sys +from argparse import FileType +from enum import Enum +from pathlib import Path +from typing import IO, TYPE_CHECKING, Any + +from graphviz import Digraph + +from pyk.coverage import get_rule_by_id, strip_coverage_logger +from pyk.cterm import CTerm +from pyk.kast.inner import KInner +from pyk.kast.manip import ( + flatten_label, + minimize_rule, + minimize_term, + propagate_up_constraints, + remove_source_map, + split_config_and_constraints, +) +from pyk.kast.outer import read_kast_definition +from pyk.kast.pretty import PrettyPrinter +from pyk.kore.parser import KoreParser +from pyk.kore.rpc import ExecuteResult, StopReason +from pyk.kore.syntax import Pattern, kore_term +from pyk.ktool.kprint import KPrint +from pyk.ktool.kprove import KProve +from pyk.prelude.k import GENERATED_TOP_CELL +from pyk.prelude.ml import is_top, mlAnd, mlOr +from pyk.utils import _LOGGER + +from .args import DefinitionOptions, DisplayOptions, LoggingOptions, OutputFileOptions +from .cli import Command + +if TYPE_CHECKING: + from argparse import ArgumentParser + from collections.abc import Iterable + + +class PrintInput(Enum): + KORE_JSON = 'kore-json' + KAST_JSON = 'kast-json' + + +class JsonToKoreCommand(Command, LoggingOptions): + @staticmethod + def name() -> str: + return 'json-to-kore' + + @staticmethod + def help_str() -> str: + return 'Convert JSON to textual KORE' + + def exec(self) -> None: + text = sys.stdin.read() + kore = Pattern.from_json(text) + kore.write(sys.stdout) + sys.stdout.write('\n') + + +class KoreToJsonCommand(Command, LoggingOptions): + @staticmethod + def name() -> str: + return 'kore-to-json' + + @staticmethod + def help_str() -> str: + return 'Convert textual KORE to JSON' + + def exec(self) -> None: + text = sys.stdin.read() + kore = KoreParser(text).pattern() + print(kore.json) + + +class CoverageCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): + coverage_file: IO[Any] + + @staticmethod + def name() -> str: + return 'coverage' + + @staticmethod + def help_str() -> str: + return 'Convert coverage file to human readable log.' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.') + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json')) + pretty_printer = PrettyPrinter(definition) + for rid in self.coverage_file: + rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip()))) + self.output_file.write('\n\n') + self.output_file.write('Rule: ' + rid.strip()) + self.output_file.write('\nUnparsed:\n') + self.output_file.write(pretty_printer.print(rule)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + + +class GraphImportsCommand(Command, DefinitionOptions, LoggingOptions): + @staticmethod + def name() -> str: + return 'graph-imports' + + @staticmethod + def help_str() -> str: + return 'Graph the imports of a given definition.' + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + kprinter = KPrint(kompiled_dir) + definition = kprinter.definition + import_graph = Digraph() + graph_file = kompiled_dir / 'import-graph' + for module in definition.modules: + module_name = module.name + import_graph.node(module_name) + for module_import in module.imports: + import_graph.edge(module_name, module_import.name) + import_graph.render(graph_file) + _LOGGER.info(f'Wrote file: {graph_file}') + + +class RPCKastCommand(Command, OutputFileOptions, LoggingOptions): + reference_request_file: IO[Any] + response_file: IO[Any] + + @staticmethod + def name() -> str: + return 'rpc-kast' + + @staticmethod + def help_str() -> str: + return 'Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument( + 'reference_request_file', + type=FileType('r'), + help='An input file containing a JSON RPC request to server as a reference for the new request.', + ) + parser.add_argument( + 'response_file', + type=FileType('r'), + help='An input file containing a JSON RPC response with KoreJSON payload.', + ) + + def exec(self) -> None: + """ + Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request, + copying parameters from a reference request. + """ + reference_request = json.loads(self.reference_request_file.read()) + input_dict = json.loads(self.response_file.read()) + execute_result = ExecuteResult.from_dict(input_dict['result']) + non_state_keys = set(reference_request['params'].keys()).difference(['state']) + request_params = {} + for key in non_state_keys: + request_params[key] = reference_request['params'][key] + request_params['state'] = {'format': 'KORE', 'version': 1, 'term': execute_result.state.kore.dict} + request = { + 'jsonrpc': reference_request['jsonrpc'], + 'id': reference_request['id'], + 'method': reference_request['method'], + 'params': request_params, + } + self.output_file.write(json.dumps(request)) + + +class RPCPrintCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): + input_file: IO[Any] + + @staticmethod + def name() -> str: + return 'rpc-print' + + @staticmethod + def help_str() -> str: + return 'Pretty-print an RPC request/response' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument( + 'input_file', + type=FileType('r'), + help='An input file containing the JSON RPC request or response with KoreJSON payload.', + ) + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + printer = KPrint(kompiled_dir) + input_dict = json.loads(self.input_file.read()) + output_buffer = [] + + def pretty_print_request(request_params: dict[str, Any]) -> list[str]: + output_buffer = [] + non_state_keys = set(request_params.keys()).difference(['state']) + for key in non_state_keys: + output_buffer.append(f'{key}: {request_params[key]}') + state = CTerm.from_kast(printer.kore_to_kast(kore_term(request_params['state']))) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + return output_buffer + + def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]: + output_buffer = [] + output_buffer.append(f'Depth: {execute_result.depth}') + output_buffer.append(f'Stop reason: {execute_result.reason.value}') + if execute_result.reason == StopReason.TERMINAL_RULE or execute_result.reason == StopReason.CUT_POINT_RULE: + output_buffer.append(f'Stop rule: {execute_result.rule}') + output_buffer.append( + f'Number of next states: {len(execute_result.next_states) if execute_result.next_states is not None else 0}' + ) + state = CTerm.from_kast(printer.kore_to_kast(execute_result.state.kore)) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + if execute_result.next_states is not None: + next_states = [CTerm.from_kast(printer.kore_to_kast(s.kore)) for s in execute_result.next_states] + for i, s in enumerate(next_states): + output_buffer.append(f'Next state #{i}:') + output_buffer.append(printer.pretty_print(s.kast, sort_collections=True)) + return output_buffer + + try: + if 'method' in input_dict: + output_buffer.append('JSON RPC request') + output_buffer.append(f'id: {input_dict["id"]}') + output_buffer.append(f'Method: {input_dict["method"]}') + try: + if 'state' in input_dict['params']: + output_buffer += pretty_print_request(input_dict['params']) + else: # this is an "add-module" request, skip trying to print state + for key in input_dict['params'].keys(): + output_buffer.append(f'{key}: {input_dict["params"][key]}') + except KeyError as e: + _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') + exit(1) + else: + if not 'result' in input_dict: + _LOGGER.critical('The input is neither a request not a resonse') + exit(1) + output_buffer.append('JSON RPC Response') + output_buffer.append(f'id: {input_dict["id"]}') + if list(input_dict['result'].keys()) == ['state']: # this is a "simplify" response + output_buffer.append('Method: simplify') + state = CTerm.from_kast(printer.kore_to_kast(kore_term(input_dict['result']['state']))) + output_buffer.append('State:') + output_buffer.append(printer.pretty_print(state.kast, sort_collections=True)) + elif list(input_dict['result'].keys()) == ['module']: # this is an "add-module" response + output_buffer.append('Method: add-module') + output_buffer.append('Module:') + output_buffer.append(input_dict['result']['module']) + else: + try: # assume it is an "execute" response + output_buffer.append('Method: execute') + execute_result = ExecuteResult.from_dict(input_dict['result']) + output_buffer += pretty_print_execute_response(execute_result) + except KeyError as e: + _LOGGER.critical(f'Could not find key {str(e)} in input JSON file') + exit(1) + if self.output_file is not None: + self.output_file.write('\n'.join(output_buffer)) + else: + print('\n'.join(output_buffer)) + except ValueError as e: + # shorten and print the error message in case kore_to_kast throws ValueError + _LOGGER.critical(str(e)[:200]) + exit(1) + + +class PrintCommand(Command, DefinitionOptions, OutputFileOptions, DisplayOptions, LoggingOptions): + term: IO[Any] + input: PrintInput + minimize: bool + omit_labels: str | None + keep_cells: str | None + + @staticmethod + def name() -> str: + return 'print' + + @staticmethod + def help_str() -> str: + return 'Pretty print a term.' + + @staticmethod + def default() -> dict[str, Any]: + return { + 'input': PrintInput.KAST_JSON, + 'omit_labels': None, + 'keep_cells': None, + } + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument( + 'term', type=FileType('r'), help='File containing input term (in format specified with --input).' + ) + parser.add_argument('--input', type=PrintInput, choices=list(PrintInput)) + parser.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.') + parser.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.') + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + printer = KPrint(kompiled_dir) + if self.input == PrintInput.KORE_JSON: + _LOGGER.info(f'Reading Kore JSON from file: {self.term.name}') + kore = Pattern.from_json(self.term.read()) + term = printer.kore_to_kast(kore) + else: + _LOGGER.info(f'Reading Kast JSON from file: {self.term.name}') + term = KInner.from_json(self.term.read()) + if is_top(term): + self.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + else: + if self.minimize: + if self.omit_labels != None and self.keep_cells != None: + raise ValueError('You cannot use both --omit-labels and --keep-cells.') + + abstract_labels = self.omit_labels.split(',') if self.omit_labels is not None else [] + keep_cells = self.keep_cells.split(',') if self.keep_cells is not None else [] + minimized_disjuncts = [] + + for disjunct in flatten_label('#Or', term): + try: + minimized = minimize_term(disjunct, abstract_labels=abstract_labels, keep_cells=keep_cells) + config, constraint = split_config_and_constraints(minimized) + except ValueError as err: + raise ValueError('The minimized term does not contain a config cell.') from err + + if not is_top(constraint): + minimized_disjuncts.append(mlAnd([config, constraint], sort=GENERATED_TOP_CELL)) + else: + minimized_disjuncts.append(config) + term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL)) + + self.output_file.write(printer.pretty_print(term)) + _LOGGER.info(f'Wrote file: {self.output_file.name}') + + +class ProveCommand(Command, DefinitionOptions, OutputFileOptions, LoggingOptions): + main_file: Path + spec_file: Path + spec_module: str + k_args: Iterable[str] + + @staticmethod + def name() -> str: + return 'prove' + + @staticmethod + def help_str() -> str: + return 'Prove an input specification (using kprovex).' + + @staticmethod + def update_args(parser: ArgumentParser) -> None: + parser.add_argument('main_file', type=str, help='Main file used for kompilation.') + parser.add_argument('spec_file', type=str, help='File with the specification module.') + parser.add_argument('spec_module', type=str, help='Module with claims to be proven.') + parser.add_argument('k_args', nargs='*', help='Arguments to pass through to K invocation.') + + def exec(self) -> None: + kompiled_dir: Path = self.definition_dir + kprover = KProve(kompiled_dir, self.main_file) + final_state = kprover.prove(Path(self.spec_file), spec_module_name=self.spec_module, args=self.k_args) + self.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict())) + _LOGGER.info(f'Wrote file: {self.output_file.name}') From 41ad5e645ba41c8a44216e649b355310382ae5a9 Mon Sep 17 00:00:00 2001 From: devops Date: Wed, 6 Mar 2024 19:39:23 +0000 Subject: [PATCH 54/62] Set Version: 0.1.686 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c4fcfb09b..cdb0a91e5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.685' -release = '0.1.685' +version = '0.1.686' +release = '0.1.686' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index d0668c76b..8d2584175 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.685 +0.1.686 diff --git a/pyproject.toml b/pyproject.toml index caaa8086e..9d33d4666 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.685" +version = "0.1.686" description = "" authors = [ "Runtime Verification, Inc. ", From 44577de119d36ebd2899d714fd00d4a4bef1d5f2 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 6 Mar 2024 15:07:16 -0600 Subject: [PATCH 55/62] Fix kdist defaults, fix list defaults always being [] --- src/pyk/cli/cli.py | 9 +++++++-- src/pyk/kdist/__main__.py | 31 +++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index e084c9558..060052a3c 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -2,13 +2,13 @@ from abc import abstractmethod from argparse import ArgumentParser +from collections.abc import Iterable from typing import TYPE_CHECKING, Any from pyk.cli.args import Options if TYPE_CHECKING: from argparse import _SubParsersAction - from collections.abc import Iterable class CLI: @@ -48,7 +48,12 @@ def create_argument_parser(self) -> ArgumentParser: def get_command(self) -> Command: parser = self.create_argument_parser() args = parser.parse_args() - return self.generate_command({key: val for (key, val) in vars(args).items() if val is not None}) + stripped_args = { + key: val + for (key, val) in vars(args).items() + if val is not None and not (isinstance(val, Iterable) and not val) + } + return self.generate_command(stripped_args) def get_and_exec_command(self) -> None: cmd = self.get_command() diff --git a/src/pyk/kdist/__main__.py b/src/pyk/kdist/__main__.py index 7a7c02f9c..47643d2fe 100644 --- a/src/pyk/kdist/__main__.py +++ b/src/pyk/kdist/__main__.py @@ -4,8 +4,9 @@ import logging from typing import TYPE_CHECKING, Any -from pyk.cli.args import LoggingOptions, Options +from pyk.cli.args import LoggingOptions from pyk.cli.cli import CLI, Command +from pyk.cli.utils import loglevel from ..kdist import kdist, target_ids @@ -22,7 +23,11 @@ def main() -> None: kdist_cli = CLI( {KDistBuildCommand, KDistCleanCommand, KDistWhichCommand, KDistListCommand}, top_level_args=[LoggingOptions] ) - kdist_cli.get_and_exec_command() + cmd = kdist_cli.get_command() + assert isinstance(cmd, LoggingOptions) + print(vars(cmd)) + logging.basicConfig(level=loglevel(cmd), format=_LOG_FORMAT) + cmd.exec() def _process_targets(targets: list[str]) -> list[str]: @@ -66,7 +71,7 @@ def default() -> dict[str, Any]: return { 'force': False, 'jobs': 1, - 'targets': [], + 'targets': ['*'], 'args': [], } @@ -85,6 +90,8 @@ def update_args(parser: ArgumentParser) -> None: parser.add_argument('-j', '--jobs', metavar='N', type=int, help='maximal number of build jobs') def exec(self) -> None: + print(self.verbose) + print(self.debug) kdist.build( target_ids=_process_targets(self.targets), args=_process_args(self.args), @@ -94,7 +101,7 @@ def exec(self) -> None: ) -class KDistCleanCommand(Command, Options): +class KDistCleanCommand(Command, LoggingOptions): target: str @staticmethod @@ -105,6 +112,12 @@ def name() -> str: def help_str() -> str: return 'clean targets' + @staticmethod + def default() -> dict[str, Any]: + return { + 'target': None, + } + @staticmethod def update_args(parser: ArgumentParser) -> None: parser.add_argument( @@ -119,7 +132,7 @@ def exec(self) -> None: print(res) -class KDistWhichCommand(Command, Options): +class KDistWhichCommand(Command, LoggingOptions): target: str @staticmethod @@ -130,6 +143,12 @@ def name() -> str: def help_str() -> str: return 'print target location' + @staticmethod + def default() -> dict[str, Any]: + return { + 'target': None, + } + @staticmethod def update_args(parser: ArgumentParser) -> None: parser.add_argument( @@ -144,7 +163,7 @@ def exec(self) -> None: print(res) -class KDistListCommand(Command, Options): +class KDistListCommand(Command, LoggingOptions): @staticmethod def name() -> str: return 'list' From ab7a1a22ecbf385eb34a4be49ecfdc011e4eaefe Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 6 Mar 2024 15:42:44 -0600 Subject: [PATCH 56/62] Fix no default arg for list --- src/pyk/cli/pyk.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pyk/cli/pyk.py b/src/pyk/cli/pyk.py index 68c327cfb..6f4ee1a26 100644 --- a/src/pyk/cli/pyk.py +++ b/src/pyk/cli/pyk.py @@ -360,6 +360,11 @@ def name() -> str: def help_str() -> str: return 'Prove an input specification (using kprovex).' + def default() -> dict[str, Any]: + return { + 'k_args': [], + } + @staticmethod def update_args(parser: ArgumentParser) -> None: parser.add_argument('main_file', type=str, help='Main file used for kompilation.') From 2f58d508170fd354fedb9824c17a22ed495c9051 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 6 Mar 2024 15:45:37 -0600 Subject: [PATCH 57/62] Fix default not static --- src/pyk/cli/pyk.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pyk/cli/pyk.py b/src/pyk/cli/pyk.py index 6f4ee1a26..90c1c257d 100644 --- a/src/pyk/cli/pyk.py +++ b/src/pyk/cli/pyk.py @@ -360,6 +360,7 @@ def name() -> str: def help_str() -> str: return 'Prove an input specification (using kprovex).' + @staticmethod def default() -> dict[str, Any]: return { 'k_args': [], From 8a02f04d85da144bc66695017bf0fe994ec89d11 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Wed, 6 Mar 2024 21:39:01 -0600 Subject: [PATCH 58/62] Fix typo --- src/pyk/cli/args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index 7089bb455..fb452705e 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -201,7 +201,7 @@ def default() -> dict[str, Any]: 'o1': False, 'o2': False, 'o3': False, - 'ccopt': [], + 'ccopts': [], } @staticmethod From a5da13f8cb899459f3ada63e1d0ec742f446b9aa Mon Sep 17 00:00:00 2001 From: Noah Watson <107630091+nwatson22@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:48:56 -0600 Subject: [PATCH 59/62] Update src/pyk/cli/cli.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tamás Tóth --- src/pyk/cli/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index 060052a3c..15db50f0e 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -60,7 +60,7 @@ def get_and_exec_command(self) -> None: cmd.exec() -class Command: +class Command(ABC): @staticmethod @abstractmethod def name() -> str: From 1ac5abc8436ca50f1b31b4032571cddb10166924 Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Thu, 7 Mar 2024 11:49:41 -0600 Subject: [PATCH 60/62] Add import --- src/pyk/cli/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index 15db50f0e..902e40ba0 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -1,6 +1,6 @@ from __future__ import annotations -from abc import abstractmethod +from abc import ABC, abstractmethod from argparse import ArgumentParser from collections.abc import Iterable from typing import TYPE_CHECKING, Any From 645900d16ee64a7539d959231a45e6d03b3919ff Mon Sep 17 00:00:00 2001 From: Noah Watson Date: Thu, 7 Mar 2024 11:55:17 -0600 Subject: [PATCH 61/62] Switch to using git branch pyk version --- src/pyk/cli/args.py | 30 +++--------------------------- src/pyk/cli/cli.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/pyk/cli/args.py b/src/pyk/cli/args.py index fb452705e..7af8b4d99 100644 --- a/src/pyk/cli/args.py +++ b/src/pyk/cli/args.py @@ -1,14 +1,16 @@ from __future__ import annotations import sys -from argparse import ArgumentParser, FileType +from argparse import FileType from typing import IO, TYPE_CHECKING, Any from pyk.utils import ensure_dir_path +from .cli import Options from .utils import bug_report_arg, dir_path, file_path if TYPE_CHECKING: + from argparse import ArgumentParser from pathlib import Path from typing import TypeVar @@ -17,32 +19,6 @@ T = TypeVar('T') -class Options: - def __init__(self, args: dict[str, Any]) -> None: - # Get defaults from this and all superclasses that define them, preferring the most specific class - defaults: dict[str, Any] = {} - for cl in reversed(type(self).mro()): - if hasattr(cl, 'default'): - defaults = defaults | cl.default() - - # Overwrite defaults with args from command line - _args = defaults | args - - for attr, val in _args.items(): - self.__setattr__(attr, val) - - @classmethod - def all_args(cls: type[Options]) -> ArgumentParser: - # Collect args from this and all superclasses - parser = ArgumentParser(add_help=False) - mro = cls.mro() - mro.reverse() - for cl in mro: - if hasattr(cl, 'update_args') and 'update_args' in cl.__dict__: - cl.update_args(parser) - return parser - - class LoggingOptions(Options): debug: bool verbose: bool diff --git a/src/pyk/cli/cli.py b/src/pyk/cli/cli.py index 902e40ba0..1bbc5e2b4 100644 --- a/src/pyk/cli/cli.py +++ b/src/pyk/cli/cli.py @@ -5,8 +5,6 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Any -from pyk.cli.args import Options - if TYPE_CHECKING: from argparse import _SubParsersAction @@ -84,3 +82,29 @@ def parser(cls, base: _SubParsersAction) -> _SubParsersAction: parents=all_args, ) return base + + +class Options: + def __init__(self, args: dict[str, Any]) -> None: + # Get defaults from this and all superclasses that define them, preferring the most specific class + defaults: dict[str, Any] = {} + for cl in reversed(type(self).mro()): + if hasattr(cl, 'default'): + defaults = defaults | cl.default() + + # Overwrite defaults with args from command line + _args = defaults | args + + for attr, val in _args.items(): + self.__setattr__(attr, val) + + @classmethod + def all_args(cls: type[Options]) -> ArgumentParser: + # Collect args from this and all superclasses + parser = ArgumentParser(add_help=False) + mro = cls.mro() + mro.reverse() + for cl in mro: + if hasattr(cl, 'update_args') and 'update_args' in cl.__dict__: + cl.update_args(parser) + return parser From b77481a0e832e43fa6fd6693ab3309d9367d5694 Mon Sep 17 00:00:00 2001 From: devops Date: Thu, 7 Mar 2024 18:12:42 +0000 Subject: [PATCH 62/62] Set Version: 0.1.688 --- docs/conf.py | 4 ++-- package/version | 2 +- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index edf7a6512..9aed2648d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,8 @@ project = 'pyk' author = 'Runtime Verification, Inc' copyright = '2024, Runtime Verification, Inc' -version = '0.1.687' -release = '0.1.687' +version = '0.1.688' +release = '0.1.688' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/package/version b/package/version index a6945e651..bd3da3c55 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.687 +0.1.688 diff --git a/pyproject.toml b/pyproject.toml index d66044de2..3c0612727 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyk" -version = "0.1.687" +version = "0.1.688" description = "" authors = [ "Runtime Verification, Inc. ",