Open randomstuff opened 5 years ago
One workaround might be to use a mutex in order to prevent concurrent mypy linting. Ultimately, sys.stdout
and sys.stderr
overriding could create some other issues and this should be fixed in mypy API instead.
This will most likely be resolved in python/mypy#6125.
As I said in python/mypy/pull/6129 if people are having trouble with this, in the meantime, a quick duct-tape solution could be to replace the call of mypy.api.run
with something like this:
res = subprocess.run(
["python", "-m", "mypy", *args],
stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
report = res.stdout
errors = res.stderr
@randomstuff amazing tenacity narrowing own the cause of this issue!
Let me know if we need an alternative to the pull request solution.
@elkhadiy started working on a PR on mypy. (@elkhadiy: Tell me if you want some help on the PR.)
In the meanwhile, I used the workaround of executing the body of _run()
while holding a mutex:
_lock = Lock()
def _run(f: Callable[[], None]) -> Tuple[str, str, int]:
with _lock:
old_stdout = sys.stdout
new_stdout = StringIO()
sys.stdout = new_stdout
old_stderr = sys.stderr
new_stderr = StringIO()
sys.stderr = new_stderr
try:
f()
exit_status = 0
except SystemExit as system_exit:
exit_status = system_exit.code
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
return new_stdout.getvalue(), new_stderr.getvalue(), exit_status
It's working alright but I don't think it's worth merging this hack as the correct fix (in mypy) should be comparatively simple.
upgrading mypy to the latest version now solves the issue
edit: no it does not
@remorses, mypy's bug is not marked as fixed and at first glance I don't see any change in the latest release in this regard.
This issue appeared when I activated dmypy in the configuration file:
Here is my pylsp-mypy.cfg
:
{
"enabled": True,
"live_mode": False,
"dmypy": True,
"strict": False
}
When I set dmypy
to False
, the error disappears
While debugging an error appearing in Atom IDE-Python plugin, we found that some errors reported by mypy sometimes end up appearing directly in the process stdout (outside on the JSON body) which breaks the protocol:
You can easily check the output of pyls with sysdig:
AFAIU, this happens because mypy API currently works by temporarily overriding
sys.stdout
andsys.stderr
which is not thread-safe:The linter tasks are handled in separate threads because of the debouncing feature of python-language-server:
Because stdout overriding is not thread safe,
sys.stout
may not be correctly restored and some errors are actually reported in the real/original/system stdout instead of theStringIO
one.