Test failures with "RuntimeError: dictionary changed size during iteration"
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 45/100
Research direction
Start in pyfakefs/fake_filesystem_unittest.py at Patcher._find_modules, with the pytest_plugin.py fs fixture as the setup entry point. Reproduce the reported conda-forge test failure if possible and inspect whether sys.modules changes during discovery; done means setup no longer raises RuntimeError and the fs fixture is initialized for the affected tests.
Written by the indexing model from the issue text.
Description
This came up in this comment by @schuylermartin45:
I'm seeing some odd test failures in our
conda-forgebuild for CRM that are not present elsewhere. Looks like some of thepyfakefsfixtures are not being initialized properly: https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=1274733&view=logs&j=7b6f2c87-f3a7-5133-8d84-7c03a75d9dfc&t=9eb77fd2-8ddd-5444-8fc0-71cb28dcb736&l=5034Here's a small snippet from that log:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E AttributeError: 'NoneType' object has no attribute 'add_real_directory' tests/fetcher/test_http_artifact_fetcher.py:100: AttributeError ___________________ test_scan[dummy_py_project_01-expected0] ___________________ [gw0] linux -- Python 3.11.13 $PREFIX/bin/python project_name = 'dummy_py_project_01' expected = {ProjectDependency(data=MatchSpec("python"), type=<DependencySection.RUN: 3>), ProjectDependency(data=MatchSpec("conda... type=<DependencySection.RUN: 3>), ProjectDependency(data=MatchSpec("requests"), type=<DependencySection.RUN: 3>), ...} request = <FixtureRequest for <Function test_scan[dummy_py_project_01-expected0]>> @pytest.mark.parametrize( "project_name,expected", [ ( "dummy_py_project_01", { ProjectDependency(MatchSpec("conda_recipe_manager"), DependencySection.RUN), ProjectDependency(MatchSpec("matplotlib"), DependencySection.RUN), # Two imports on one line ProjectDependency(MatchSpec("networkx"), DependencySection.RUN), # Two imports on one line ProjectDependency(MatchSpec("python"), DependencySection.HOST), ProjectDependency(MatchSpec("python"), DependencySection.RUN), ProjectDependency(MatchSpec("pyyaml"), DependencySection.TESTS), ProjectDependency(MatchSpec("requests"), DependencySection.RUN), # Found in source and test code. }, ), ], ) def test_scan(project_name: str, expected: set[ProjectDependency], request: pytest.FixtureRequest) -> None: """ Tests scanning for Python dependencies with a mocked-out Python project. :param project_name: Name of the dummy Python project directory to use :param expected: Expected value """ fs = cast(FakeFilesystem, request.getfixturevalue("fs")) project_path: Final[Path] = get_test_path() / "software_projects" / project_name > fs.add_real_directory(project_path) ^^^^^^^^^^^^^^^^^^^^^ E AttributeError: 'NoneType' object has no attribute 'add_real_directory'
While examining the log file from the test, I found the following part:
==================================== ERRORS ====================================
_ ERROR at setup of test_bump_recipe_cli[pytest-pep8.yaml-None-bump_recipe/pytest-pep8_build_num_2.yaml] _
[gw0] linux -- Python 3.11.13 $PREFIX/bin/python
request = <SubRequest 'fs' for <Function test_bump_recipe_cli[pytest-pep8.yaml-None-bump_recipe/pytest-pep8_build_num_2.yaml]>>
@pytest.fixture
def fs(request):
"""Fake filesystem."""
if hasattr(request, "param"):
# pass optional parameters via @pytest.mark.parametrize
patcher = Patcher(*request.param)
else:
patcher = Patcher()
> patcher.setUp()
../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place/lib/python3.11/site-packages/pyfakefs/pytest_plugin.py:38:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place/lib/python3.11/site-packages/pyfakefs/fake_filesystem_unittest.py:1033: in setUp
self._find_modules()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pyfakefs.fake_filesystem_unittest.Patcher object at 0x7ff8021acf90>
def _find_modules(self) -> None:
"""Find and cache all modules that import file system modules.
Later, `setUp()` will stub these with the fake file system
modules.
"""
module_names = list(self._fake_module_classes.keys()) + [PATH_MODULE]
> for name, module in list(sys.modules.items()):
^^^^^^^^^^^^^^^^^^^^^^^^^
E RuntimeError: dictionary changed size during iteration
I'm not sure if this is the root of the problem, but it looks like the modules change while iterating over them - probably some module behaving unexpectedly, but this should be avoided, maybe by making a copy of the modules before iterating over them (have to check the performance impact).
A related problem (#338) had been reported (and fixed) quite some time ago, though I have never seen this specific problem until now.
- Dominant language
- Python
- Stars
- 756
- Forks
- 112
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 9
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from pytest-dev/pyfakefs
-
Real Path objects keep a lowercased _str_normcase after a fake filesystem session on Python 3.14Possibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 3/5 1-2 days Newbie friendliness 58/100
pytest-dev/pyfakefs#1359 · 1 comment ·
Maintainers usually reply within 2 days
-
fnmatch.filter and glob don't match uppercase names under Windows simulationPossibly taken @sricharanreddycheruku claimed this 29 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 68/100
pytest-dev/pyfakefs#1345 · 4 comments ·
Maintainers usually reply within 2 days
-
`Path` is replaced with `FakePathlibPathModule` instead of `FakePath` when imported directlyPossibly taken @sunxiuguo claimed this 21 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 70/100
pytest-dev/pyfakefs#1334 · 1 comment ·
Maintainers usually reply within 2 days
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
pytest-dev/pyfakefs#1321 · 4 comments ·
Maintainers usually reply within 2 days
-
fake_filesystem: RuntimeError "dictionary changed size during iteration" under concurrent mkdirOpen
Difficulty 3/5 1-2 days Newbie friendliness 65/100
pytest-dev/pyfakefs#1319 · 1 comment ·
Maintainers usually reply within 2 days
All issues in pytest-dev/pyfakefs
Similar issues
-
community enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Hochfrequenz/sapgui.mcp#1039 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
didi/helixharness#18 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
dataforgoodfr/democracy-watch#46 · 1 reaction ·