Repository navigation
Closed
Description
Environment data
- debugpy version: 1.8.13
- OS and version: Ubuntu 24.04
- Python version (& distribution if applicable, e.g. Anaconda): 3.12
- Using VS Code or Visual Studio: VS Code
Actual behavior
Using joblib (1.5.1) debugpy prints
Traceback (most recent call last):
File "/root/.vscode-server/extensions/ms-python.debugpy-2025.9.2025052001/bundled/libs/debugpy/_vendored/pydevd/_pydev_bundle/pydev_monkey.py", line 543, in patch_args
new_args.append(_get_python_c_args(host, port, code, unquoted_args, SetupHolder.setup))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.vscode-server/extensions/ms-python.debugpy-2025.9.2025052001/bundled/libs/debugpy/_vendored/pydevd/_pydev_bundle/pydev_monkey.py", line 195, in _get_python_c_args
if "__future__" in code:
^^^^^^^^^^^^^^^^^^^^
TypeError: a bytes-like object is required, not 'str'
Expected behavior
Checking if code is byte
Steps to reproduce:
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Worker",
"type": "debugpy",
"request": "launch",
"module": "app.worker",
"subProcess": true, // with this to false we wont debug the subprocess
"justMyCode": true
}
]
}app/worker.py
from joblib import Parallel, delayed
def test():
return 42
Parallel(n_jobs=10)(delayed(test)() for _ in range(10))Tested monkey patch:
@@ -190,7 +190,8 @@
setup_repr = setup if setup is None else (sorted_dict_repr(setup))
future_imports = ""
- if "__future__" in code:
+ future_str = b'__future__' if isinstance(code, bytes) else '__future__'
+ if future_str in code:
# If the code has a __future__ import, we need to be able to strip the __future__
# imports from the code and add them to the start of our code snippet.
future_imports, code = _separate_future_imports(code)But with this I receive a deadlock
/tmp/venv/lib/python3.12/site-packages/joblib/externals/loky/backend/resource_tracker.py:120: UserWarning: resource_tracker: process died unexpectedly, relaunching. Some folders/sempahores might leak.
warnings.warn(
Reacted by Filip Matzner, Tabrez Mohammed and cibeah
Metadata
Metadata
Assignees
Labels
No labels
Activity
rchiodo commentedon May 30, 2025
Can you try this with 3.11? joblib may be generating their own byte code, making debugpy not able to patch their source for debugging. In 3.11 there's a different method of debugging so that might work.
FedericoHeichou commentedon Jun 3, 2025
Hi Rich Chiodo (@rchiodo)
Exactly same problem.
If I add a dummy
print(code)the output is:After that, like before, most of the time goes in deadlock (you can see on the callstack panel a pid spawning and despawning fast).
But the debugging itself works
JhonatanFelix commentedon Apr 28, 2026
Hello Rich Chiodo (@rchiodo),
I investigated a related scikit-learn callback failure from scikit-learn/scikit-learn#33710 and I tried to reduced the lower level failure to direct joblib/loky usage, without requiring scikit-learn
The smaller reproducer is directly the
joblib.externals.loky.backend.get_context().Manager()on debugpy subprocess patchingEnvironment
EOFErrorduring Callback instance creation scikit-learn/scikit-learn#33710Minimal direct-loky reproducer
results matrix
From a clean rerun with fresh logs/output directories:
Manager()--configure-subProcess false, direct lokyManager()Manager()--configure-subProcess true, direct lokyManager()joblib.Parallel(...)reproducer from this issue--configure-subProcess false,joblib.Parallel(...)joblib.Parallel(...)--configure-subProcess true,joblib.Parallel(...)So the hard failure was not specific to scikit-learn. The smallest failing surface I found that it was direct
joblib.externals.loky.backend.get_context().Manager()under debugpy subprocess patchingParent side
For the direct loky reproducer under default debugpy, the parent process fails with:
My interpretation is that the
EOFErroris a secondary symptom: the manager/helper child exits before sending its address back to the parentdebugpy log evidence
The debugpy logs contain the same kind of error as reported here:
the same logs show subprocess patching for loky/joblib helper processes with bytes argv values. for instance:
and loky worker bootstrap commands such as:
There is also a stdlib resource tracker patching line in the logs:
Is it debugpy centered?
The results matrix (above) suggests this is tied to debugpy subprocess patching rather than plain loky or plain multiprocessing:
Manager()passes in plain Python;Manager()passes with--configure-subProcess false;Manager()fails with default subprocess behavior;Manager()fails with--configure-subProcess true;joblib.Parallel(...)reproducer from this issue follows the same pass/fail pattern;pydev_monkey.pybytes/str errors while patching loky/joblib helper process argumentsDoes this look like the same underlying issue as the
pydev_monkey.patch_argsbytes/str error already discussed here?I’m not sure what the best fix would be from the debugpy side. Would it make sense for debugpy to handle these bytes based subprocess arguments, or is there something special about loky’s helper processes that should be treated differently?
rchiodo commentedon Apr 28, 2026
I don't get how "code" in that call stack isn't a string. It must be None then. I think the simple thing would be check for None first and see if it fixes the problem. You can test it out with your reproduction.
JhonatanFelix commentedon Apr 29, 2026
Hello Rich Chiodo (@rchiodo), I checked for None and unfortunately it does not fix the problem.
I tested it locally by temporarily patching the installed (vendored)
pydev_monkey.pyin the repro virtualenv to add diagnostics around_get_python_c_args()and this guard:then I reran on the
joblib/lokyreproducer and restored the original file afterward, finally, I saw that:Just a short diagnotisc snippet:
obs.: using the same environment as before
rchiodo commentedon Apr 29, 2026
Okay thanks. I must have missed something when looking at the callers. We probably just need to handle the bytes case as well then.
JhonatanFelix commentedon Apr 30, 2026
Hello Rich Chiodo (@rchiodo), I tested the bytes handling direction in the same enviromnent. So, I applied a small local patch to
pydev_monkey.pyto decodecodewhen it isbytes, before the"__future__" in codecheck.The patch I tested was essentially:
Actually this does remove the original
pydev_monkey.pybytes/str TypeError, but, it does not fix everything yet because I stlil got the some fails.loky Manager()under default debugpy subprocessloky Manager()with--configure-subProcess truejoblib.Parallel()repro under default debugpy subprocess handlingjoblib.Parallel() repro with--configure-subProcess trueThe other visible failure is still the parent EOFError from:
and the
joblib.Parallel()repro still ends in worker terminationSo it looks like handling bytes in
_get_python_c_args()fixes the first visible error, but the problem is there is still another subprocess/bootstrap failure on Python 3.14.3rchiodo commentedon May 1, 2026
Jhonatan Ramos Felix (@JhonatanFelix), can you try the fix outlined here?
#2021
That fixes it for me but wanted to make sure it works for you.
JhonatanFelix commentedon May 2, 2026
Confirmed! This fixes the failing matrix on my original repro environment as well. Thank you a lot Rich Chiodo (@rchiodo)!