Skip to content

Commit 2609551

Browse files
authored
Merge pull request #1013 from plasma-umass/fix/strip-python-interpreter-flags-863
Fix subprocess profiling with Python interpreter flags (#863)
2 parents 1fa9b41 + bd746e5 commit 2609551

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

scalene/scalene_profiler.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,45 @@ def run_profiler(
16491649
progs = None
16501650
exit_status = 0
16511651
try:
1652+
# Strip Python interpreter flags (e.g., -u, -B, -O) that
1653+
# may precede -c or -m when a subprocess is spawned via
1654+
# redirect_python. For example, pytest-xdist launches
1655+
# workers with "python -u ..." which becomes
1656+
# "python -m scalene run ... --- -u -c ..." after
1657+
# redirection. Without stripping, Scalene misinterprets
1658+
# "-u" as a filename.
1659+
# See https://github.com/plasma-umass/scalene/issues/863
1660+
_PY_NO_ARG_FLAGS = {
1661+
"-b", "-B", "-d", "-E", "-i", "-I",
1662+
"-O", "-OO", "-q", "-R", "-s", "-S",
1663+
"-u", "-v", "-x",
1664+
}
1665+
_PY_WITH_ARG_FLAGS = {"-W", "-X"}
1666+
while sys.argv:
1667+
if sys.argv[0] in _PY_NO_ARG_FLAGS:
1668+
flag = sys.argv.pop(0)
1669+
# Apply flags whose effects we can still honor.
1670+
if flag == "-u":
1671+
os.environ["PYTHONUNBUFFERED"] = "1"
1672+
try:
1673+
sys.stdout.reconfigure(line_buffering=False) # type: ignore[union-attr]
1674+
sys.stderr.reconfigure(line_buffering=False) # type: ignore[union-attr]
1675+
except Exception:
1676+
# reconfigure() may not exist (Python < 3.7)
1677+
# or fail on non-standard streams (e.g., pytest
1678+
# capture objects). The env var above is the
1679+
# primary mechanism; reconfigure is best-effort.
1680+
pass
1681+
elif flag == "-B":
1682+
sys.dont_write_bytecode = True
1683+
elif flag == "-v":
1684+
os.environ["PYTHONVERBOSE"] = "1"
1685+
elif sys.argv[0] in _PY_WITH_ARG_FLAGS and len(sys.argv) >= 2:
1686+
sys.argv.pop(0) # flag
1687+
sys.argv.pop(0) # its argument
1688+
else:
1689+
break
1690+
16521691
# Handle direct invocation of a string by executing the string and returning.
16531692
if len(sys.argv) >= 2 and sys.argv[0] == "-c":
16541693
code_to_exec = sys.argv[1]

0 commit comments

Comments
 (0)