-
-
Notifications
You must be signed in to change notification settings - Fork 448
pypy3 + coverage: unclosed file <_io.FileIO fd=3 mode='rb' closefd=True> #807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Does it refer to this? https://github.com/nedbat/coveragepy/blob/coverage-4.5.2/coverage/pytracer.py#L107 |
Apart from that: do you have to use PyTracer? |
The error points at a random line number in a random file and doesn't seem correlated with anything I've figured out yet |
I'm now debugging in a
An example output:
And strace: # grep '= 3$' -- 14.trace | tail -1
open("/pre-commit/.coverage", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3 still not 100% what this means yet 🤔 |
interestingly sometimes I get this:
root@a8e1f963ad16:/pre-commit# grep '= 22$' -- 8.trace | tail -1
open("/pre-commit", O_RDONLY|O_CLOEXEC) = 22 |
if I also add
I see this for the fd 22 issue:
🤔 so there's definitely an open() without a close() there |
I've made quite a few leaps here on some guesses, I think I've narrowed it further... the calls above appear to be coming from the import pytest
import zipfile
import zipp
@pytest.fixture(autouse=True)
def no_warnings(recwarn):
yield
warnings = []
for warning in recwarn: # pragma: no cover
message = str(warning.message)
warnings.append(
'{}:{} {}'.format(warning.filename, warning.lineno, message),
)
assert not warnings
def test():
for _ in range(10000):
with pytest.raises(Exception):
zipfile.ZipFile('.') |
Here's an even more minimal case which takes zipp / zipfile out of the picture: import io
import pytest
import warnings
def test():
for _ in range(10000):
with pytest.raises(IsADirectoryError):
io.open('.')
with warnings.catch_warnings(record=True) as wrns:
warnings.simplefilter('always')
test()
if len(wrns):
print('*' * 79)
print('warnings: {}'.format(len(wrns)))
print('first warning:')
print('{}:{}:{}'.format(wrns[0].filename, wrns[0].lineno, wrns[0].message))
print('*' * 79)
|
and now I've eliminated coverage as well:
I'll take this to the pypy bug tracker 👍 |
Please provide a reference. |
oops used to github linking things, here it is: https://bitbucket.org/pypy/pypy/issues/3021/ioopen-directory-leaks-a-file-descriptor |
pypy3 has a file-descriptor leak with `open('directory')` which `zipp.Path(...)` triggers. This preempts passing a directory and tickling that. More information: - https://bitbucket.org/pypy/pypy/issues/3021/ioopen-directory-leaks-a-file-descriptor - nedbat/coveragepy#807 - pytest-dev/pytest#5342
Describe the bug
Occasionally while running coverage with pypy3 on a specific testsuite it causes "unclosed file" warnings in random parts of code only when instrumented by coverage.
Apologies, I haven't narrowed down the root cause yet but I do have a pretty-consistent reproduction using
docker
.To Reproduce
Here's a dockerfile:
Build this with
docker build -t pypy-coverage-bug .
You can run this with the following command, however it only reproduces about 1 every 10 times and it's a bit slow to stop and start docker repeatedly:
The easier way that I've been reproducing is by doing this
When it passes it looks like this (which happens most of the time):
When it fails it looks like this:
Python 3.5.3[pypy-7.0.0-final]
pip freeze
is very helpful.Expected behavior
Not to crash (see above)
Additional context
Thanks again for writing coverage, it has been instrumental to all of my python testing! Sorry I haven't narrowed down this bug enough yet, but figured I'd post this in case you have any ideas on where I should start looking!
This is currently flaking a lot for me in azure pipelines :(
The text was updated successfully, but these errors were encountered: