Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,6 @@ repos:
src/aiida/tools/data/orbital/orbital.py|
src/aiida/tools/data/orbital/realhydrogen.py|
src/aiida/tools/dbimporters/plugins/.*|
src/aiida/transports/cli.py|
src/aiida/transports/plugins/local.py|
src/aiida/transports/plugins/ssh.py|
)$
- id: generate-conda-environment
Expand Down
6 changes: 4 additions & 2 deletions src/aiida/transports/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def configure_computer_main(computer, user, **kwargs):

user = user or orm.User.collection.get_default()

assert user is not None

echo.echo_report(f'Configuring computer {computer.label} for user {user.email}.')
if not user.is_default:
echo.echo_report('Configuring different user, defaults may not be appropriate.')
Expand Down Expand Up @@ -85,7 +87,7 @@ def get_default(ctx):
user = ctx.params.get('user', None) or orm.User.collection.get_default()
computer = ctx.params.get('computer', None)

if computer is None:
if computer is None or user is None:
return None

try:
Expand Down Expand Up @@ -123,7 +125,7 @@ def create_option(name, spec):
if existing_option:
return existing_option(**kwargs)

return click.option(option_name, **kwargs)
return click.option(option_name, **kwargs) # type: ignore[arg-type]


def list_transport_options(transport_type):
Expand Down
7 changes: 4 additions & 3 deletions src/aiida/transports/plugins/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def curdir(self):
If possible, use getcwd() instead!
"""
if self._is_open:
assert self._internal_dir is not None
return os.path.realpath(self._internal_dir)

raise TransportInternalError('Error, local method called for LocalTransport without opening the channel first')
Expand Down Expand Up @@ -816,7 +817,9 @@ def exec_command_wait_bytes(self, command, stdin=None, workdir: TransportPath |
# Also, if I get a StringIO, I just read it all in memory and put it into a BytesIO.
# Clearly not memory effective - in this case do not use a StringIO, but pass directly a BytesIO
# that will be read line by line, if you have a huge stdin and care about memory usage.
if isinstance(stdin, str):
if isinstance(stdin, io.BufferedIOBase):
filelike_stdin = stdin
elif isinstance(stdin, str):
filelike_stdin = io.BytesIO(stdin.encode('utf-8'))
elif isinstance(stdin, bytes):
filelike_stdin = io.BytesIO(stdin)
Expand All @@ -832,8 +835,6 @@ def line_encoder(iterator, encoding='utf-8'):
yield line.encode(encoding)

filelike_stdin = line_encoder(stdin)
elif isinstance(stdin, io.BufferedIOBase):
filelike_stdin = stdin
else:
raise ValueError('You can only pass strings, bytes, BytesIO or StringIO objects')

Expand Down
39 changes: 28 additions & 11 deletions src/aiida/transports/plugins/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ def open(self):
matcher = re.compile(r'^(?:(?P<username>[^@]+)@)?(?P<host>[^@:]+)(?::(?P<port>\d+))?\s*$')
try:
# don't use a generator here to have everything evaluated
proxies = [matcher.match(s).groupdict() for s in proxyjumpstring.split(',')]
proxies = [matcher.match(s).groupdict() for s in proxyjumpstring.split(',')] # type: ignore[union-attr]
except AttributeError:
raise ValueError('The given configuration for the SSH proxy jump option could not be parsed')

Expand Down Expand Up @@ -486,7 +486,7 @@ def open(self):
)
self._close_proxies() # close all since we're going to start anew on the next open() (if any)
raise
connection_arguments['sock'] = proxy_client.get_transport().open_channel(
connection_arguments['sock'] = proxy_client.get_transport().open_channel( # type: ignore[union-attr]
'direct-tcpip', (target['host'], target['port']), ('', 0)
)
self._proxies.append(proxy_client)
Expand Down Expand Up @@ -540,13 +540,16 @@ def close(self):

:todo: correctly manage exceptions

:raise aiida.common.InvalidOperation: if the channel is already open
:raise aiida.common.InvalidOperation: if the channel is already closed
"""
from aiida.common.exceptions import InvalidOperation

if not self._is_open:
raise InvalidOperation('Cannot close the transport: it is already closed')

if self._sftp is None:
raise InvalidOperation('Cannot close the transport: it has never been opened')

self._sftp.close()
self._client.close()
self._close_proxies()
Expand Down Expand Up @@ -1400,7 +1403,14 @@ def isfile(self, path: TransportPath):
return False
raise # Typically if I don't have permissions (errno=13)

def _exec_command_internal(self, command, combine_stderr=False, bufsize=-1, workdir=None):
def _exec_command_internal(
self,
command: str,
workdir: TransportPath | None = None,
combine_stderr: bool = False,
bufsize: int = -1,
**kwargs,
):
"""Executes the specified command in bash login shell.


Expand Down Expand Up @@ -1449,7 +1459,14 @@ def _exec_command_internal(self, command, combine_stderr=False, bufsize=-1, work
return stdin, stdout, stderr, channel

def exec_command_wait_bytes(
self, command, stdin=None, combine_stderr=False, bufsize=-1, timeout=0.01, workdir: TransportPath = None
self,
command: str,
stdin=None,
workdir: TransportPath | None = None,
combine_stderr: bool = False,
bufsize: int = -1,
timeout: float = 0.01,
**kwargs,
):
"""Executes the specified command and waits for it to finish.

Expand All @@ -1472,18 +1489,18 @@ def exec_command_wait_bytes(
workdir = str(workdir)

ssh_stdin, stdout, stderr, channel = self._exec_command_internal(
command, combine_stderr, bufsize=bufsize, workdir=workdir
command, workdir, combine_stderr=combine_stderr, bufsize=bufsize
)

if stdin is not None:
if isinstance(stdin, str):
filelike_stdin = io.StringIO(stdin)
elif isinstance(stdin, bytes):
filelike_stdin = io.BytesIO(stdin)
elif isinstance(stdin, (io.BufferedIOBase, io.TextIOBase)):
if isinstance(stdin, (io.BufferedIOBase, io.TextIOBase)):
# It seems both StringIO and BytesIO work correctly when doing ssh_stdin.write(line)?
# (The ChannelFile is opened with mode 'b', but until now it always has been a StringIO)
filelike_stdin = stdin
elif isinstance(stdin, str):
filelike_stdin = io.StringIO(stdin)
elif isinstance(stdin, bytes):
filelike_stdin = io.BytesIO(stdin)
else:
raise ValueError('You can only pass strings, bytes, BytesIO or StringIO objects')

Expand Down
Loading