diff --git a/milatools/cli/commands.py b/milatools/cli/commands.py index 37afa78d..0a0b76fb 100644 --- a/milatools/cli/commands.py +++ b/milatools/cli/commands.py @@ -24,12 +24,13 @@ from urllib.parse import urlencode import questionary as qn -from invoke.exceptions import UnexpectedExit from typing_extensions import TypedDict from ..version import version as mversion from .init_command import ( - create_ssh_keypair, + print_welcome_message, + setup_keys_on_login_node, + setup_passwordless_ssh_access, setup_ssh_config, setup_vscode_settings, setup_windows_ssh_config_from_wsl, @@ -47,13 +48,13 @@ randname, running_inside_WSL, with_control_file, - yn, ) -logger = get_logger(__name__) if typing.TYPE_CHECKING: from typing_extensions import Unpack +logger = get_logger(__name__) + def main(): if sys.platform != "win32" and get_fully_qualified_name().endswith( @@ -139,12 +140,12 @@ def mila(): intranet_parser.set_defaults(function=intranet) # ----- mila init ------ - init_parser = subparsers.add_parser( "init", help="Set up your configuration and credentials.", formatter_class=SortingHelpFormatter, ) + init_parser.set_defaults(function=init) # ----- mila forward ------ @@ -396,7 +397,6 @@ def init(): print("Checking ssh config") ssh_config = setup_ssh_config() - print("# OK") # if we're running on WSL, we actually just copy the id_rsa + id_rsa.pub and the # ~/.ssh/config to the Windows ssh directory (taking care to remove the @@ -405,116 +405,14 @@ def init(): if running_inside_WSL(): setup_windows_ssh_config_from_wsl(linux_ssh_config=ssh_config) - setup_passwordless_ssh_access() + success = setup_passwordless_ssh_access(ssh_config=ssh_config) + if not success: + exit() setup_keys_on_login_node() setup_vscode_settings() print_welcome_message() -def setup_passwordless_ssh_access(): - print("Checking passwordless authentication") - - here = Local() - - # Check that there is an id file - ssh_private_key_path = Path.home() / ".ssh" / "id_rsa" - - sshdir = os.path.expanduser("~/.ssh") - if not any( - entry.startswith("id") and entry.endswith(".pub") - for entry in os.listdir(sshdir) - ): - if yn("You have no public keys. Generate one?"): - # Run ssh-keygen with the given location and no passphrase. - create_ssh_keypair(ssh_private_key_path, here) - else: - exit("No public keys.") - - # Check that it is possible to connect using the key - - if not here.check_passwordless("mila"): - if yn( - "Your public key does not appear be registered on the cluster. Register it?" - ): - # NOTE: If we're on a Windows machine, we do something different here: - if sys.platform == "win32": - command = ( - "powershell.exe type $env:USERPROFILE\\.ssh\\id_rsa.pub | ssh mila " - '"cat >> ~/.ssh/authorized_keys"' - ) - here.run(command) - else: - here.run("ssh-copy-id", "mila") - if not here.check_passwordless("mila"): - exit("ssh-copy-id appears to have failed") - else: - exit("No passwordless login.") - - -def setup_keys_on_login_node(): - print("Checking connection to compute nodes") - - remote = Remote("mila") - try: - pubkeys = remote.get_lines("ls -t ~/.ssh/id*.pub") - print("# OK") - except UnexpectedExit: - print("# MISSING") - if yn("You have no public keys on the login node. Generate them?"): - # print("(Note: You can just press Enter 3x to accept the defaults)") - # _, keyfile = remote.extract( - # "ssh-keygen", - # pattern="Your public key has been saved in ([^ ]+)", - # wait=True, - # ) - private_file = "~/.ssh/id_rsa" - remote.run(f'ssh-keygen -q -t rsa -N "" -f {private_file}') - pubkeys = [f"{private_file}.pub"] - else: - exit("Cannot proceed because there is no public key") - - common = remote.with_bash().get_output( - "comm -12 <(sort ~/.ssh/authorized_keys) <(sort ~/.ssh/*.pub)" - ) - if common: - print("# OK") - else: - print("# MISSING") - if yn( - "To connect to a compute node from a login node you need one id_*.pub to " - "be in authorized_keys. Do it?" - ): - pubkey = pubkeys[0] - remote.run(f"cat {pubkey} >> ~/.ssh/authorized_keys") - else: - exit("You will not be able to SSH to a compute node") - - -def print_welcome_message(): - print(T.bold_cyan("=" * 60)) - print(T.bold_cyan("Congrats! You are now ready to start working on the cluster!")) - print(T.bold_cyan("=" * 60)) - print(T.bold("To connect to a login node:")) - print(" ssh mila") - print(T.bold("To allocate and connect to a compute node:")) - print(" ssh mila-cpu") - print(T.bold("To open a directory on the cluster with VSCode:")) - print(" mila code path/to/code/on/cluster") - print(T.bold("Same as above, but allocate 1 GPU, 4 CPUs, 32G of RAM:")) - print(" mila code path/to/code/on/cluster --alloc --gres=gpu:1 --mem=32G -c 4") - print() - print( - "For more information, read the milatools documentation at", - T.bold_cyan("https://github.com/mila-iqia/milatools"), - "or run `mila --help`.", - "Also make sure you read the Mila cluster documentation at", - T.bold_cyan("https://docs.mila.quebec/"), - "and join the", - T.bold_green("#mila-cluster"), - "channel on Slack.", - ) - - def forward( remote: str, page: str | None, diff --git a/milatools/cli/init_command.py b/milatools/cli/init_command.py index 3f11fd9f..5dbfc9fe 100644 --- a/milatools/cli/init_command.py +++ b/milatools/cli/init_command.py @@ -2,7 +2,9 @@ import copy import difflib +import functools import json +import shlex import shutil import subprocess import sys @@ -12,8 +14,10 @@ from typing import Any import questionary as qn +from invoke.exceptions import UnexpectedExit -from .local import Local +from .local import Local, check_passwordless +from .remote import Remote from .utils import SSHConfig, T, running_inside_WSL, yn from .vscode_utils import ( get_expected_vscode_settings_json_path, @@ -23,8 +27,88 @@ logger = get_logger(__name__) WINDOWS_UNSUPPORTED_KEYS = ["ControlMaster", "ControlPath", "ControlPersist"] -HOSTS = ["mila", "mila-cpu", "*.server.mila.quebec !*login.server.mila.quebec"] -"""List of host entries that get added to the SSH configuration by `mila init`.""" + + +if sys.platform == "win32": + ssh_multiplexing_config = {} +else: + ssh_multiplexing_config = { + # Tries to reuse an existing connection, but if it fails, it will create a + # new one. + "ControlMaster": "auto", + # This makes a file per connection, like + # normandf@login.server.mila.quebec:2222 + "ControlPath": r"~/.cache/ssh/%r@%h:%p", + # persist for 10 minutes after the last connection ends. + "ControlPersist": 600, + } + + +MILA_ENTRIES: dict[str, dict[str, int | str]] = { + "mila": { + "HostName": "login.server.mila.quebec", + # "User": mila_username, + "PreferredAuthentications": "publickey,keyboard-interactive", + "Port": 2222, + "ServerAliveInterval": 120, + "ServerAliveCountMax": 5, + **ssh_multiplexing_config, + }, + "mila-cpu": { + # "User": mila_username, + "Port": 2222, + "ForwardAgent": "yes", + "StrictHostKeyChecking": "no", + "LogLevel": "ERROR", + "UserKnownHostsFile": "/dev/null", + "RequestTTY": "force", + "ConnectTimeout": 600, + "ServerAliveInterval": 120, + # NOTE: will not work with --gres prior to Slurm 22.05, because srun --overlap + # cannot share gpus + "ProxyCommand": ( + 'ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh ' + 'mila-cpu --mem=8G"' + ), + "RemoteCommand": ( + "/cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu" + ), + }, + "*.server.mila.quebec !*login.server.mila.quebec": { + "HostName": "%h", + # "User": mila_username, + "ProxyJump": "mila", + **ssh_multiplexing_config, + }, +} +DRAC_CLUSTERS = ["beluga", "cedar", "graham", "narval"] +DRAC_ENTRIES: dict[str, dict[str, int | str]] = { + "beluga cedar graham narval niagara": { + "Hostname": "%h.alliancecan.ca", + # User=drac_username, + **ssh_multiplexing_config, + }, + "!beluga bc????? bg????? bl?????": { + "ProxyJump": "beluga", + # User=drac_username, + }, + "!cedar cdr? cdr?? cdr??? cdr????": { + "ProxyJump": "cedar", + # User=drac_username, + }, + "!graham gra??? gra????": { + "ProxyJump": "graham", + # User=drac_username, + }, + "!narval nc????? ng?????": { + "ProxyJump": "narval", + # User=drac_username, + }, + "!niagara nia????": { + "ProxyJump": "niagara", + # User=drac_username, + }, +} def setup_ssh_config( @@ -44,96 +128,39 @@ def setup_ssh_config( - "*.server.mila.quebec !*login.server.mila.quebec": Sets some useful attributes for connecting directly to compute nodes. - TODO: Also ask if we should add entries for the ComputeCanada/DRAC clusters. - Returns: The resulting SSHConfig if the changes are approved. """ ssh_config_path = _setup_ssh_config_file(ssh_config_path) ssh_config = SSHConfig(ssh_config_path) - username: str = _get_username(ssh_config) + mila_username: str = _get_mila_username(ssh_config) + drac_username: str | None = _get_drac_username(ssh_config) orig_config = ssh_config.cfg.config() - control_path_dir = Path("~/.cache/ssh") - # note: a bit nicer to keep the "~" in the path in the ssh config file, but we need - # to make sure that the directory actually exists. - control_path_dir.expanduser().mkdir(exist_ok=True, parents=True) + for hostname, entry in MILA_ENTRIES.copy().items(): + entry.update(User=mila_username) + _add_ssh_entry(ssh_config, hostname, entry) + _make_controlpath_dir(entry) - if sys.platform == "win32": - ssh_multiplexing_config = {} - else: - ssh_multiplexing_config = { - # Tries to reuse an existing connection, but if it fails, it will create a - # new one. - "ControlMaster": "auto", - # This makes a file per connection, like - # normandf@login.server.mila.quebec:2222 - "ControlPath": str(control_path_dir / r"%r@%h:%p"), - # persist for 10 minutes after the last connection ends. - "ControlPersist": 600, - } - - _add_ssh_entry( - ssh_config, - host="mila", - HostName="login.server.mila.quebec", - User=username, - PreferredAuthentications="publickey,keyboard-interactive", - Port=2222, - ServerAliveInterval=120, - ServerAliveCountMax=5, - **ssh_multiplexing_config, - ) - - _add_ssh_entry( - ssh_config, - "mila-cpu", - User=username, - Port=2222, - ForwardAgent="yes", - StrictHostKeyChecking="no", - LogLevel="ERROR", - UserKnownHostsFile="/dev/null", - RequestTTY="force", - ConnectTimeout=600, - ServerAliveInterval=120, - # NOTE: will not work with --gres prior to Slurm 22.05, because srun --overlap - # cannot share it - ProxyCommand=( - 'ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh ' - 'mila-cpu --mem=8G"' - ), - RemoteCommand=( - "/cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu" - ), - ) + if drac_username: + logger.debug( + f"Adding entries for the ComputeCanada/DRAC clusters to {ssh_config_path}." + ) + for hostname, entry in DRAC_ENTRIES.copy().items(): + entry.update(User=drac_username) + _add_ssh_entry(ssh_config, hostname, entry) + _make_controlpath_dir(entry) # Check for *.server.mila.quebec in ssh config, to connect to compute nodes - old_cnode_pattern = "*.server.mila.quebec" - cnode_pattern = "*.server.mila.quebec !*login.server.mila.quebec" if old_cnode_pattern in ssh_config.hosts(): - if yn( - "The '*.server.mila.quebec' entry in ~/.ssh/config is too general and " - "should exclude login.server.mila.quebec. Fix this?" - ): - if cnode_pattern in ssh_config.hosts(): - ssh_config.remove(old_cnode_pattern) - else: - ssh_config.rename(old_cnode_pattern, cnode_pattern) - else: - _add_ssh_entry( - ssh_config, - cnode_pattern, - HostName="%h", - User=username, - ProxyJump="mila", - ForwardAgent="yes", - ForwardX11="yes", - **ssh_multiplexing_config, + logger.info( + f"The '{old_cnode_pattern}' entry in ~/.ssh/config is too general and " + "should exclude login.server.mila.quebec. Fixing this." ) + ssh_config.remove(old_cnode_pattern) new_config = ssh_config.cfg.config() if orig_config == new_config: @@ -200,6 +227,174 @@ def setup_windows_ssh_config_from_wsl(linux_ssh_config: SSHConfig): _copy_if_needed(linux_key_file, windows_key_file) +def setup_passwordless_ssh_access(ssh_config: SSHConfig) -> bool: + """Sets up passwordless ssh access to the Mila and optionally also to DRAC. + + Sets up ssh connection to the DRAC clusters if they are present in the SSH config + file. + + Returns whether the operation completed successfully or not. + """ + print("Checking passwordless authentication") + + here = Local() + sshdir = Path.home() / ".ssh" + ssh_private_key_path = Path.home() / ".ssh" / "id_rsa" + + # Check if there is a public key file in ~/.ssh + if not list(sshdir.glob("id*.pub")): + if yn("You have no public keys. Generate one?"): + # Run ssh-keygen with the given location and no passphrase. + create_ssh_keypair(ssh_private_key_path, here) + else: + print("No public keys.") + return False + + success = setup_passwordless_ssh_access_to_cluster("mila") + if not success: + return False + + drac_clusters_in_ssh_config: list[str] = [] + hosts_in_config = ssh_config.hosts() + for cluster in DRAC_CLUSTERS: + if any(cluster in hostname for hostname in hosts_in_config): + drac_clusters_in_ssh_config.append(cluster) + + if not drac_clusters_in_ssh_config: + logger.debug( + f"There are no DRAC clusters in the SSH config at {ssh_config.path}." + ) + return True + + print( + "Setting up passwordless ssh access to the DRAC clusters with ssh-copy-id.\n" + "\n" + "Please note that you can also setup passwordless SSH access to all the DRAC " + "clusters by visiting https://ccdb.alliancecan.ca/ssh_authorized_keys and " + "copying in the content of your public key in the box.\n" + "See https://docs.alliancecan.ca/wiki/SSH_Keys#Using_CCDB for more info." + ) + for drac_cluster in drac_clusters_in_ssh_config: + success = setup_passwordless_ssh_access_to_cluster(drac_cluster) + if not success: + return False + return True + + +def setup_passwordless_ssh_access_to_cluster(cluster: str) -> bool: + """Sets up passwordless SSH access to the given hostname. + + On Mac/Linux, uses `ssh-copy-id`. Performs the steps of ssh-copy-id manually on + Windows. + + Returns whether the operation completed successfully or not. + """ + here = Local() + # Check that it is possible to connect without using a password. + print(f"Checking if passwordless SSH access is setup for the {cluster} cluster.") + # TODO: Potentially use the public key from the SSH config file instead of + # the default. It's also possible that ssh-copy-id selects the key from the + # config file, I'm not sure. + # ssh_private_key_path = Path.home() / ".ssh" / "id_rsa" + + if check_passwordless(cluster): + logger.info(f"Passwordless SSH access to {cluster} is already setup correctly.") + return True + + if not yn( + f"Your public key does not appear be registered on the {cluster} cluster. " + "Register it?" + ): + print("No passwordless login.") + return False + + print("Please enter your password when prompted.") + if sys.platform == "win32": + # todo: the path to the key is hard-coded here. + command = ( + "powershell.exe", + "type", + "$env:USERPROFILE\\.ssh\\id_rsa.pub", + "|", + "ssh", + "-o", + "StrictHostKeyChecking=no", + cluster, + '"cat >> ~/.ssh/authorized_keys"', + ) + here.run(*command, check=True) + else: + here.run("ssh-copy-id", "-o", "StrictHostKeyChecking=no", cluster, check=True) + + # double-check that this worked. + if not check_passwordless(cluster): + print(f"'ssh-copy-id {cluster}' appears to have failed!") + return False + return True + + +def setup_keys_on_login_node(): + ##################################### + # Step 3: Set up keys on login node # + ##################################### + + print("Checking connection to compute nodes") + + remote = Remote("mila") + try: + pubkeys = remote.get_lines("ls -t ~/.ssh/id*.pub") + print("# OK") + except UnexpectedExit: + print("# MISSING") + if yn("You have no public keys on the login node. Generate them?"): + private_file = "~/.ssh/id_rsa" + remote.run(f'ssh-keygen -q -t rsa -N "" -f {private_file}') + pubkeys = [f"{private_file}.pub"] + else: + exit("Cannot proceed because there is no public key") + + common = remote.with_bash().get_output( + "comm -12 <(sort ~/.ssh/authorized_keys) <(sort ~/.ssh/*.pub)" + ) + if common: + print("# OK") + else: + print("# MISSING") + if yn( + "To connect to a compute node from a login node you need one id_*.pub to " + "be in authorized_keys. Do it?" + ): + pubkey = pubkeys[0] + remote.run(f"cat {pubkey} >> ~/.ssh/authorized_keys") + else: + exit("You will not be able to SSH to a compute node") + + +def print_welcome_message(): + print(T.bold_cyan("=" * 60)) + print(T.bold_cyan("Congrats! You are now ready to start working on the cluster!")) + print(T.bold_cyan("=" * 60)) + print(T.bold("To connect to a login node:")) + print(" ssh mila") + print(T.bold("To allocate and connect to a compute node:")) + print(" ssh mila-cpu") + print(T.bold("To open a directory on the cluster with VSCode:")) + print(" mila code path/to/code/on/cluster") + print(T.bold("Same as above, but allocate 1 GPU, 4 CPUs, 32G of RAM:")) + print(" mila code path/to/code/on/cluster --alloc --gres=gpu:1 --mem=32G -c 4") + print() + print( + "For more information, read the milatools documentation at", + T.bold_cyan("https://github.com/mila-iqia/milatools"), + "or run `mila --help`.", + "Also make sure you read the Mila cluster documentation at", + T.bold_cyan("https://docs.mila.quebec/"), + "and join the", + T.bold_green("#mila-cluster"), + "channel on Slack.", + ) + + def _copy_if_needed(linux_key_file: Path, windows_key_file: Path): if linux_key_file.exists() and not windows_key_file.exists(): print( @@ -216,7 +411,11 @@ def get_windows_home_path_in_wsl() -> Path: def create_ssh_keypair(ssh_private_key_path: Path, local: Local) -> None: - local.run("ssh-keygen", "-f", str(ssh_private_key_path), "-t", "rsa", "-N=''") + local.run( + *shlex.split( + f'ssh-keygen -f {shlex.quote(str(ssh_private_key_path))} -t rsa -N=""' + ), + ) def setup_vscode_settings(): @@ -240,25 +439,34 @@ def setup_vscode_settings(): ) ) return - + vscode_settings_json_path = get_expected_vscode_settings_json_path() try: - _update_vscode_settings_json({"remote.SSH.connectTimeout": 60}) + _update_vscode_settings_json( + vscode_settings_json_path, new_values={"remote.SSH.connectTimeout": 60} + ) except Exception as err: logger.warning( - f"Unable to setup VsCode settings for remote development: {err}\n" - f"Skipping and leaving the settings unchanged.", + T.orange( + f"Unable to setup VsCode settings file at {vscode_settings_json_path} " + f"for remote development.\n" + f"Skipping and leaving the settings unchanged." + ), exc_info=err, ) -def _update_vscode_settings_json(new_values: dict[str, Any]) -> None: - vscode_settings_json_path = get_expected_vscode_settings_json_path() - +def _update_vscode_settings_json( + vscode_settings_json_path: Path, new_values: dict[str, Any] +) -> None: settings_json: dict[str, Any] = {} if vscode_settings_json_path.exists(): logger.info(f"Reading VsCode settings from {vscode_settings_json_path}") with open(vscode_settings_json_path) as f: - settings_json = json.load(f) + settings_json = json.loads( + "\n".join( + line for line in f.readlines() if not line.strip().startswith("#") + ) + ) settings_before = copy.deepcopy(settings_json) settings_json.update( @@ -338,7 +546,7 @@ def _confirm_changes(ssh_config: SSHConfig, previous: str) -> bool: return ask_to_confirm_changes(before, after, ssh_config.path) -def _get_username(ssh_config: SSHConfig) -> str: +def _get_mila_username(ssh_config: SSHConfig) -> str: # Check for a mila entry in ssh config # NOTE: This also supports the case where there's a 'HOST mila some_alias_for_mila' # entry. @@ -359,14 +567,47 @@ def _get_username(ssh_config: SSHConfig) -> str: while not username: username = qn.text( "What's your username on the mila cluster?\n", - validate=_is_valid_username, + validate=functools.partial(_is_valid_username, cluster_name="mila cluster"), ).unsafe_ask() return username.strip() -def _is_valid_username(text: str) -> bool | str: +def _get_drac_username(ssh_config: SSHConfig) -> str | None: + """Retrieve or ask the user for their username on the ComputeCanada/DRAC + clusters.""" + # Check for one of the DRAC entries in ssh config + username: str | None = None + hosts_with_cluster_in_name_and_a_user_entry = [ + host + for host in ssh_config.hosts() + if any( + cc_cluster in host.split() or f"!{cc_cluster}" in host.split() + for cc_cluster in DRAC_CLUSTERS + ) + and "user" in ssh_config.host(host) + ] + users_from_drac_config_entries = set( + ssh_config.host(host)["user"] + for host in hosts_with_cluster_in_name_and_a_user_entry + ) + # Note: If there are none, or more than one, then we'll ask the user for their + # username, just to be sure. + if len(users_from_drac_config_entries) == 1: + username = users_from_drac_config_entries.pop() + elif yn("Do you also have an account on the ComputeCanada/DRAC clusters?"): + while not username: + username = qn.text( + "What's your username on the CC/DRAC clusters?\n", + validate=functools.partial( + _is_valid_username, cluster_name="ComputeCanada/DRAC clusters" + ), + ).unsafe_ask() + return username.strip() if username else None + + +def _is_valid_username(text: str, cluster_name: str = "mila cluster") -> bool | str: return ( - "Please enter your username on the mila cluster." + f"Please enter your username on the {cluster_name}." if not text or text.isspace() else True ) @@ -381,22 +622,27 @@ def _is_valid_username(text: str) -> bool | str: def _add_ssh_entry( ssh_config: SSHConfig, host: str, - Host: str | None = None, + entry: dict[str, str | int], *, _space_before: bool = True, _space_after: bool = False, - **entry, ) -> None: """Adds or updates an entry in the ssh config object.""" # NOTE: `Host` is also a parameter to make sure it isn't in `entry`. - assert not (host and Host) - host = Host or host + assert "Host" not in entry + + sorted_by_keys = False + if host in ssh_config.hosts(): existing_entry = ssh_config.host(host) existing_entry.update(entry) + if sorted_by_keys: + existing_entry = dict(sorted(existing_entry.items())) ssh_config.cfg.set(host, **existing_entry) logger.debug(f"Updated {host} entry in ssh config at path {ssh_config.path}.") else: + if sorted_by_keys: + entry = dict(sorted(entry.items())) ssh_config.add( host, _space_before=_space_before, @@ -414,13 +660,15 @@ def _copy_valid_ssh_entries_to_windows_ssh_config_file( unsupported_keys_lowercase = set(k.lower() for k in WINDOWS_UNSUPPORTED_KEYS) # NOTE: need to preserve the ordering of entries: - for host in HOSTS + [ - host for host in linux_ssh_config.hosts() if host not in HOSTS + entries_to_move = list(MILA_ENTRIES.keys()) + list(DRAC_ENTRIES.keys()) + for host in entries_to_move + [ + host for host in linux_ssh_config.hosts() if host not in entries_to_move ]: if host not in linux_ssh_config.hosts(): warnings.warn( RuntimeWarning( - f"Weird, we expected to have a {host!r} entry in the SSH config..." + f"We expected to have a {host!r} entry in the SSH config. " + f"Did you run `mila init`?" ) ) continue @@ -428,9 +676,19 @@ def _copy_valid_ssh_entries_to_windows_ssh_config_file( _add_ssh_entry( windows_ssh_config, host, - **{ + { key: value for key, value in linux_ssh_entry.items() if key.lower() not in unsupported_keys_lowercase }, ) + + +def _make_controlpath_dir(entry: dict[str, str | int]) -> None: + if "ControlPath" not in entry: + return + control_path = entry["ControlPath"] + assert isinstance(control_path, str) + # Create the ControlPath directory if it doesn't exist: + control_path_dir = Path(control_path).expanduser().parent + control_path_dir.mkdir(exist_ok=True, parents=True) diff --git a/milatools/cli/local.py b/milatools/cli/local.py index 9c30ae60..a9a1b73f 100644 --- a/milatools/cli/local.py +++ b/milatools/cli/local.py @@ -1,25 +1,29 @@ from __future__ import annotations -import shlex import subprocess +from logging import getLogger as get_logger from subprocess import CompletedProcess from typing import IO, Any +import fabric +import paramiko.ssh_exception from typing_extensions import deprecated from .utils import CommandNotFoundError, T, shjoin +logger = get_logger(__name__) + class Local: def display(self, args: list[str] | tuple[str, ...]) -> None: - print(T.bold_green("(local) $ ", shjoin(args))) + display(args) def silent_get(self, *cmd: str) -> str: return subprocess.check_output(cmd, universal_newlines=True) @deprecated("This isn't used and will probably be removed. Don't start using it.") def get(self, *cmd: str) -> str: - self.display(cmd) + display(cmd) return subprocess.check_output(cmd, universal_newlines=True) def run( @@ -28,8 +32,10 @@ def run( stdout: int | IO[Any] | None = None, stderr: int | IO[Any] | None = None, capture_output: bool = False, + timeout: float | None = None, + check: bool = False, ) -> CompletedProcess[str]: - self.display(cmd) + display(cmd) try: return subprocess.run( cmd, @@ -37,6 +43,8 @@ def run( stderr=stderr, capture_output=capture_output, universal_newlines=True, + timeout=timeout, + check=check, ) except FileNotFoundError as e: if e.filename == cmd[0]: @@ -54,20 +62,33 @@ def popen( cmd, stdout=stdout, stderr=stderr, universal_newlines=True ) - def check_passwordless(self, host: str) -> bool: - results = self.run( - *shlex.split(f"ssh -oPreferredAuthentications=publickey {host} 'echo OK'"), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - if results.returncode != 0: - if "Permission denied" in results.stderr: - return False - print(results.stdout) - print(results.stderr) - exit(f"Failed to connect to {host}, could not understand error") - # TODO: Perhaps we could actually check the output of the command here! - # elif "OK" in results.stdout: - else: - print("# OK") - return True + def check_passwordless(self, host: str): + return check_passwordless(host) + + +def display(split_command: list[str] | tuple[str, ...]) -> None: + print(T.bold_green("(local) $ ", shjoin(split_command))) + + +def check_passwordless(host: str) -> bool: + try: + with fabric.Connection(host) as connection: + results: fabric.runners.Result = connection.run( + "echo OK", + in_stream=False, + echo=True, + echo_format=T.bold_cyan(f"({host})" + " $ {command}"), + ) + + except ( + paramiko.ssh_exception.SSHException, + paramiko.ssh_exception.NoValidConnectionsError, + ) as err: + logger.debug(f"Unable to connect to {host} without a password: {err}") + return False + + if "OK" in results.stdout: + return True + logger.error("Unexpected output from SSH command, output didn't contain 'OK'!") + logger.error(f"stdout: {results.stdout}, stderr: {results.stderr}") + return False diff --git a/poetry.lock b/poetry.lock index 55014833..57f1544f 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" @@ -22,66 +22,57 @@ files = [ {file = "ansicon-1.89.0.tar.gz", hash = "sha256:e4d039def5768a47e4afec8e89e83ec3ae5a26bf00ad851f914d1240b444d2b1"}, ] -[[package]] -name = "attrs" -version = "22.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.6" -files = [ - {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, - {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, -] - -[package.extras] -cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] -tests = ["attrs[tests-no-zope]", "zope.interface"] -tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] - [[package]] name = "babel" -version = "2.11.0" +version = "2.14.0" description = "Internationalization utilities" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, - {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, ] [package.dependencies] -pytz = ">=2015.7" +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "bcrypt" -version = "4.0.1" +version = "4.1.2" description = "Modern password hashing for your software and your servers" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "bcrypt-4.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2"}, - {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535"}, - {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e"}, - {file = "bcrypt-4.0.1-cp36-abi3-win32.whl", hash = "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab"}, - {file = "bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9"}, - {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c"}, - {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b"}, - {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d"}, - {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d"}, - {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215"}, - {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c"}, - {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda"}, - {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665"}, - {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71"}, - {file = "bcrypt-4.0.1.tar.gz", hash = "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd"}, + {file = "bcrypt-4.1.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ac621c093edb28200728a9cca214d7e838529e557027ef0581685909acd28b5e"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea505c97a5c465ab8c3ba75c0805a102ce526695cd6818c6de3b1a38f6f60da1"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57fa9442758da926ed33a91644649d3e340a71e2d0a5a8de064fb621fd5a3326"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb3bd3321517916696233b5e0c67fd7d6281f0ef48e66812db35fc963a422a1c"}, + {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6cad43d8c63f34b26aef462b6f5e44fdcf9860b723d2453b5d391258c4c8e966"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:44290ccc827d3a24604f2c8bcd00d0da349e336e6503656cb8192133e27335e2"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:732b3920a08eacf12f93e6b04ea276c489f1c8fb49344f564cca2adb663b3e4c"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1c28973decf4e0e69cee78c68e30a523be441972c826703bb93099868a8ff5b5"}, + {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b8df79979c5bae07f1db22dcc49cc5bccf08a0380ca5c6f391cbb5790355c0b0"}, + {file = "bcrypt-4.1.2-cp37-abi3-win32.whl", hash = "sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369"}, + {file = "bcrypt-4.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:9800ae5bd5077b13725e2e3934aa3c9c37e49d3ea3d06318010aa40f54c63551"}, + {file = "bcrypt-4.1.2-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:71b8be82bc46cedd61a9f4ccb6c1a493211d031415a34adde3669ee1b0afbb63"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e3c6642077b0c8092580c819c1684161262b2e30c4f45deb000c38947bf483"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:387e7e1af9a4dd636b9505a465032f2f5cb8e61ba1120e79a0e1cd0b512f3dfc"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7"}, + {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2a298db2a8ab20056120b45e86c00a0a5eb50ec4075b6142db35f593b97cb3fb"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ba55e40de38a24e2d78d34c2d36d6e864f93e0d79d0b6ce915e4335aa81d01b1"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3566a88234e8de2ccae31968127b0ecccbb4cddb629da744165db72b58d88ca4"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b90e216dc36864ae7132cb151ffe95155a37a14e0de3a8f64b49655dd959ff9c"}, + {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:69057b9fc5093ea1ab00dd24ede891f3e5e65bee040395fb1e66ee196f9c9b4a"}, + {file = "bcrypt-4.1.2-cp39-abi3-win32.whl", hash = "sha256:02d9ef8915f72dd6daaef40e0baeef8a017ce624369f09754baf32bb32dba25f"}, + {file = "bcrypt-4.1.2-cp39-abi3-win_amd64.whl", hash = "sha256:be3ab1071662f6065899fe08428e45c16aa36e28bc42921c4901a191fda6ee42"}, + {file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d75fc8cd0ba23f97bae88a6ec04e9e5351ff3c6ad06f38fe32ba50cbd0d11946"}, + {file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:a97e07e83e3262599434816f631cc4c7ca2aa8e9c072c1b1a7fec2ae809a1d2d"}, + {file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e51c42750b7585cee7892c2614be0d14107fad9581d1738d954a262556dd1aab"}, + {file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba4e4cc26610581a6329b3937e02d319f5ad4b85b074846bf4fef8a8cf51e7bb"}, + {file = "bcrypt-4.1.2.tar.gz", hash = "sha256:33313a1200a3ae90b75587ceac502b048b840fc69e7f7a0905b5f87fac7a1258"}, ] [package.extras] @@ -90,28 +81,42 @@ typecheck = ["mypy"] [[package]] name = "black" -version = "23.1a1" +version = "23.3.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.7" files = [ - {file = "black-23.1a1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fb7641d442ede92538bc70fa0201f884753a7d0f62f26c722b7b00301b95902"}, - {file = "black-23.1a1-cp310-cp310-win_amd64.whl", hash = "sha256:88288a645402106b8eb9f50d7340ae741e16240bb01c2eed8466549153daa96e"}, - {file = "black-23.1a1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db1d8027ce7ae53f0ccf02b0be0b8808fefb291d6cb1543420f4165d96d364c"}, - {file = "black-23.1a1-cp311-cp311-win_amd64.whl", hash = "sha256:88ec25a64063945b4591b6378bead544c5d3260de1c93ad96f3ad2d76ddd76fd"}, - {file = "black-23.1a1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dff6f0157e47fbbeada046fca144b6557d3be2fb2602d668881cd179f04a352"}, - {file = "black-23.1a1-cp37-cp37m-win_amd64.whl", hash = "sha256:ca658b69260a18bf7aa0b0a6562dbbd304a737487d1318998aaca5a75901fd2c"}, - {file = "black-23.1a1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85dede655442f5e246e7abd667fe07e14916897ba52f3640b5489bf11f7dbf67"}, - {file = "black-23.1a1-cp38-cp38-win_amd64.whl", hash = "sha256:ddbf9da228726d46f45c29024263e160d41030a415097254817d65127012d1a2"}, - {file = "black-23.1a1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63330069d8ec909cf4e2c4d43a7f00aeb03335430ef9fec6cd2328e6ebde8a77"}, - {file = "black-23.1a1-cp39-cp39-win_amd64.whl", hash = "sha256:793c9176beb2adf295f6b863d9a4dc953fe2ac359ca3da108d71d14cb2c09e52"}, - {file = "black-23.1a1-py3-none-any.whl", hash = "sha256:e88e4b633d64b9e7adc4a6b922f52bb204af9f90d7b1e3317e6490f2b598b1ea"}, - {file = "black-23.1a1.tar.gz", hash = "sha256:0b945a5a1e5a5321f884de0061d5a8585d947c9b608e37b6d26ceee4dfdf4b62"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, + {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, + {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, + {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, + {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, + {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, + {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, + {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, + {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, + {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, + {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, + {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, + {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, + {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, ] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" +packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -126,13 +131,13 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "blessed" -version = "1.19.1" +version = "1.20.0" description = "Easy, practical library for making terminal apps, by providing an elegant, well-documented interface to Colors, Keyboard input, and screen Positioning capabilities." optional = false python-versions = ">=2.7" files = [ - {file = "blessed-1.19.1-py2.py3-none-any.whl", hash = "sha256:63b8554ae2e0e7f43749b6715c734cc8f3883010a809bf16790102563e6cf25b"}, - {file = "blessed-1.19.1.tar.gz", hash = "sha256:9a0d099695bf621d4680dd6c73f6ad547f6a3442fbdbe80c4b1daa1edbc492fc"}, + {file = "blessed-1.20.0-py2.py3-none-any.whl", hash = "sha256:0c542922586a265e699188e52d5f5ac5ec0dd517e5a1041d90d2bbf23f906058"}, + {file = "blessed-1.20.0.tar.gz", hash = "sha256:2cdd67f8746e048f00df47a2880f4d6acbcdb399031b604e34ba8f71d5787680"}, ] [package.dependencies] @@ -142,13 +147,13 @@ wcwidth = ">=0.1.4" [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] [[package]] @@ -229,110 +234,112 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.0.1" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = "*" +python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"}, - {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] @@ -419,34 +426,34 @@ toml = ["toml"] [[package]] name = "cryptography" -version = "41.0.4" +version = "41.0.7" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"}, - {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"}, - {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"}, - {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"}, - {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"}, - {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"}, - {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"}, + {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"}, + {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"}, + {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"}, + {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"}, + {file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"}, + {file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"}, + {file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"}, ] [package.dependencies] @@ -492,24 +499,24 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] [[package]] name = "docutils" -version = "0.17.1" +version = "0.18.1" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, + {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, + {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] [[package]] name = "exceptiongroup" -version = "1.1.0" +version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, - {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] @@ -537,29 +544,29 @@ pytest = ["pytest (>=7)"] [[package]] name = "flake8" -version = "6.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-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, - {file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, + {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.10.0,<2.11.0" -pyflakes = ">=3.0.0,<3.1.0" +pycodestyle = ">=2.11.0,<2.12.0" +pyflakes = ">=3.1.0,<3.2.0" [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] @@ -575,13 +582,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.0.0" +version = "6.7.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, - {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, + {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, + {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, ] [package.dependencies] @@ -591,7 +598,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "iniconfig" @@ -617,18 +624,18 @@ files = [ [[package]] name = "isort" -version = "5.11.4" +version = "5.11.5" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.7.0" files = [ - {file = "isort-5.11.4-py3-none-any.whl", hash = "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b"}, - {file = "isort-5.11.4.tar.gz", hash = "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6"}, + {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"}, + {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"}, ] [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pipreqs", "requirementslib"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] @@ -651,13 +658,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jinxed" -version = "1.2.0" +version = "1.2.1" description = "Jinxed Terminal Library" optional = false python-versions = "*" files = [ - {file = "jinxed-1.2.0-py2.py3-none-any.whl", hash = "sha256:cfc2b2e4e3b4326954d546ba6d6b9a7a796ddcb0aef8d03161d005177eb0d48b"}, - {file = "jinxed-1.2.0.tar.gz", hash = "sha256:032acda92d5c57cd216033cbbd53de731e6ed50deb63eb4781336ca55f72cda5"}, + {file = "jinxed-1.2.1-py2.py3-none-any.whl", hash = "sha256:37422659c4925969c66148c5e64979f553386a4226b9484d910d3094ced37d30"}, + {file = "jinxed-1.2.1.tar.gz", hash = "sha256:30c3f861b73279fea1ed928cfd4dfb1f273e16cd62c8a32acfac362da0f78f3f"}, ] [package.dependencies] @@ -665,61 +672,71 @@ ansicon = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "markupsafe" -version = "2.1.2" +version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, - {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, + {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]] @@ -735,24 +752,24 @@ files = [ [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] [[package]] name = "packaging" -version = "23.0" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, - {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] @@ -778,42 +795,42 @@ invoke = ["invoke (>=2.0)"] [[package]] name = "pathspec" -version = "0.11.0" +version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.7" files = [ - {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, - {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, ] [[package]] name = "platformdirs" -version = "2.6.2" +version = "4.0.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-4.0.0-py3-none-any.whl", hash = "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b"}, + {file = "platformdirs-4.0.0.tar.gz", hash = "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731"}, ] [package.dependencies] -typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4.7.1", markers = "python_version < \"3.8\""} [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +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.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] [package.dependencies] @@ -825,13 +842,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prompt-toolkit" -version = "3.0.36" +version = "3.0.43" description = "Library for building powerful interactive command lines in Python" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, - {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, ] [package.dependencies] @@ -839,13 +856,13 @@ wcwidth = "*" [[package]] name = "pycodestyle" -version = "2.10.0" +version = "2.11.1" description = "Python style guide checker" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, - {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, + {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, + {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, ] [[package]] @@ -861,28 +878,29 @@ files = [ [[package]] name = "pyflakes" -version = "3.0.1" +version = "3.1.0" description = "passive checker of Python programs" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, - {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, + {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.14.0" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, - {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, + {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 = "pynacl" @@ -912,17 +930,16 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] name = "pytest" -version = "7.2.1" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"}, - {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} @@ -932,7 +949,7 @@ pluggy = ">=0.12,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" @@ -985,13 +1002,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-regressions" -version = "2.4.2" +version = "2.4.3" description = "Easy to use fixtures to write regression tests." optional = false python-versions = ">=3.6" files = [ - {file = "pytest-regressions-2.4.2.tar.gz", hash = "sha256:eab89e7ba4aa339bdfe07b31047e8e6a70b1e7846e74a8bbfc31a588d01e7303"}, - {file = "pytest_regressions-2.4.2-py3-none-any.whl", hash = "sha256:b47f92c39d5dd2faa90716ee74c584d705c08e14f435a947f67706c4e5b8ef9a"}, + {file = "pytest-regressions-2.4.3.tar.gz", hash = "sha256:7238036bbd17c62944bff55d73edb4993eea3f5dbb835c332ec7bc0ddeb027ed"}, + {file = "pytest_regressions-2.4.3-py3-none-any.whl", hash = "sha256:a0fd84e45d2c3b43d2b36157045ebca8b85185d3dc7b014a62b2954a05d8e07d"}, ] [package.dependencies] @@ -1019,64 +1036,88 @@ files = [ [package.dependencies] pytest = ">=3.6.3" +[[package]] +name = "pytest-timeout" +version = "2.2.0" +description = "pytest plugin to abort hanging tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, + {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, +] + +[package.dependencies] +pytest = ">=5.0.0" + [[package]] name = "pytz" -version = "2022.7.1" +version = "2023.3.post1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, - {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, + {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, + {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, ] [[package]] name = "pyyaml" -version = "6.0" +version = "6.0.1" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.6" files = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] @@ -1098,20 +1139,20 @@ docs = ["Sphinx (>=3.3,<4.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphin [[package]] name = "requests" -version = "2.28.2" +version = "2.31.0" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7, <4" +python-versions = ">=3.7" files = [ - {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, - {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] @@ -1176,18 +1217,19 @@ test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] [[package]] name = "sphinx-rtd-theme" -version = "1.1.1" +version = "1.3.0" description = "Read the Docs theme for Sphinx" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "sphinx_rtd_theme-1.1.1-py2.py3-none-any.whl", hash = "sha256:31faa07d3e97c8955637fc3f1423a5ab2c44b74b8cc558a51498c202ce5cbda7"}, - {file = "sphinx_rtd_theme-1.1.1.tar.gz", hash = "sha256:6146c845f1e1947b3c3dd4432c28998a1693ccc742b4f9ad7c63129f0757c103"}, + {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"}, + {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"}, ] [package.dependencies] -docutils = "<0.18" -sphinx = ">=1.6,<6" +docutils = "<0.19" +sphinx = ">=1.6,<8" +sphinxcontrib-jquery = ">=4,<5" [package.extras] dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] @@ -1237,6 +1279,20 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +description = "Extension to include jQuery on newer Sphinx releases" +optional = false +python-versions = ">=2.7" +files = [ + {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, + {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, +] + +[package.dependencies] +Sphinx = ">=1.8" + [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" @@ -1319,35 +1375,52 @@ files = [ [[package]] name = "typed-ast" -version = "1.5.4" +version = "1.5.5" description = "a fork of Python 2 and 3 ast modules with type comment support" optional = false python-versions = ">=3.6" files = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, + {file = "typed_ast-1.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bc1efe0ce3ffb74784e06460f01a223ac1f6ab31c6bc0376a21184bf5aabe3b"}, + {file = "typed_ast-1.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f7a8c46a8b333f71abd61d7ab9255440d4a588f34a21f126bbfc95f6049e686"}, + {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597fc66b4162f959ee6a96b978c0435bd63791e31e4f410622d19f1686d5e769"}, + {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d41b7a686ce653e06c2609075d397ebd5b969d821b9797d029fccd71fdec8e04"}, + {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5fe83a9a44c4ce67c796a1b466c270c1272e176603d5e06f6afbc101a572859d"}, + {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d5c0c112a74c0e5db2c75882a0adf3133adedcdbfd8cf7c9d6ed77365ab90a1d"}, + {file = "typed_ast-1.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:e1a976ed4cc2d71bb073e1b2a250892a6e968ff02aa14c1f40eba4f365ffec02"}, + {file = "typed_ast-1.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c631da9710271cb67b08bd3f3813b7af7f4c69c319b75475436fcab8c3d21bee"}, + {file = "typed_ast-1.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b445c2abfecab89a932b20bd8261488d574591173d07827c1eda32c457358b18"}, + {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc95ffaaab2be3b25eb938779e43f513e0e538a84dd14a5d844b8f2932593d88"}, + {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61443214d9b4c660dcf4b5307f15c12cb30bdfe9588ce6158f4a005baeb167b2"}, + {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6eb936d107e4d474940469e8ec5b380c9b329b5f08b78282d46baeebd3692dc9"}, + {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e48bf27022897577d8479eaed64701ecaf0467182448bd95759883300ca818c8"}, + {file = "typed_ast-1.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:83509f9324011c9a39faaef0922c6f720f9623afe3fe220b6d0b15638247206b"}, + {file = "typed_ast-1.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f214394fc1af23ca6d4e9e744804d890045d1643dd7e8229951e0ef39429b5"}, + {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:118c1ce46ce58fda78503eae14b7664163aa735b620b64b5b725453696f2a35c"}, + {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be4919b808efa61101456e87f2d4c75b228f4e52618621c77f1ddcaae15904fa"}, + {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fc2b8c4e1bc5cd96c1a823a885e6b158f8451cf6f5530e1829390b4d27d0807f"}, + {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:16f7313e0a08c7de57f2998c85e2a69a642e97cb32f87eb65fbfe88381a5e44d"}, + {file = "typed_ast-1.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:2b946ef8c04f77230489f75b4b5a4a6f24c078be4aed241cfabe9cbf4156e7e5"}, + {file = "typed_ast-1.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2188bc33d85951ea4ddad55d2b35598b2709d122c11c75cffd529fbc9965508e"}, + {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0635900d16ae133cab3b26c607586131269f88266954eb04ec31535c9a12ef1e"}, + {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57bfc3cf35a0f2fdf0a88a3044aafaec1d2f24d8ae8cd87c4f58d615fb5b6311"}, + {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fe58ef6a764de7b4b36edfc8592641f56e69b7163bba9f9c8089838ee596bfb2"}, + {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d09d930c2d1d621f717bb217bf1fe2584616febb5138d9b3e8cdd26506c3f6d4"}, + {file = "typed_ast-1.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:d40c10326893ecab8a80a53039164a224984339b2c32a6baf55ecbd5b1df6431"}, + {file = "typed_ast-1.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fd946abf3c31fb50eee07451a6aedbfff912fcd13cf357363f5b4e834cc5e71a"}, + {file = "typed_ast-1.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ed4a1a42df8a3dfb6b40c3d2de109e935949f2f66b19703eafade03173f8f437"}, + {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:045f9930a1550d9352464e5149710d56a2aed23a2ffe78946478f7b5416f1ede"}, + {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381eed9c95484ceef5ced626355fdc0765ab51d8553fec08661dce654a935db4"}, + {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bfd39a41c0ef6f31684daff53befddae608f9daf6957140228a08e51f312d7e6"}, + {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8c524eb3024edcc04e288db9541fe1f438f82d281e591c548903d5b77ad1ddd4"}, + {file = "typed_ast-1.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:7f58fabdde8dcbe764cef5e1a7fcb440f2463c1bbbec1cf2a86ca7bc1f95184b"}, + {file = "typed_ast-1.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:042eb665ff6bf020dd2243307d11ed626306b82812aba21836096d229fdc6a10"}, + {file = "typed_ast-1.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:622e4a006472b05cf6ef7f9f2636edc51bda670b7bbffa18d26b255269d3d814"}, + {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1efebbbf4604ad1283e963e8915daa240cb4bf5067053cf2f0baadc4d4fb51b8"}, + {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0aefdd66f1784c58f65b502b6cf8b121544680456d1cebbd300c2c813899274"}, + {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:48074261a842acf825af1968cd912f6f21357316080ebaca5f19abbb11690c8a"}, + {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:429ae404f69dc94b9361bb62291885894b7c6fb4640d561179548c849f8492ba"}, + {file = "typed_ast-1.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:335f22ccb244da2b5c296e6f96b06ee9bed46526db0de38d2f0e5a6597b81155"}, + {file = "typed_ast-1.5.5.tar.gz", hash = "sha256:94282f7a354f36ef5dbce0ef3467ebf6a258e370ab33d5b40c249fa996e590dd"}, ] [[package]] @@ -1363,131 +1436,127 @@ files = [ [[package]] name = "urllib3" -version = "1.26.14" +version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7" files = [ - {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, - {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.12" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.12-py2.py3-none-any.whl", hash = "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c"}, + {file = "wcwidth-0.2.12.tar.gz", hash = "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02"}, ] [[package]] name = "wrapt" -version = "1.15.0" +version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, - {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, - {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, - {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, - {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, - {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, - {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, - {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, - {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, - {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, - {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, - {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, - {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, - {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, - {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, - {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, - {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, - {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, - {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, ] [[package]] name = "zipp" -version = "3.11.0" +version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.7" files = [ - {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, - {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, + {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, + {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "6a7c6ae677b3a04605131d53031df9036571bb5ebbd87d166445fb7263bcf275" +content-hash = "79a2e67c2001f854824d8c49a2a47d23e97890009a19f361df5d9deba1f6b728" diff --git a/pyproject.toml b/pyproject.toml index 970161f4..f7f61492 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,10 @@ pytest-mock = "^3.11.1" pytest-socket = "^0.6.0" pytest-cov = "^4.1.0" + +[tool.poetry.group.test.dependencies] +pytest-timeout = "^2.1.0" + [tool.isort] multi_line_output = 3 include_trailing_comma = true diff --git a/tests/cli/common.py b/tests/cli/common.py index afa623f5..de8eb31d 100644 --- a/tests/cli/common.py +++ b/tests/cli/common.py @@ -1,5 +1,6 @@ from __future__ import annotations +import functools import inspect import os import sys @@ -7,6 +8,8 @@ from subprocess import CompletedProcess from typing import Any, Callable +import fabric +import paramiko.ssh_exception import pytest from pytest_regressions.file_regression import FileRegressionFixture from typing_extensions import ParamSpec @@ -14,8 +17,34 @@ if typing.TYPE_CHECKING: from typing_extensions import TypeGuard +in_github_CI = all(var in os.environ for var in ["CI", "GITHUB_ACTION", "GITHUB_ENV"]) +"""True if this is being run inside the GitHub CI.""" + +skip_if_on_github_CI = pytest.mark.skipif( + in_github_CI, reason="This test shouldn't run on the Github CI." +) +skip_param_if_on_github_ci = functools.partial(pytest.param, marks=skip_if_on_github_CI) + + +passwordless_ssh_connection_to_localhost_is_setup = False + +try: + _connection = fabric.Connection("localhost") + _connection.open() +except ( + paramiko.ssh_exception.SSHException, + paramiko.ssh_exception.NoValidConnectionsError, +): + pass +else: + passwordless_ssh_connection_to_localhost_is_setup = True + _connection.close() + +requires_ssh_to_localhost = pytest.mark.skipif( + not passwordless_ssh_connection_to_localhost_is_setup, + reason="Test requires a SSH connection to localhost.", +) -P = ParamSpec("P") REQUIRES_S_FLAG_REASON = ( "Seems to require reading from stdin? Works with the -s flag, but other " @@ -32,7 +61,9 @@ reason="Passing pytest's -s flag makes this test fail.", ) on_windows = sys.platform == "win32" -in_github_windows_ci = os.environ.get("PLATFORM") == "windows-latest" +in_github_windows_ci = in_github_CI and os.environ.get("PLATFORM") == "windows-latest" + +P = ParamSpec("P") def xfails_on_windows( diff --git a/tests/cli/test_commands.py b/tests/cli/test_commands.py index 1418fdb0..3b35c085 100644 --- a/tests/cli/test_commands.py +++ b/tests/cli/test_commands.py @@ -1,19 +1,11 @@ import contextlib -import importlib import io import shlex -import subprocess -from subprocess import CompletedProcess -from unittest import mock import pytest -from fabric.testing.fixtures import Connection, MockRemote, remote # noqa -from pytest_mock import MockerFixture from pytest_regressions.file_regression import FileRegressionFixture -from typing_extensions import ParamSpec from milatools.cli.commands import main -from milatools.cli.local import Local from .common import requires_no_s_flag @@ -23,51 +15,6 @@ def _convert_argparse_output_to_pre_py311_format(output: str) -> str: return output.replace("options:\n", "optional arguments:\n") -P = ParamSpec("P") - - -def reload_module(): - """Reload the module after mocking out functions. - - Need to reload the module because we have mocked some of the functions that are used - as default values in the methods of the class under test (e.g. `subprocess.run`). - The functions being in the signature of the methods makes it possible for us to - describe their our method signatures explicitly, but it means that we need to reload - the module after mocking them. - """ - global Local - import milatools.cli.local - - importlib.reload(milatools.cli.local) - Local = milatools.cli.local.Local - - -@pytest.fixture -def mock_subprocess_run(mocker: MockerFixture) -> mock.Mock: - mock_subprocess_run: mock.Mock = mocker.patch("subprocess.run") - # NOTE: Trying out https://stackoverflow.com/questions/25692440/mocking-a-subprocess-call-in-python - - reload_module() - return mock_subprocess_run - - -def test_check_passwordless( - mock_subprocess_run: mock.Mock, -): - # NOTE: Trying out https://stackoverflow.com/questions/25692440/mocking-a-subprocess-call-in-python - mock_subprocess_run.return_value = CompletedProcess(["echo OK"], 0, stdout="BOBOBO") - local = Local() - local.check_passwordless("mila") - - mock_subprocess_run.assert_called_once_with( - tuple(shlex.split("ssh -oPreferredAuthentications=publickey mila 'echo OK'")), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - capture_output=False, - universal_newlines=True, - ) - - @requires_no_s_flag @pytest.mark.parametrize( "command", diff --git a/tests/cli/test_init_command.py b/tests/cli/test_init_command.py index def41b93..2df23f6f 100644 --- a/tests/cli/test_init_command.py +++ b/tests/cli/test_init_command.py @@ -2,31 +2,47 @@ import contextlib import json +import os +import shutil import subprocess import sys import textwrap from functools import partial +from logging import getLogger as get_logger from pathlib import Path from unittest.mock import Mock import pytest +import pytest_mock import questionary from prompt_toolkit.input import PipeInput, create_pipe_input from pytest_regressions.file_regression import FileRegressionFixture from milatools.cli import init_command from milatools.cli.init_command import ( - _get_username, + DRAC_CLUSTERS, + _get_drac_username, + _get_mila_username, _setup_ssh_config_file, create_ssh_keypair, get_windows_home_path_in_wsl, + setup_passwordless_ssh_access, + setup_passwordless_ssh_access_to_cluster, setup_ssh_config, setup_vscode_settings, setup_windows_ssh_config_from_wsl, ) -from milatools.cli.local import Local +from milatools.cli.local import Local, check_passwordless from milatools.cli.utils import SSHConfig, running_inside_WSL -from tests.cli.common import xfails_on_windows + +from .common import ( + in_github_CI, + on_windows, + passwordless_ssh_connection_to_localhost_is_setup, + xfails_on_windows, +) + +logger = get_logger(__name__) def raises_NoConsoleScreenBufferError_on_windows_ci_action(): @@ -52,6 +68,10 @@ def permission_bits_check_doesnt_work_on_windows(): ) +# Set a module-level mark: Each test cannot take longer than 1 second to run. +pytestmark = pytest.mark.timeout(10) + + @pytest.fixture def input_pipe(monkeypatch: pytest.MonkeyPatch, request: pytest.FixtureRequest): """Fixture that creates an input pipe and makes questionary use it. @@ -102,12 +122,27 @@ def _yn(accept: bool): def test_creates_ssh_config_file(tmp_path: Path, input_pipe: PipeInput): ssh_config_path = tmp_path / "ssh_config" - for prompt in ["y", "bob\r", "y", "y", "y", "y", "y"]: + for prompt in [ + "y", + "bob\r", # mila username + "y", # drac? + "bob\r", # drac username + "y", + "y", + "y", + "y", + "y", + ]: input_pipe.send_text(prompt) setup_ssh_config(tmp_path / "ssh_config") assert ssh_config_path.exists() +@pytest.mark.parametrize( + "drac_username", + [None, "bob"], + ids=["no_drac", "drac"], +) @pytest.mark.parametrize( "confirm_changes", [False, True], @@ -155,6 +190,7 @@ def test_creates_ssh_config_file(tmp_path: Path, input_pipe: PipeInput): def test_setup_ssh( initial_contents: str, confirm_changes: bool, + drac_username: str | None, tmp_path: Path, file_regression: FileRegressionFixture, input_pipe: PipeInput, @@ -172,7 +208,10 @@ def test_setup_ssh( f.write(initial_contents) user_inputs = [ - "bob\r", # username + "bob\r", # username on Mila cluster + *( # DRAC account? + enter username + ["n"] if drac_username is None else ["y", drac_username + "\r"] + ), _yn(confirm_changes), ] for prompt in user_inputs: @@ -235,7 +274,12 @@ def test_fixes_overly_general_entry( f.write(initial_contents) # Enter username, accept fixing that entry, then confirm. - for user_input in ["bob\r", "y", "y"]: + for user_input in [ + "bob\r", # mila username + "n", # DRAC account? + "y", + "y", + ]: input_pipe.send_text(user_input) setup_ssh_config(ssh_config_path=ssh_config_path) @@ -278,6 +322,9 @@ def test_ssh_config_host(tmp_path: Path): } +@pytest.mark.parametrize( + "already_has_drac", [True, False], ids=["has_drac_entries", "no_drac_entries"] +) @pytest.mark.parametrize( "already_has_mila", [True, False], ids=["has_mila_entry", "no_mila_entry"] ) @@ -295,15 +342,17 @@ def test_with_existing_entries( already_has_mila: bool, already_has_mila_cpu: bool, already_has_mila_compute: bool, + already_has_drac: bool, file_regression: FileRegressionFixture, tmp_path: Path, input_pipe: PipeInput, ): + user = "bob" existing_mila = textwrap.dedent( - """\ + f"""\ Host mila HostName login.server.mila.quebec - User bob + User {user} """ ) existing_mila_cpu = textwrap.dedent( @@ -318,11 +367,38 @@ def test_with_existing_entries( HostName foooobar.com """ ) + existing_drac = textwrap.dedent( + f""" + # Compute Canada + Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User {user} + Host mist + Hostname mist.scinet.utoronto.ca + User {user} + Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User {user} + Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User {user} + Host !graham gra??? gra???? + ProxyJump graham + User {user} + Host !narval nc????? ng????? + ProxyJump narval + User {user} + Host !niagara nia???? + ProxyJump niagara + User {user} + """ + ) initial_blocks = [] initial_blocks += [existing_mila] if already_has_mila else [] initial_blocks += [existing_mila_cpu] if already_has_mila_cpu else [] initial_blocks += [existing_mila_compute] if already_has_mila_compute else [] + initial_blocks += [existing_drac] if already_has_drac else [] initial_contents = _join_blocks(*initial_blocks) # TODO: Need to insert the entries in the right place, in the right order! @@ -346,11 +422,13 @@ def test_with_existing_entries( " ControlPersist 600", ] ) + if not all( [ already_has_mila and controlmaster_block in existing_mila, already_has_mila_cpu, already_has_mila_compute and controlmaster_block in existing_mila_compute, + already_has_drac, ] ): # There's a confirmation prompt only if we're adding some entry. @@ -358,7 +436,10 @@ def test_with_existing_entries( else: confirm_inputs = [] - prompt_inputs = username_input + confirm_inputs + drac_username_inputs = [] + if not already_has_drac: + drac_username_inputs = ["y", f"{user}\r"] + prompt_inputs = username_input + drac_username_inputs + confirm_inputs for prompt_input in prompt_inputs: input_pipe.send_text(prompt_input) @@ -484,7 +565,103 @@ def test_get_username( input_pipe.close() for prompt_input in prompt_inputs: input_pipe.send_text(prompt_input) - assert _get_username(ssh_config) == expected + assert _get_mila_username(ssh_config) == expected + + +@pytest.mark.parametrize( + ("contents", "prompt_inputs", "expected"), + [ + pytest.param( + "", # empty file. + ["n"], # No I don't have a DRAC account. + None, # get None as a result + id="no_drac_account", + ), + pytest.param( + "", # empty file. + ["y", "bob\r"], # enter yes, then "bob" then enter. + "bob", # get "bob" as username. + id="empty_file", + ), + pytest.param( + textwrap.dedent( + """\ + Host narval + HostName narval.computecanada.ca + User bob + """ + ), + [], + "bob", + id="existing_drac_entry", + ), + pytest.param( + textwrap.dedent( + """\ + Host beluga cedar graham narval niagara + HostName %h.computecanada.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + """ + ), + ["y", "bob\r"], # Yes I have a username on the drac clusters, and it's bob. + "bob", + id="entry_without_user", + ), + pytest.param( + textwrap.dedent( + """\ + Host beluga cedar graham narval niagara + HostName login.server.mila.quebec + User george + # duplicate entry + Host beluga cedar graham narval niagara other_cluster + User Bob + """ + ), + ["y", "bob\r"], + "bob", + id="two_matching_entries", + ), + pytest.param( + textwrap.dedent( + """\ + Host fooo beluga bar baz + HostName beluga.alliancecan.ca + User george + """ + ), + [], + "george", + id="with_aliases", + ), + pytest.param( + "", + # Yes (by pressing just enter), then an invalid username (space), then a + # real username. + ["\r", " \r", "bob\r"], + "bob", + id="empty_username", + ), + ], +) +def test_get_drac_username( + contents: str, + prompt_inputs: list[str], + expected: str | None, + input_pipe: PipeInput, + tmp_path: Path, +): + ssh_config_path = tmp_path / "config" + with open(ssh_config_path, "w") as f: + f.write(contents) + ssh_config = SSHConfig(ssh_config_path) + if not prompt_inputs: + input_pipe.close() + for prompt_input in prompt_inputs: + input_pipe.send_text(prompt_input) + assert _get_drac_username(ssh_config) == expected class TestSetupSshFile: @@ -549,7 +726,8 @@ def test_fixes_dir_permission_issues( assert file.stat().st_mode & 0o777 == 0o600 -@permission_bits_check_doesnt_work_on_windows() +# takes a little longer in the CI runner (Windows in particular) +@pytest.mark.timeout(10) def test_create_ssh_keypair(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): here = Local() mock_run = Mock( @@ -559,19 +737,17 @@ def test_create_ssh_keypair(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): fake_ssh_folder = tmp_path / "fake_ssh" fake_ssh_folder.mkdir(mode=0o700) ssh_private_key_path = fake_ssh_folder / "bob" + create_ssh_keypair(ssh_private_key_path=ssh_private_key_path, local=here) - mock_run.assert_called_once_with( - ("ssh-keygen", "-f", str(ssh_private_key_path), "-t", "rsa", "-N=''"), - universal_newlines=True, - capture_output=False, - stderr=None, - stdout=None, - ) + + mock_run.assert_called_once() assert ssh_private_key_path.exists() - assert ssh_private_key_path.stat().st_mode & 0o777 == 0o600 + if not on_windows: + assert ssh_private_key_path.stat().st_mode & 0o777 == 0o600 ssh_public_key_path = ssh_private_key_path.with_suffix(".pub") assert ssh_public_key_path.exists() - assert ssh_public_key_path.stat().st_mode & 0o777 == 0o644 + if not on_windows: + assert ssh_public_key_path.stat().st_mode & 0o777 == 0o644 @pytest.fixture @@ -582,7 +758,13 @@ def linux_ssh_config( # Enter username, accept fixing that entry, then confirm. ssh_config_path = tmp_path / "ssh_config" - for prompt in ["y", "bob\r", "y"]: + for prompt in [ + "y", # Create an ssh config file? + "bob\r", # What's your username on the Mila cluster? + "y", # Do you also have a DRAC account? + "bob\r", # username on DRAC + "y", # accept adding the entries in the ssh config + ]: input_pipe.send_text(prompt) if sys.platform.startswith("win"): @@ -803,3 +985,270 @@ def test_setup_windows_ssh_config_from_wsl_copies_keys( assert windows_private_key_path.read_text() == private_key_text assert windows_public_key_path.exists() assert windows_public_key_path.read_text() == public_key_text + + +BACKUP_SSH_DIR = Path.home() / ".ssh_backup" +USE_MY_REAL_SSH_DIR = os.environ.get("USE_MY_REAL_SSH_DIR", "0") == "1" +"""Set this to `True` for the tests below to actually use your real SSH directory. + +A backup is saved in `BACKUP_SSH_DIR`. +""" + + +@pytest.fixture +def backup_ssh_dir(): + """Creates a backup of the SSH config files.""" + import shutil + + assert in_github_CI or USE_MY_REAL_SSH_DIR + + ssh_dir = Path.home() / ".ssh" + backup_ssh_dir = BACKUP_SSH_DIR + + ssh_dir_existed_before = ssh_dir.exists() + + def _ignore_sockets_dir(src: str, names: list[str]) -> list[str]: + return names if Path(src).name == "sockets" else [] + + if ssh_dir_existed_before: + logger.warning(f"Backing up {ssh_dir} to {backup_ssh_dir}") + if backup_ssh_dir.exists(): + shutil.rmtree(backup_ssh_dir) + shutil.copytree(ssh_dir, backup_ssh_dir, ignore=_ignore_sockets_dir) + else: + logger.warning(f"Test might temporarily create files in a new {ssh_dir} dir.") + + yield backup_ssh_dir + + if ssh_dir_existed_before: + logger.warning(f"Restoring {ssh_dir} from backup at {backup_ssh_dir}") + if ssh_dir.exists(): + shutil.rmtree(ssh_dir) + shutil.copytree(backup_ssh_dir, ssh_dir) + shutil.rmtree(backup_ssh_dir) + else: + logger.warning(f"Removing temporarily generated sshdir at {ssh_dir}.") + if ssh_dir.exists(): + shutil.rmtree(ssh_dir) + + +@pytest.mark.skipif( + not ( + (in_github_CI or USE_MY_REAL_SSH_DIR) + and passwordless_ssh_connection_to_localhost_is_setup + ), + reason=( + "It's a bit risky to actually change the SSH config directory on a dev " + "machine. Only doing it in the CI or if the USE_MY_REAL_SSH_DIR env var is set." + ), +) +@pytest.mark.timeout(20) +@pytest.mark.parametrize( + "passwordless_to_cluster_is_already_setup", + [True, False], + ids=["already_setup", "not_already_setup"], +) +@pytest.mark.parametrize( + "user_accepts_registering_key", + [True, False], + ids=["accept_registering_key", "reject_registering_key"], +) +def test_setup_passwordless_ssh_access_to_cluster( + input_pipe: PipeInput, + backup_ssh_dir: Path, + mocker: pytest_mock.MockerFixture, + passwordless_to_cluster_is_already_setup: bool, + user_accepts_registering_key: bool, +): + """Test the function that sets up passwordless SSH to a cluster (localhost in tests) + + NOTE: Running this test will make a backup of the ~/.ssh directory in + `backup_ssh_dir` (~/.ssh_backup), and restore it after the test. + For that reason, it currently only runs in the GitHub CI, unless you specifically + set the `USE_MY_REAL_SSH_DIR` env variable to '1'. + """ + assert passwordless_ssh_connection_to_localhost_is_setup + assert in_github_CI or USE_MY_REAL_SSH_DIR + + ssh_dir = Path.home() / ".ssh" + authorized_keys_file = ssh_dir / "authorized_keys" + backup_authorized_keys_file = backup_ssh_dir / "authorized_keys" + assert backup_authorized_keys_file.exists() + + if not passwordless_to_cluster_is_already_setup: + if authorized_keys_file.exists(): + logger.warning( + f"Temporarily removing {authorized_keys_file}. " + f"(A backup is available at {backup_authorized_keys_file})" + ) + authorized_keys_file.unlink() + + input_pipe.send_text("y" if user_accepts_registering_key else "n") + + assert not check_passwordless("localhost") + else: + assert check_passwordless("localhost") + + logger.info(backup_authorized_keys_file.read_text()) + + def _mock_subprocess_run(command: tuple[str], *args, **kwargs): + """Mock of the ssh-copy-id command. + + Copies the `authorized_keys` file from the backup to the (temporarily cleared) + .ssh directory. + """ + logger.debug(f"Running: {command} {args} {kwargs}") + if sys.platform == "linux": + assert command[0] == "ssh-copy-id" + ssh_dir.mkdir(exist_ok=True, mode=0o700) + shutil.copy(backup_authorized_keys_file, authorized_keys_file) + return subprocess.CompletedProcess(command, 0, "", "") + + mock_subprocess_run = mocker.patch("subprocess.run", wraps=_mock_subprocess_run) + + success = setup_passwordless_ssh_access_to_cluster("localhost") + + if passwordless_to_cluster_is_already_setup: + mock_subprocess_run.assert_not_called() + assert success is True + elif user_accepts_registering_key: + mock_subprocess_run.assert_called_once() + assert success is True + else: + mock_subprocess_run.assert_not_called() + assert success is False + + +@pytest.mark.timeout(10) +@pytest.mark.skipif( + not (in_github_CI or USE_MY_REAL_SSH_DIR), + reason=( + "It's a bit risky to actually change the SSH config directory on a dev " + "machine. Only doing it in the CI or if the USE_MY_REAL_SSH_DIR env var is set." + ), +) +@pytest.mark.parametrize( + "drac_clusters_in_ssh_config", + [[]] + [DRAC_CLUSTERS[i:] for i in range(len(DRAC_CLUSTERS))], +) +@pytest.mark.parametrize( + "accept_generating_key", + [True, False], + ids=["accept_generate_key", "accept_generate_key"], +) +@pytest.mark.parametrize( + "public_key_exists", + [True, False], + ids=["key_exists", "no_key"], +) +@pytest.mark.parametrize( + "accept_mila", [True, False], ids=["accept_mila", "reject_mila"] +) +@pytest.mark.parametrize( + "accept_drac", [True, False], ids=["accept_drac", "reject_drac"] +) +def test_setup_passwordless_ssh_access( + accept_generating_key: bool, + public_key_exists: bool, + accept_mila: bool, + accept_drac: bool, + drac_clusters_in_ssh_config: list[str], + # capsys: pytest.CaptureFixture, + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, + backup_ssh_dir: Path, + input_pipe: PipeInput, +): + assert in_github_CI or USE_MY_REAL_SSH_DIR + ssh_dir = Path.home() / ".ssh" + if ssh_dir.exists(): + logger.warning( + f"Temporarily deleting the ssh dir (backed up at {backup_ssh_dir})" + ) + shutil.rmtree(ssh_dir) + + if not public_key_exists: + # There should be no ssh keys in the ssh dir before calling the function. + # We should get a prompt asking if we want to generate a key. + input_pipe.send_text("y" if accept_generating_key else "n") + else: + # There should be an ssh key in the .ssh dir. + # Won't ask to generate a key. + create_ssh_keypair( + ssh_private_key_path=ssh_dir / "id_rsa_milatools", local=Local() + ) + if drac_clusters_in_ssh_config: + # We should get a promtp asking if we want or not to register the public key + # on the DRAC clusters. + input_pipe.send_text("y" if accept_drac else "n") + + # Pre-populate the ssh config file. + ssh_config_path = tmp_path / "ssh_config" + ssh_config_path.write_text( + textwrap.dedent( + f"""\ + Host {' '.join(drac_clusters_in_ssh_config)} + Hostname %h.computecanada.ca + User bob + """ + ) + if drac_clusters_in_ssh_config + else "" + ) + ssh_config = SSHConfig(path=ssh_config_path) + + # We mock the main function used by the `setup_passwordless_ssh_access` function. + # It's okay because we have a good test for it above. Therefore we just test how it + # gets called here. + mock_setup_passwordless_ssh_access_to_cluster = Mock( + spec=setup_passwordless_ssh_access_to_cluster, + side_effect=[accept_mila, *(accept_drac for _ in drac_clusters_in_ssh_config)], + ) + import milatools.cli.init_command + + monkeypatch.setattr( + milatools.cli.init_command, + setup_passwordless_ssh_access_to_cluster.__name__, + mock_setup_passwordless_ssh_access_to_cluster, + ) + + result = setup_passwordless_ssh_access(ssh_config) + + if not public_key_exists: + if accept_generating_key: + assert ssh_dir.exists() + assert ssh_dir.stat().st_mode & 0o777 == 0o700 + assert (ssh_dir / "id_rsa").exists() + assert (ssh_dir / "id_rsa").stat().st_mode & 0o777 == 0o600 + assert (ssh_dir / "id_rsa.pub").exists() + else: + assert not (ssh_dir / "id_rsa").exists() + assert not (ssh_dir / "id_rsa.pub").exists() + assert not result + mock_setup_passwordless_ssh_access_to_cluster.assert_not_called() + return + + mock_setup_passwordless_ssh_access_to_cluster.assert_any_call("mila") + if not accept_mila: + mock_setup_passwordless_ssh_access_to_cluster.assert_called_once_with("mila") + assert result is False + return + + # If we accept to setup passwordless SSH access to the Mila cluster, we go on + # to ask for DRAC clusters. + if not drac_clusters_in_ssh_config: + assert result is True + mock_setup_passwordless_ssh_access_to_cluster.assert_called_once_with("mila") + return + + # If there were DRAC clusters in the SSH config, then the fn is called for each + # cluster, unless the user rejects setting up passwordless SSH access to one of the + # clusters, in which case there's an early return False. + if not accept_drac: + assert len(mock_setup_passwordless_ssh_access_to_cluster.mock_calls) == 2 + assert result is False + return + + for drac_cluster in drac_clusters_in_ssh_config: + mock_setup_passwordless_ssh_access_to_cluster.assert_any_call(drac_cluster) + assert result is True diff --git a/tests/cli/test_init_command/test_fixes_overly_general_entry.txt b/tests/cli/test_init_command/test_fixes_overly_general_entry.txt index 484af2d5..4f565d16 100644 --- a/tests/cli/test_init_command/test_fixes_overly_general_entry.txt +++ b/tests/cli/test_init_command/test_fixes_overly_general_entry.txt @@ -1,9 +1,6 @@ -Host *.server.mila.quebec !*login.server.mila.quebec - User bob Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -11,9 +8,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -23,4 +20,13 @@ Host mila-cpu ConnectTimeout 600 ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" - RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu \ No newline at end of file + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob \ No newline at end of file diff --git a/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_drac_.md new file mode 100644 index 00000000..a4619edd --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_drac_.md @@ -0,0 +1,66 @@ +Running the `mila init` command with no initial ssh config file + +and these user inputs: ('bob\r', 'y', 'bob\r', 'y') +leads the following ssh config file: + +``` + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_.md b/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_no_drac_.md similarity index 92% rename from tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_no_drac_.md index ee5e220a..9ecbdaf1 100644 --- a/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_empty_confirm_changes_no_drac_.md @@ -1,13 +1,12 @@ Running the `mila init` command with no initial ssh config file -and these user inputs: ('bob\r', 'y') +and these user inputs: ('bob\r', 'n', 'y') leads the following ssh config file: ``` Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -15,9 +14,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -28,14 +27,13 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_drac_.md new file mode 100644 index 00000000..dc3ada1c --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_drac_.md @@ -0,0 +1,8 @@ +Running the `mila init` command with no initial ssh config file + +and these user inputs: ('bob\r', 'y', 'bob\r', 'n') +leads the following ssh config file: + +``` + +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_.md b/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_no_drac_.md similarity index 72% rename from tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_no_drac_.md index cb6aeede..06596331 100644 --- a/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_empty_reject_changes_no_drac_.md @@ -1,6 +1,6 @@ Running the `mila init` command with no initial ssh config file -and these user inputs: ('bob\r', 'n') +and these user inputs: ('bob\r', 'n', 'n') leads the following ssh config file: ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_drac_.md new file mode 100644 index 00000000..b2593767 --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_drac_.md @@ -0,0 +1,80 @@ +Running the `mila init` command with this initial content: + +``` +# a comment +Host foo + HostName foobar.com + +# another comment + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'y') +leads the following ssh config file: + +``` +# a comment +Host foo + HostName foobar.com + +# another comment + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_no_drac_.md similarity index 93% rename from tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_no_drac_.md index dcb3db48..b89c1401 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_confirm_changes_no_drac_.md @@ -9,7 +9,7 @@ Host foo ``` -and these user inputs: ('bob\r', 'y') +and these user inputs: ('bob\r', 'n', 'y') leads the following ssh config file: ``` @@ -21,7 +21,6 @@ Host foo Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -29,9 +28,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -42,14 +41,13 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_drac_.md new file mode 100644 index 00000000..44334113 --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_drac_.md @@ -0,0 +1,22 @@ +Running the `mila init` command with this initial content: + +``` +# a comment +Host foo + HostName foobar.com + +# another comment + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'n') +leads the following ssh config file: + +``` +# a comment +Host foo + HostName foobar.com + +# another comment + +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_no_drac_.md similarity index 84% rename from tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_no_drac_.md index 1ba16f4f..4db55afd 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_reject_changes_no_drac_.md @@ -9,7 +9,7 @@ Host foo ``` -and these user inputs: ('bob\r', 'n') +and these user inputs: ('bob\r', 'n', 'n') leads the following ssh config file: ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_drac_.md new file mode 100644 index 00000000..594f817d --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_drac_.md @@ -0,0 +1,88 @@ +Running the `mila init` command with this initial content: + +``` +# a comment + +Host foo + HostName foobar.com + + + + +# another comment after lots of empty lines. + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'y') +leads the following ssh config file: + +``` +# a comment + +Host foo + HostName foobar.com + + + + +# another comment after lots of empty lines. + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_no_drac_.md similarity index 93% rename from tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_no_drac_.md index c75603fa..ce4cf361 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_confirm_changes_no_drac_.md @@ -13,7 +13,7 @@ Host foo ``` -and these user inputs: ('bob\r', 'y') +and these user inputs: ('bob\r', 'n', 'y') leads the following ssh config file: ``` @@ -29,7 +29,6 @@ Host foo Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -37,9 +36,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -50,14 +49,13 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_drac_.md new file mode 100644 index 00000000..2239f984 --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_drac_.md @@ -0,0 +1,30 @@ +Running the `mila init` command with this initial content: + +``` +# a comment + +Host foo + HostName foobar.com + + + + +# another comment after lots of empty lines. + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'n') +leads the following ssh config file: + +``` +# a comment + +Host foo + HostName foobar.com + + + + +# another comment after lots of empty lines. + +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_no_drac_.md similarity index 87% rename from tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_no_drac_.md index 1436b7b2..3b82c33d 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_and_entry_with_extra_space_reject_changes_no_drac_.md @@ -13,7 +13,7 @@ Host foo ``` -and these user inputs: ('bob\r', 'n') +and these user inputs: ('bob\r', 'n', 'n') leads the following ssh config file: ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_drac_.md new file mode 100644 index 00000000..c77e8d84 --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_drac_.md @@ -0,0 +1,72 @@ +Running the `mila init` command with this initial content: + +``` +# A comment in the file. + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'y') +leads the following ssh config file: + +``` +# A comment in the file. + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_no_drac_.md similarity index 92% rename from tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_no_drac_.md index 38126088..f9384480 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_confirm_changes_no_drac_.md @@ -5,7 +5,7 @@ Running the `mila init` command with this initial content: ``` -and these user inputs: ('bob\r', 'y') +and these user inputs: ('bob\r', 'n', 'y') leads the following ssh config file: ``` @@ -13,7 +13,6 @@ leads the following ssh config file: Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -21,9 +20,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -34,14 +33,13 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_drac_.md new file mode 100644 index 00000000..78f78257 --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_drac_.md @@ -0,0 +1,14 @@ +Running the `mila init` command with this initial content: + +``` +# A comment in the file. + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'n') +leads the following ssh config file: + +``` +# A comment in the file. + +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_no_drac_.md similarity index 79% rename from tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_no_drac_.md index 90f6ca32..a817aff5 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_comment_reject_changes_no_drac_.md @@ -5,7 +5,7 @@ Running the `mila init` command with this initial content: ``` -and these user inputs: ('bob\r', 'n') +and these user inputs: ('bob\r', 'n', 'n') leads the following ssh config file: ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_drac_.md new file mode 100644 index 00000000..0e23643d --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_drac_.md @@ -0,0 +1,76 @@ +Running the `mila init` command with this initial content: + +``` +# a comment +Host foo + HostName foobar.com + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'y') +leads the following ssh config file: + +``` +# a comment +Host foo + HostName foobar.com + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_no_drac_.md similarity index 93% rename from tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_no_drac_.md index 172838bf..2d57c530 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_confirm_changes_no_drac_.md @@ -7,7 +7,7 @@ Host foo ``` -and these user inputs: ('bob\r', 'y') +and these user inputs: ('bob\r', 'n', 'y') leads the following ssh config file: ``` @@ -17,7 +17,6 @@ Host foo Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -25,9 +24,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -38,14 +37,13 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob ``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_drac_.md b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_drac_.md new file mode 100644 index 00000000..fd72a52e --- /dev/null +++ b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_drac_.md @@ -0,0 +1,18 @@ +Running the `mila init` command with this initial content: + +``` +# a comment +Host foo + HostName foobar.com + +``` + +and these user inputs: ('bob\r', 'y', 'bob\r', 'n') +leads the following ssh config file: + +``` +# a comment +Host foo + HostName foobar.com + +``` diff --git a/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_.md b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_no_drac_.md similarity index 82% rename from tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_.md rename to tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_no_drac_.md index a3304653..87835e84 100644 --- a/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_.md +++ b/tests/cli/test_init_command/test_setup_ssh_has_different_indent_reject_changes_no_drac_.md @@ -7,7 +7,7 @@ Host foo ``` -and these user inputs: ('bob\r', 'n') +and these user inputs: ('bob\r', 'n', 'n') leads the following ssh config file: ``` diff --git a/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_accept_.md b/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_accept_.md index d3ea3206..54f7c442 100644 --- a/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_accept_.md +++ b/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_accept_.md @@ -3,7 +3,6 @@ When this SSH config is already present in the WSL environment with these initia Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -11,9 +10,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -24,16 +23,42 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` @@ -44,14 +69,13 @@ leads the following ssh config file on the Windows side: Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 ServerAliveCountMax 5 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -62,11 +86,34 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" remotecommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_reject_.md b/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_reject_.md index 5aeff916..3610147c 100644 --- a/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_reject_.md +++ b/tests/cli/test_init_command/test_setup_windows_ssh_config_from_wsl_reject_.md @@ -3,7 +3,6 @@ When this SSH config is already present in the WSL environment with these initia Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -11,9 +10,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -24,16 +23,42 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..a26dc74f --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_has_drac_entries_.md @@ -0,0 +1,103 @@ +Running the `mila init` command with this initial content: + +``` +Host mila + HostName login.server.mila.quebec + User bob + +Host mila-cpu + HostName login.server.mila.quebec + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName foooobar.com + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['y'] +leads to the following ssh config file: + +``` +Host mila + HostName login.server.mila.quebec + User bob + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + +Host mila-cpu + HostName login.server.mila.quebec + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_no_drac_entries_.md similarity index 69% rename from tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_no_drac_entries_.md index 2cb93738..c1188c05 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_no_drac_entries_.md @@ -13,7 +13,7 @@ Host *.server.mila.quebec !*login.server.mila.quebec ``` -and these user inputs: ['y'] +and these user inputs: ['y', 'bob\r', 'y'] leads to the following ssh config file: ``` @@ -30,7 +30,6 @@ Host mila Host mila-cpu HostName login.server.mila.quebec - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -41,14 +40,40 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..daff7a18 --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_has_drac_entries_.md @@ -0,0 +1,99 @@ +Running the `mila init` command with this initial content: + +``` +Host mila-cpu + HostName login.server.mila.quebec + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName foooobar.com + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['bob\r', 'y'] +leads to the following ssh config file: + +``` +Host mila-cpu + HostName login.server.mila.quebec + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_no_drac_entries_.md similarity index 67% rename from tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_no_drac_entries_.md index 1c719ef2..265a0168 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_no_drac_entries_.md @@ -9,13 +9,12 @@ Host *.server.mila.quebec !*login.server.mila.quebec ``` -and these user inputs: ['bob\r', 'y'] +and these user inputs: ['bob\r', 'y', 'bob\r', 'y'] leads to the following ssh config file: ``` Host mila-cpu HostName login.server.mila.quebec - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -26,20 +25,18 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -47,4 +44,32 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..c1c922a0 --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_has_drac_entries_.md @@ -0,0 +1,99 @@ +Running the `mila init` command with this initial content: + +``` +Host mila + HostName login.server.mila.quebec + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName foooobar.com + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['y'] +leads to the following ssh config file: + +``` +Host mila + HostName login.server.mila.quebec + User bob + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_no_drac_entries_.md similarity index 67% rename from tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_no_drac_entries_.md index 1d510711..2b2687b2 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_no_drac_entries_.md @@ -10,7 +10,7 @@ Host *.server.mila.quebec !*login.server.mila.quebec ``` -and these user inputs: ['y'] +and these user inputs: ['y', 'bob\r', 'y'] leads to the following ssh config file: ``` @@ -27,16 +27,13 @@ Host mila Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -47,4 +44,32 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..cd884b01 --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_has_drac_entries_.md @@ -0,0 +1,95 @@ +Running the `mila init` command with this initial content: + +``` +Host *.server.mila.quebec !*login.server.mila.quebec + HostName foooobar.com + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['bob\r', 'y'] +leads to the following ssh config file: + +``` +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_no_drac_entries_.md similarity index 65% rename from tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_no_drac_entries_.md index 64b6bd4e..1be98519 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_has_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_no_drac_entries_.md @@ -6,23 +6,20 @@ Host *.server.mila.quebec !*login.server.mila.quebec ``` -and these user inputs: ['bob\r', 'y'] +and these user inputs: ['bob\r', 'y', 'bob\r', 'y'] leads to the following ssh config file: ``` Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -30,9 +27,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -43,4 +40,32 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..5ee14c97 --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_has_drac_entries_.md @@ -0,0 +1,100 @@ +Running the `mila init` command with this initial content: + +``` +Host mila + HostName login.server.mila.quebec + User bob + +Host mila-cpu + HostName login.server.mila.quebec + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['y'] +leads to the following ssh config file: + +``` +Host mila + HostName login.server.mila.quebec + User bob + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + +Host mila-cpu + HostName login.server.mila.quebec + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_no_drac_entries_.md similarity index 67% rename from tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_no_drac_entries_.md index 9a20d5dc..7ba79693 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_has_mila_entry_no_drac_entries_.md @@ -10,7 +10,7 @@ Host mila-cpu ``` -and these user inputs: ['y'] +and these user inputs: ['y', 'bob\r', 'y'] leads to the following ssh config file: ``` @@ -27,7 +27,6 @@ Host mila Host mila-cpu HostName login.server.mila.quebec - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -38,14 +37,40 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..bda623a4 --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_has_drac_entries_.md @@ -0,0 +1,96 @@ +Running the `mila init` command with this initial content: + +``` +Host mila-cpu + HostName login.server.mila.quebec + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['bob\r', 'y'] +leads to the following ssh config file: + +``` +Host mila-cpu + HostName login.server.mila.quebec + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_no_drac_entries_.md similarity index 65% rename from tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_no_drac_entries_.md index 24155517..e22c7afa 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_has_mila_cpu_entry_no_mila_entry_no_drac_entries_.md @@ -6,13 +6,12 @@ Host mila-cpu ``` -and these user inputs: ['bob\r', 'y'] +and these user inputs: ['bob\r', 'y', 'bob\r', 'y'] leads to the following ssh config file: ``` Host mila-cpu HostName login.server.mila.quebec - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -23,10 +22,10 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -34,14 +33,40 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..91dfc64f --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_has_drac_entries_.md @@ -0,0 +1,96 @@ +Running the `mila init` command with this initial content: + +``` +Host mila + HostName login.server.mila.quebec + User bob + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['y'] +leads to the following ssh config file: + +``` +Host mila + HostName login.server.mila.quebec + User bob + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_no_drac_entries_.md similarity index 65% rename from tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_no_drac_entries_.md index d015cf55..f15a1393 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_has_mila_entry_no_drac_entries_.md @@ -7,7 +7,7 @@ Host mila ``` -and these user inputs: ['y'] +and these user inputs: ['y', 'bob\r', 'y'] leads to the following ssh config file: ``` @@ -23,7 +23,6 @@ Host mila ControlPersist 600 Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -34,14 +33,40 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_has_drac_entries_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_has_drac_entries_.md new file mode 100644 index 00000000..795c0373 --- /dev/null +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_has_drac_entries_.md @@ -0,0 +1,92 @@ +Running the `mila init` command with this initial content: + +``` + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +``` + +and these user inputs: ['bob\r', 'y'] +leads to the following ssh config file: + +``` + +# Compute Canada +Host beluga cedar graham narval niagara + Hostname %h.alliancecan.ca + User bob + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 +Host mist + Hostname mist.scinet.utoronto.ca + User bob +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob +Host !graham gra??? gra???? + ProxyJump graham + User bob +Host !narval nc????? ng????? + ProxyJump narval + User bob +Host !niagara nia???? + ProxyJump niagara + User bob + +Host mila + HostName login.server.mila.quebec + PreferredAuthentications publickey,keyboard-interactive + Port 2222 + ServerAliveInterval 120 + ServerAliveCountMax 5 + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host mila-cpu + Port 2222 + ForwardAgent yes + StrictHostKeyChecking no + LogLevel ERROR + UserKnownHostsFile /dev/null + RequestTTY force + ConnectTimeout 600 + ServerAliveInterval 120 + ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" + RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob + +Host *.server.mila.quebec !*login.server.mila.quebec + HostName %h + ProxyJump mila + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob +``` \ No newline at end of file diff --git a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_.md b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_no_drac_entries_.md similarity index 63% rename from tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_.md rename to tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_no_drac_entries_.md index 1f20cd11..bf9a28c4 100644 --- a/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_.md +++ b/tests/cli/test_init_command/test_with_existing_entries_no_mila_compute_entry_no_mila_cpu_entry_no_mila_entry_no_drac_entries_.md @@ -1,13 +1,12 @@ Running the `mila init` command with no initial ssh config file -and these user inputs: ['bob\r', 'y'] +and these user inputs: ['bob\r', 'y', 'bob\r', 'y'] leads to the following ssh config file: ``` Host mila HostName login.server.mila.quebec - User bob PreferredAuthentications publickey,keyboard-interactive Port 2222 ServerAliveInterval 120 @@ -15,9 +14,9 @@ Host mila ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob Host mila-cpu - User bob Port 2222 ForwardAgent yes StrictHostKeyChecking no @@ -28,14 +27,40 @@ Host mila-cpu ServerAliveInterval 120 ProxyCommand ssh mila "/cvmfs/config.mila.quebec/scripts/milatools/slurm-proxy.sh mila-cpu --mem=8G" RemoteCommand /cvmfs/config.mila.quebec/scripts/milatools/entrypoint.sh mila-cpu + User bob Host *.server.mila.quebec !*login.server.mila.quebec HostName %h - User bob ProxyJump mila - ForwardAgent yes - ForwardX11 yes ControlMaster auto ControlPath ~/.cache/ssh/%r@%h:%p ControlPersist 600 + User bob + +Host beluga cedar graham narval niagara + HostName %h.alliancecan.ca + ControlMaster auto + ControlPath ~/.cache/ssh/%r@%h:%p + ControlPersist 600 + User bob + +Host !beluga bc????? bg????? bl????? + ProxyJump beluga + User bob + +Host !cedar cdr? cdr?? cdr??? cdr???? + ProxyJump cedar + User bob + +Host !graham gra??? gra???? + ProxyJump graham + User bob + +Host !narval nc????? ng????? + ProxyJump narval + User bob + +Host !niagara nia???? + ProxyJump niagara + User bob ``` \ No newline at end of file diff --git a/tests/cli/test_local.py b/tests/cli/test_local.py index 854be276..783f74de 100644 --- a/tests/cli/test_local.py +++ b/tests/cli/test_local.py @@ -1,14 +1,19 @@ from __future__ import annotations -import sys from subprocess import PIPE import pytest from pytest_regressions.file_regression import FileRegressionFixture -from milatools.cli.local import CommandNotFoundError, Local +from milatools.cli.local import CommandNotFoundError, Local, check_passwordless -from .common import output_tester, requires_no_s_flag, xfails_on_windows +from .common import ( + output_tester, + passwordless_ssh_connection_to_localhost_is_setup, + requires_no_s_flag, + skip_param_if_on_github_ci, + xfails_on_windows, +) _ECHO_CMD = pytest.param( ["echo", "--arg1", "val1", "--arg2=val2", "X"], @@ -32,6 +37,17 @@ def test_display( output_tester(lambda: (Local().display(cmd), None), capsys, file_regression) +prints_unexpected_text_to_stdout_on_windows = xfails_on_windows( + raises=AssertionError, + strict=False, + reason=( + "BUG: There is somehow some text being printed to stdout during this test on " + "windows." + ), +) + + +@prints_unexpected_text_to_stdout_on_windows @pytest.mark.parametrize("cmd", [_ECHO_CMD]) def test_silent_get( cmd: list[str], @@ -41,6 +57,7 @@ def test_silent_get( output_tester(lambda: (Local().silent_get(*cmd), None), capsys, file_regression) +@prints_unexpected_text_to_stdout_on_windows @requires_no_s_flag @pytest.mark.parametrize("cmd", [_ECHO_CMD]) def test_get( @@ -51,10 +68,7 @@ def test_get( output_tester(lambda: (Local().get(*cmd), None), capsys, file_regression) -@pytest.mark.skipif( - sys.platform == "win32", - reason="TODO: The output of this test varies between Windows and Ubuntu.", -) +@prints_unexpected_text_to_stdout_on_windows @requires_no_s_flag @pytest.mark.parametrize("cmd", [_ECHO_CMD, _FAKE_CMD, _FAIL_CODE_CMD]) def test_run( @@ -81,6 +95,7 @@ def _catch_exc(): output_tester(func, capsys, file_regression) +@prints_unexpected_text_to_stdout_on_windows @requires_no_s_flag @pytest.mark.parametrize("cmd", [_ECHO_CMD]) def test_popen( @@ -93,3 +108,20 @@ def test_popen( capsys, file_regression, ) + + +@pytest.mark.parametrize( + ("hostname", "expected"), + [ + ("localhost", passwordless_ssh_connection_to_localhost_is_setup), + ("blablabob@localhost", False), + skip_param_if_on_github_ci("narval", True), + skip_param_if_on_github_ci("blablabob@narval", False), + skip_param_if_on_github_ci("beluga", True), + skip_param_if_on_github_ci("cedar", True), + skip_param_if_on_github_ci("graham", True), + skip_param_if_on_github_ci("niagara", False), # Not enabled by default. + ], +) +def test_check_passwordless(hostname: str, expected: bool): + assert check_passwordless(hostname) == expected diff --git a/tests/cli/test_remote.py b/tests/cli/test_remote.py index 58ba2ff6..3d4884fa 100644 --- a/tests/cli/test_remote.py +++ b/tests/cli/test_remote.py @@ -11,11 +11,9 @@ from unittest.mock import Mock import invoke -import paramiko.ssh_exception import pytest from fabric.connection import Connection from pytest_regressions.file_regression import FileRegressionFixture -from typing_extensions import ParamSpec from milatools.cli.remote import ( QueueIO, @@ -25,33 +23,17 @@ ) from milatools.cli.utils import T, shjoin -from .common import function_call_string, requires_s_flag - -P = ParamSpec("P") - -passwordless_ssh_connection_to_localhost_is_setup = False - -try: - Connection("localhost").open() -except ( - paramiko.ssh_exception.SSHException, - paramiko.ssh_exception.NoValidConnectionsError, -): - pass -else: - passwordless_ssh_connection_to_localhost_is_setup = True +from .common import ( + function_call_string, + requires_s_flag, + requires_ssh_to_localhost, +) @pytest.fixture( scope="session", params=[ - pytest.param( - "localhost", - marks=pytest.mark.skipif( - not passwordless_ssh_connection_to_localhost_is_setup, - reason="Passwordless ssh access to localhost needs to be setup.", - ), - ), + pytest.param("localhost", marks=requires_ssh_to_localhost), # TODO: Think about a smart way to enable this. Some tests won't work as-is. # pytest.param( # "mila", @@ -261,7 +243,9 @@ def test_remote_transform_methods( @pytest.fixture(scope="function") def remote(mock_connection: Connection): - return Remote(hostname=mock_connection.host, connection=mock_connection) + hostname = mock_connection.host + assert isinstance(hostname, str) + return Remote(hostname=hostname, connection=mock_connection) @pytest.mark.parametrize("message", ["foobar"])