Skip to content

Fix subprocess profiling with Python interpreter flags (#863)#1013

Merged
emeryberger merged 2 commits intomasterfrom
fix/strip-python-interpreter-flags-863
Mar 5, 2026
Merged

Fix subprocess profiling with Python interpreter flags (#863)#1013
emeryberger merged 2 commits intomasterfrom
fix/strip-python-interpreter-flags-863

Conversation

@emeryberger
Copy link
Member

Summary

  • Fixes Running pytest on Charcoal-SE/Smokedetector under scalene fails #863: Running pytest with scalene --profile-all fails when pytest-xdist spawns workers with python -u ...
  • When redirect_python intercepts subprocess calls, Python interpreter flags like -u end up in sys.argv before -c/-m, causing Scalene to misinterpret them as filenames
  • Strips recognized Python flags (-u, -B, -O, -W, -X, etc.) before looking for -c/-m/script, applying their effects where possible (unbuffered I/O, .pyc suppression, verbose imports)

Test plan

  • All 322 existing tests pass
  • Manual test with pytest-xdist: scalene run --profile-all --- -m pytest -n 3

🤖 Generated with Claude Code

When pytest-xdist (or similar tools) spawn workers with "python -u ...",
Scalene's redirect_python intercepts and re-invokes as
"python -m scalene run ... --- -u -c ...". After parsing its own args,
sys.argv becomes ["-u", "-c", "..."], but the existing code only checked
sys.argv[0] == "-c", causing "-u" to be misinterpreted as a filename
("could not find input file .../-u").

Strip Python interpreter flags (-u, -B, -O, etc.) before looking for
-c/-m/script arguments, applying their effects where possible (-u sets
unbuffered I/O, -B disables .pyc writing, -v enables verbose imports).

Fixes #863

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
try:
sys.stdout.reconfigure(line_buffering=False) # type: ignore[union-attr]
sys.stderr.reconfigure(line_buffering=False) # type: ignore[union-attr]
except Exception:

Check notice

Code scanning / CodeQL

Empty except Note

'except' clause does nothing but pass and there is no explanatory comment.

Copilot Autofix

AI 7 days ago

In general, empty except blocks should either (1) be removed, (2) be replaced with handling of specific, expected exception types, or (3) at least log or comment why it is safe to ignore the exception. Here, the code is doing a best‑effort call to reconfigure on sys.stdout and sys.stderr. The safest change without altering behavior is to either (a) add a short explanatory comment in the except body and keep it empty, or (b) log a low‑priority message when reconfiguration fails. Since Scalene already imports warnings and writes error messages to sys.stderr in other places, the best targeted fix is to emit a warning when reconfiguration fails; this retains robustness while still surfacing unexpected problems.

Concretely, in scalene/scalene_profiler.py, around lines 1672–1676, replace the bare except Exception: pass with an except Exception as exc: block that calls warnings.warn with a concise message explaining that unbuffered mode could not be applied, including the exception text. This keeps the program running while making the failure visible, and satisfies the static analysis rule by ensuring the except clause does something meaningful. No new imports are needed since warnings is already imported at line 56.

Suggested changeset 1
scalene/scalene_profiler.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/scalene/scalene_profiler.py b/scalene/scalene_profiler.py
--- a/scalene/scalene_profiler.py
+++ b/scalene/scalene_profiler.py
@@ -1672,8 +1672,11 @@
                             try:
                                 sys.stdout.reconfigure(line_buffering=False)  # type: ignore[union-attr]
                                 sys.stderr.reconfigure(line_buffering=False)  # type: ignore[union-attr]
-                            except Exception:
-                                pass
+                            except Exception as exc:
+                                warnings.warn(
+                                    f"Scalene: failed to reconfigure standard streams for unbuffered mode: {exc!r}",
+                                    RuntimeWarning,
+                                )
                         elif flag == "-B":
                             sys.dont_write_bytecode = True
                         elif flag == "-v":
EOF
@@ -1672,8 +1672,11 @@
try:
sys.stdout.reconfigure(line_buffering=False) # type: ignore[union-attr]
sys.stderr.reconfigure(line_buffering=False) # type: ignore[union-attr]
except Exception:
pass
except Exception as exc:
warnings.warn(
f"Scalene: failed to reconfigure standard streams for unbuffered mode: {exc!r}",
RuntimeWarning,
)
elif flag == "-B":
sys.dont_write_bytecode = True
elif flag == "-v":
Copilot is powered by AI and may make mistakes. Always verify output.
Addresses Copilot code scanning alert about the bare except/pass
on the stream reconfigure call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@emeryberger emeryberger merged commit 2609551 into master Mar 5, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Running pytest on Charcoal-SE/Smokedetector under scalene fails

1 participant