Skip to content

Commit

Permalink
Adds modal shell support for -m flag
Browse files Browse the repository at this point in the history
  • Loading branch information
freider committed Feb 25, 2025
1 parent ada783d commit 7130561
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
5 changes: 4 additions & 1 deletion modal/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,9 @@ def shell(
),
),
pty: Optional[bool] = typer.Option(default=None, help="Run the command using a PTY."),
use_module_mode: bool = typer.Option(
False, "-m", help="Interpret argument as a Python module path instead of a file/script path"
),
):
"""Run a command or interactive shell inside a Modal container.
Expand Down Expand Up @@ -584,7 +587,7 @@ def shell(
exec(container_id=container_or_function, command=shlex.split(cmd), pty=pty)
return

import_ref = parse_import_ref(container_or_function)
import_ref = parse_import_ref(container_or_function, use_module_mode=use_module_mode)
runnable, all_usable_commands = import_and_filter(
import_ref, base_cmd="modal shell", accept_local_entrypoint=False, accept_webhook=True
)
Expand Down
23 changes: 12 additions & 11 deletions test/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,34 +470,35 @@ async def _write():


app_file = Path("app_run_tests") / "default_app.py"
app_file_as_module = "app_run_tests.default_app"
webhook_app_file = Path("app_run_tests") / "webhook.py"
cls_app_file = Path("app_run_tests") / "cls.py"


@skip_windows("modal shell is not supported on Windows.")
@pytest.mark.parametrize(
["rel_file", "suffix"],
["flags", "rel_file", "suffix"],
[
(app_file, "::foo"), # Function is explicitly specified
(webhook_app_file, "::foo"), # Function is explicitly specified
(webhook_app_file, ""), # Function must be inferred
([], app_file, "::foo"), # Function is explicitly specified
(["-m"], app_file_as_module, "::foo"), # Function is explicitly specified - module mode
([], webhook_app_file, "::foo"), # Function is explicitly specified
([], webhook_app_file, ""), # Function must be inferred
# TODO: fix modal shell auto-detection of a single class, even if it has multiple methods
# (cls_app_file, ""), # Class must be inferred
# (cls_app_file, "AParametrized"), # class name
(cls_app_file, "::AParametrized.some_method"), # method name
# ([], cls_app_file, ""), # Class must be inferred
# ([], cls_app_file, "AParametrized"), # class name
([], cls_app_file, "::AParametrized.some_method"), # method name
],
)
def test_shell(servicer, set_env_client, supports_dir, mock_shell_pty, rel_file, suffix):
def test_shell(servicer, set_env_client, mock_shell_pty, suffix, monkeypatch, supports_dir, rel_file, flags):
monkeypatch.chdir(supports_dir)
fake_stdin, captured_out = mock_shell_pty

fake_stdin.clear()
fake_stdin.extend([b'echo "Hello World"\n', b"exit\n"])

shell_prompt = servicer.shell_prompt

fn = (supports_dir / rel_file).as_posix()

_run(["shell", fn + suffix])
_run(["shell"] + flags + [str(rel_file) + suffix])

# first captured message is the empty message the mock server sends
assert captured_out == [(1, shell_prompt), (1, b"Hello World\n")]
Expand Down

0 comments on commit 7130561

Please sign in to comment.