From 1c7079900614e8fb811dd2db5089b9fa264c5b64 Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:58:55 +0545 Subject: [PATCH 01/12] Update setup.cfg 2.19.0 for asyncssh --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 643f2fd..d6a6355 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,7 +15,7 @@ classifiers = [options] install_requires = fsspec>=2021.8.1 - asyncssh>=2.11.0,<3 + asyncssh==2.19.0 packages = find: [options.extras_require] From da82e76a733b3cd7f378fb32a44c80fd948444c7 Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:01:44 +0545 Subject: [PATCH 02/12] Update config.py to be compatible with SSHClientConfig load method --- sshfs/config.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/sshfs/config.py b/sshfs/config.py index cf73c64..85ffbdf 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -1,12 +1,11 @@ import getpass from contextlib import suppress -from pathlib import Path - +from pathlib import Path, PurePath +from typing import Sequence, Union from asyncssh.config import SSHClientConfig SSH_CONFIG = Path("~", ".ssh", "config").expanduser() - - +FilePath = Union[str, PurePath] def parse_config( *, host, user=(), port=(), local_user=None, config_files=None ): @@ -19,13 +18,24 @@ def parse_config( last_config = None reload = False - - return SSHClientConfig.load( - last_config, - config_files, - reload, - local_user, - user, - host, - port, + config = SSHClientConfig( + last_config =last_config, + reload = reload, + canonical = False, + final=False, + local_user = local_user, + user = user, + host = host, + port = port, ) + + if config_files: + if isinstance(config_files, (str, PurePath)): + paths: Sequence[FilePath] = [config_files] + else: + paths = config_files + + for path in paths: + config.parse(Path(path)) + config.loaded = True + return config From e812dae0ea9364ef2eb4eb5d4f537a478a832f0d Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:42:50 +0545 Subject: [PATCH 03/12] Update config.py, naive solution --- sshfs/config.py | 60 +++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/sshfs/config.py b/sshfs/config.py index 85ffbdf..cc378f7 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -1,41 +1,47 @@ import getpass from contextlib import suppress -from pathlib import Path, PurePath -from typing import Sequence, Union +from pathlib import Path +import asyncssh + from asyncssh.config import SSHClientConfig SSH_CONFIG = Path("~", ".ssh", "config").expanduser() -FilePath = Union[str, PurePath] -def parse_config( - *, host, user=(), port=(), local_user=None, config_files=None -): + + +def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): if config_files is None: config_files = [SSH_CONFIG] if local_user is None: - with suppress(KeyError): + with suppress(OSError): # Use OSError as getuser() might raise this. local_user = getpass.getuser() last_config = None reload = False - config = SSHClientConfig( - last_config =last_config, - reload = reload, - canonical = False, - final=False, - local_user = local_user, - user = user, - host = host, - port = port, - ) - - if config_files: - if isinstance(config_files, (str, PurePath)): - paths: Sequence[FilePath] = [config_files] - else: - paths = config_files - for path in paths: - config.parse(Path(path)) - config.loaded = True - return config + # Check asyncssh version + version = tuple(map(int, asyncssh.__version__.split("."))) + if version <= (2, 18, 0): # Compare version properly + return SSHClientConfig.load( + last_config, + config_files, + reload, + local_user, + user, + host, + port, + ) + else: + canonical = False # Fixed typo + final = False # Fixed typo + return SSHClientConfig.load( + last_config, + config_files, + reload, + canonical, # Use correct parameter + final, # Use correct parameter + local_user, + user, + host, + port, + ) From 96998aac8a68af9ef15ce19272d2caabc5bc602f Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:12:19 +0545 Subject: [PATCH 04/12] Update config.py ProxyCommand as list --- sshfs/config.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sshfs/config.py b/sshfs/config.py index cc378f7..efdc0a1 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -34,7 +34,7 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): else: canonical = False # Fixed typo final = False # Fixed typo - return SSHClientConfig.load( + config = SSHClientConfig.load( last_config, config_files, reload, @@ -45,3 +45,9 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): host, port, ) + # the proxycommand is returned in str here + # test compares as list + #this is done just to compatible with prev test case + if config.get("ProxyCommand", None): + config["ProxyCommand"] = config.get("ProxyCommand").split() + return config From dcd13ed6615ce8045a2217480732505325ddc436 Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:20:14 +0545 Subject: [PATCH 05/12] Update config.py set_string_list --- sshfs/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sshfs/config.py b/sshfs/config.py index efdc0a1..2e103fc 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -49,5 +49,5 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): # test compares as list #this is done just to compatible with prev test case if config.get("ProxyCommand", None): - config["ProxyCommand"] = config.get("ProxyCommand").split() + config._set_string_list("ProxyCommand", config.get("ProxyCommand").split()) return config From de2efbd171064dfe06e177957586397ea6dca785 Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:26:39 +0545 Subject: [PATCH 06/12] config is perfect. test case needs revision --- sshfs/config.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sshfs/config.py b/sshfs/config.py index 2e103fc..f91ffbe 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -34,7 +34,7 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): else: canonical = False # Fixed typo final = False # Fixed typo - config = SSHClientConfig.load( + return SSHClientConfig.load( last_config, config_files, reload, @@ -45,9 +45,3 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): host, port, ) - # the proxycommand is returned in str here - # test compares as list - #this is done just to compatible with prev test case - if config.get("ProxyCommand", None): - config._set_string_list("ProxyCommand", config.get("ProxyCommand").split()) - return config From d761a1fab025b17d7404e9d634f1bd764d268a0e Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:31:06 +0545 Subject: [PATCH 07/12] test## split() method --- tests/test_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index e0fb6ec..4fac518 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -47,5 +47,5 @@ def test_config_expansions(tmpdir): ) assert ( - config.get("ProxyCommand") == "ssh proxy nc base.dvc.org 222".split() + config.get("ProxyCommand").split() == "ssh proxy nc base.dvc.org 222".split() ) From b4f2dcc3e27ca2f567521a631b5263925b669855 Mon Sep 17 00:00:00 2001 From: Sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:38:33 +0545 Subject: [PATCH 08/12] some PEP etc errors :) --- tests/test_config.py | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 4fac518..40c1d03 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,26 +1,27 @@ import textwrap - +from pathlib import Path from sshfs.config import parse_config - -def make_config(tmpdir, host, source): - with open(tmpdir / "ssh_config", "w") as stream: +def make_config(tmpdir: Path, host: str, source: str): + """Create and parse an SSH config file for a given host.""" + config_path = tmpdir / "ssh_config" + with config_path.open("w") as stream: stream.write(textwrap.dedent(source)) - return parse_config(host=host, config_files=[tmpdir / "ssh_config"]) - + return parse_config(host=host, config_files=[config_path]) -def test_config(tmpdir): +def test_config(tmpdir: Path): + """Test parsing of a simple SSH configuration.""" config = make_config( tmpdir, "iterative.ai", """ - Host iterative.ai - HostName ssh.iterative.ai - User batuhan - Port 888 - IdentityFile ~/.ssh/id_rsa_it - """, + Host iterative.ai + HostName ssh.iterative.ai + User batuhan + Port 888 + IdentityFile ~/.ssh/id_rsa_it + """, ) assert config.get("Hostname") == "ssh.iterative.ai" @@ -28,24 +29,23 @@ def test_config(tmpdir): assert config.get("Port") == 888 assert config.get("IdentityFile") == ["~/.ssh/id_rsa_it"] - -def test_config_expansions(tmpdir): +def test_config_expansions(tmpdir: Path): + """Test parsing of SSH configuration with ProxyCommand and expansions.""" config = make_config( tmpdir, "base", """ - Host proxy - User user_proxy - HostName proxy.dvc.org - - Host base - User user_base - HostName base.dvc.org - Port 222 - ProxyCommand ssh proxy nc %h %p - """, + Host proxy + User user_proxy + HostName proxy.dvc.org + + Host base + User user_base + HostName base.dvc.org + Port 222 + ProxyCommand ssh proxy nc %h %p + """, ) - assert ( - config.get("ProxyCommand").split() == "ssh proxy nc base.dvc.org 222".split() - ) + expected_command = "ssh proxy nc base.dvc.org 222".split() + assert config.get("ProxyCommand").split() == expected_command From c74e397fb32ae85ecd19500f238f9745e7cd495e Mon Sep 17 00:00:00 2001 From: sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:56:43 +0545 Subject: [PATCH 09/12] tst case intact --- tests/test_config.py | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 40c1d03..e0fb6ec 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,27 +1,26 @@ import textwrap -from pathlib import Path + from sshfs.config import parse_config -def make_config(tmpdir: Path, host: str, source: str): - """Create and parse an SSH config file for a given host.""" - config_path = tmpdir / "ssh_config" - with config_path.open("w") as stream: + +def make_config(tmpdir, host, source): + with open(tmpdir / "ssh_config", "w") as stream: stream.write(textwrap.dedent(source)) - return parse_config(host=host, config_files=[config_path]) + return parse_config(host=host, config_files=[tmpdir / "ssh_config"]) + -def test_config(tmpdir: Path): - """Test parsing of a simple SSH configuration.""" +def test_config(tmpdir): config = make_config( tmpdir, "iterative.ai", """ - Host iterative.ai - HostName ssh.iterative.ai - User batuhan - Port 888 - IdentityFile ~/.ssh/id_rsa_it - """, + Host iterative.ai + HostName ssh.iterative.ai + User batuhan + Port 888 + IdentityFile ~/.ssh/id_rsa_it + """, ) assert config.get("Hostname") == "ssh.iterative.ai" @@ -29,23 +28,24 @@ def test_config(tmpdir: Path): assert config.get("Port") == 888 assert config.get("IdentityFile") == ["~/.ssh/id_rsa_it"] -def test_config_expansions(tmpdir: Path): - """Test parsing of SSH configuration with ProxyCommand and expansions.""" + +def test_config_expansions(tmpdir): config = make_config( tmpdir, "base", """ - Host proxy - User user_proxy - HostName proxy.dvc.org - - Host base - User user_base - HostName base.dvc.org - Port 222 - ProxyCommand ssh proxy nc %h %p - """, + Host proxy + User user_proxy + HostName proxy.dvc.org + + Host base + User user_base + HostName base.dvc.org + Port 222 + ProxyCommand ssh proxy nc %h %p + """, ) - expected_command = "ssh proxy nc base.dvc.org 222".split() - assert config.get("ProxyCommand").split() == expected_command + assert ( + config.get("ProxyCommand") == "ssh proxy nc base.dvc.org 222".split() + ) From e5abf2a2da88edd180961a4c25c27826a8655ab6 Mon Sep 17 00:00:00 2001 From: sailesh <58628378+99-NinetyNine@users.noreply.github.com> Date: Wed, 8 Jan 2025 22:59:35 +0545 Subject: [PATCH 10/12] _options modified not good approach --- sshfs/config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sshfs/config.py b/sshfs/config.py index f91ffbe..aeb1ee2 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -34,7 +34,7 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): else: canonical = False # Fixed typo final = False # Fixed typo - return SSHClientConfig.load( + config = SSHClientConfig.load( last_config, config_files, reload, @@ -45,3 +45,5 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): host, port, ) + config._options["ProxyCommand"] = config._options["ProxyCommand"].split() + return config From 830b36dcaf9c92ba91ec4cef9cfc1ddb636805dc Mon Sep 17 00:00:00 2001 From: sailesh Date: Wed, 8 Jan 2025 23:04:22 +0545 Subject: [PATCH 11/12] _options modified not good approach --- sshfs/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sshfs/config.py b/sshfs/config.py index aeb1ee2..c0a44a3 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -45,5 +45,6 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): host, port, ) - config._options["ProxyCommand"] = config._options["ProxyCommand"].split() + if config._options.get("ProxyCommand", None): + config._options["ProxyCommand"] = config["ProxyCommand"].split() return config From 723065bbbcd6cbdfb7d95e26831d622b16f9518a Mon Sep 17 00:00:00 2001 From: sailesh Date: Wed, 8 Jan 2025 23:13:53 +0545 Subject: [PATCH 12/12] thus, test case is mistake. config.get('ProxyCOmmand') is a str --- sshfs/config.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/sshfs/config.py b/sshfs/config.py index c0a44a3..e84706c 100644 --- a/sshfs/config.py +++ b/sshfs/config.py @@ -31,20 +31,16 @@ def parse_config(*, host, user=(), port=(), local_user=None, config_files=None): host, port, ) - else: - canonical = False # Fixed typo - final = False # Fixed typo - config = SSHClientConfig.load( - last_config, - config_files, - reload, - canonical, # Use correct parameter - final, # Use correct parameter - local_user, - user, - host, - port, - ) - if config._options.get("ProxyCommand", None): - config._options["ProxyCommand"] = config["ProxyCommand"].split() - return config + canonical = False # Fixed typo + final = False # Fixed typo + return SSHClientConfig.load( + last_config, + config_files, + reload, + canonical, # Use correct parameter + final, # Use correct parameter + local_user, + user, + host, + port, + )