Skip to content

Commit

Permalink
fix: include active namespace in interactive script console (#1283)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Feb 4, 2023
1 parent e8670d8 commit eaee302
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
29 changes: 27 additions & 2 deletions src/ape_run/_cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import inspect
import os
import sys
import traceback
from pathlib import Path
from runpy import run_module
Expand All @@ -21,6 +23,7 @@ def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)
self._namespace = {}
self._command_called = None

def invoke(self, ctx: Context) -> Any:
try:
Expand Down Expand Up @@ -180,8 +183,30 @@ def result_callback(self, result, interactive):
return result

def _launch_console(self):
# TODO: Figure out how to pull out namespace for `extra_locals`
extra_locals = {**self._namespace.get(self._command_called, {})}
trace = inspect.trace()
trace_frames = [
x for x in trace if x.filename.startswith(str(self._project.scripts_folder))
]
if not trace_frames:
# Error from Ape internals; avoid launching console.
sys.exit(1)

# Use most recently matching frame.
frame = trace_frames[-1].frame

try:
globals_dict = {k: v for k, v in frame.f_globals.items() if not k.startswith("__")}
extra_locals = {
**self._namespace.get(self._command_called, {}),
**globals_dict,
**frame.f_locals,
}

finally:
# Avoid keeping a reference to a frame to avoid reference cycles.
if frame:
del frame

return console(project=self._project, extra_locals=extra_locals)


Expand Down
1 change: 1 addition & 0 deletions tests/integration/cli/projects/script/scripts/error.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
def main():
local_variable = "test foo bar" # noqa[F841]
raise Exception("Expected exception")
1 change: 1 addition & 0 deletions tests/integration/cli/projects/script/scripts/error_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

@click.command(short_help="Use a subcommand")
def cli():
local_variable = "test foo bar" # noqa[F841]
raise Exception("Expected exception") # noqa: T001
9 changes: 8 additions & 1 deletion tests/integration/cli/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,16 @@ def test_run_when_script_errors(ape_cli, runner, project):
@skip_projects_except("script")
def test_run_interactive(ape_cli, runner, project):
scripts = [s for s in project.scripts_folder.glob("*.py") if s.name.startswith("error")]
result = runner.invoke(ape_cli, ["run", "--interactive", scripts[0].stem], input="exit\n")

# Show that the variable namespace from the script is available in the console.
user_input = "local_variable\nexit\n"

result = runner.invoke(ape_cli, ["run", "--interactive", scripts[0].stem], input=user_input)
assert result.exit_code == 0, result.output

# From script: local_variable = "test foo bar"
assert "test foo bar" in result.output


@skip_projects_except("script")
def test_run_adhoc_provider(ape_cli, runner, project):
Expand Down

0 comments on commit eaee302

Please sign in to comment.