Skip to content

Commit

Permalink
Fix sys.path manipulation for isolated mode
Browse files Browse the repository at this point in the history
`memray run` tries to match the updates to `sys.path` that are performed
by the interpreter itself when it starts. When those path updates are
suppressed (by the `-I` or `-P` command line flags or their
corresponding environment variables), Memray's emulation winds up
overwriting paths in `sys.path` that needed to be left alone.

Signed-off-by: Matt Wozniski <[email protected]>
  • Loading branch information
godlygeek authored and pablogsal committed Feb 22, 2024
1 parent 8b368a1 commit 123b09c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
1 change: 1 addition & 0 deletions news/552.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug causing the first entry of ``sys.path`` to be erroneously overwritten by ``memray run`` when the Python interpreter was launched with the ``-I`` or ``-P`` flag, or when the ``PYTHONSAFEPATH`` environment variable was set.
17 changes: 14 additions & 3 deletions src/memray/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ def _get_free_port() -> int:
return int(sock.getsockname()[1])


def _should_modify_sys_path() -> bool:
isolated_mode = sys.flags.isolated
safe_path_mode = getattr(sys.flags, "safe_path", False) # New in Python 3.11
return not isolated_mode and not safe_path_mode


def _run_tracker(
destination: Destination,
args: argparse.Namespace,
Expand All @@ -52,16 +58,21 @@ def _run_tracker(
pid = os.getpid()
try:
if args.run_as_module:
sys.path[0] = os.getcwd()
if _should_modify_sys_path():
sys.path[0] = os.getcwd()
# run_module will replace argv[0] with the script's path
sys.argv = ["", *args.script_args]
runpy.run_module(args.script, run_name="__main__", alter_sys=True)
elif args.run_as_cmd:
sys.path[0] = ""
if _should_modify_sys_path():
sys.path[0] = ""
sys.argv = ["-c", *args.script_args]
exec(args.script, {"__name__": "__main__"})
else:
sys.path[0] = str(pathlib.Path(args.script).resolve().parent.absolute())
if _should_modify_sys_path():
sys.path[0] = str(
pathlib.Path(args.script).resolve().parent.absolute()
)
sys.argv = [args.script, *args.script_args]
runpy.run_path(args.script, run_name="__main__")
finally:
Expand Down

0 comments on commit 123b09c

Please sign in to comment.