pyfakefs: OSError: [Errno 9] Bad file descriptor in the fake filesystem
Hey folks ๐
Iโm facing an issue that seems to be related to pyfakefs, but Iโm not 100% sure.
While implementing an integration between MetricFlow and Prefect 2.0, Iโm using pyfakefs to mock some files I need.
I was able to reproduce the issue with this minimal script:
from prefect import flow
def test_example(fs):
msg = "This is an example flow"
@flow
def test_flow():
return msg
response = test_flow()
assert response == msg
Iโm using pyfakefs==4.6.3 and prefect==2.0b12
Below you can find the trace back generated by pytest:
platform darwin -- Python 3.9.10, pytest-7.1.2, pluggy-1.0.0 -- /Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/bin/python3.9
cachedir: .pytest_cache
rootdir: /Users/alessandro.lollo/dev/prefect-collections/prefect-metricflow, configfile: setup.cfg
plugins: anyio-3.6.1, pyfakefs-4.6.3, asyncio-0.19.0
asyncio: mode=auto
collected 1 item
tests/test_example.py::test_example FAILED [100%]
=========================================================== FAILURES ============================================================
_________________________________________________________ test_example __________________________________________________________
fs = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x10fe72eb0>
def test_example(fs):
msg = "This is an example flow"
@flow
def test_flow():
return msg
> response = test_flow()
/Users/alessandro.lollo/dev/prefect-collections/prefect-metricflow/tests/test_example.py:13:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/prefect/flows.py:367: in __call__
return enter_flow_run_engine_from_flow_call(
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/prefect/engine.py:110: in enter_flow_run_engine_from_flow_call
setup_logging()
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/prefect/logging/configuration.py:66: in setup_logging
config = load_logging_config(
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/prefect/logging/configuration.py:33: in load_logging_config
template = string.Template(path.read_text())
/Users/alessandro.lollo/.pyenv/versions/3.9.10/lib/python3.9/pathlib.py:1266: in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
/Users/alessandro.lollo/.pyenv/versions/3.9.10/lib/python3.9/pathlib.py:1252: in open
return io.open(self, mode, buffering, encoding, errors, newline,
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/pyfakefs/fake_filesystem.py:5036: in open
return fake_open(file, mode, buffering, encoding, errors,
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/pyfakefs/fake_filesystem.py:5721: in __call__
return self.call(*args, **kwargs)
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/pyfakefs/fake_filesystem.py:5778: in call
file_object, file_path, filedes, real_path = self._handle_file_arg(
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/pyfakefs/fake_filesystem.py:5912: in _handle_file_arg
wrapper = self.filesystem.get_open_file(filedes)
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/pyfakefs/fake_filesystem.py:1552: in get_open_file
self.raise_os_error(errno.EBADF, str(file_des))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x10fe72eb0>, err_no = 9, filename = '11', winerror = None
def raise_os_error(self, err_no: int,
filename: Optional[AnyString] = None,
winerror: Optional[int] = None) -> NoReturn:
"""Raises OSError.
The error message is constructed from the given error code and shall
start with the error string issued in the real system.
Note: this is not true under Windows if winerror is given - in this
case a localized message specific to winerror will be shown in the
real file system.
Args:
err_no: A numeric error code from the C variable errno.
filename: The name of the affected file, if any.
winerror: Windows only - the specific Windows error code.
"""
message = os.strerror(err_no) + ' in the fake filesystem'
if (winerror is not None and sys.platform == 'win32' and
self.is_windows_fs):
raise OSError(err_no, message, filename, winerror)
> raise OSError(err_no, message, filename)
E OSError: [Errno 9] Bad file descriptor in the fake filesystem: '11'
/Users/alessandro.lollo/.pyenv/versions/3.9.10/envs/prefect-metricflow/lib/python3.9/site-packages/pyfakefs/fake_filesystem.py:1122: OSError
==================================================== short test summary info ====================================================
FAILED tests/test_example.py::test_example - OSError: [Errno 9] Bad file descriptor in the fake filesystem: '11'
================================================= 1 failed, 8 warnings in 9.07s =================================================
My environment is Python 3.9.10 on MacOS 12.4
Anyone that can help me understanding whatโs going on?
Thanks! ๐
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 17 (11 by maintainers)
Commits related to this issue
- โฌ๏ธ(project) downgrade pyfakefs dependency As there is a regression in the new package release, the dependency is downgraded to the previous one. (https://github.com/jmcgeheeiv/pyfakefs/issues/697) — committed to openfun/ralph by quitterie-lcs 2 years ago
- โฌ๏ธ(project) downgrade pyfakefs dependency As there is a regression in the new package release, the dependency is downgraded to the previous one. (https://github.com/jmcgeheeiv/pyfakefs/issues/697) — committed to openfun/ralph by quitterie-lcs 2 years ago
My bad - forgot to mention the issue in the commit.
At a first glance, this look like the code is trying to read a file in the real fs that is not present in the fake filesystem, specifically the logging config. As the fake filesystem does not use any real filesysystem contents by defaults, these have to be mapped into the fake filesystem on setup if needed. I may have a closer look at this tonight.