diff options
author | say <say@yandex-team.ru> | 2022-05-14 02:04:16 +0300 |
---|---|---|
committer | say <say@yandex-team.ru> | 2022-05-14 02:04:16 +0300 |
commit | 492822761567bdac7f2dbe844de1bb3086e9e28e (patch) | |
tree | 5b527a1555338279656fb67212cdcfc3c37bfc49 | |
parent | e5ffe7fe05e7f9d1fd1825a902f5bbbed331d817 (diff) | |
download | ydb-492822761567bdac7f2dbe844de1bb3086e9e28e.tar.gz |
YMAKE-144: Fix RuntimeError: dictionary changed size during iteration
ref:919db9913468e91d031bbd511beeacdcfdd74489
-rw-r--r-- | library/python/runtime_py3/importer.pxi | 8 | ||||
-rw-r--r-- | library/python/runtime_py3/test/test_arcadia_source_finder.py | 24 |
2 files changed, 30 insertions, 2 deletions
diff --git a/library/python/runtime_py3/importer.pxi b/library/python/runtime_py3/importer.pxi index 904f94dea2..579a276d02 100644 --- a/library/python/runtime_py3/importer.pxi +++ b/library/python/runtime_py3/importer.pxi @@ -451,11 +451,15 @@ class ArcadiaSourceFinder: # Yield from cache import re rx = re.compile(re.escape(package_prefix) + r'([^.]+)$') + # Save result to temporary list to prevent 'RuntimeError: dictionary changed size during iteration' + found = [] for mod, path in self.module_path_cache.items(): if path is not None: m = rx.match(mod) if m: - yield prefix + m.group(1), self.is_package(mod) + found.append((prefix + m.group(1), self.is_package(mod))) + for cm in found: + yield cm # Yield from file system for path in paths: @@ -491,7 +495,7 @@ class ArcadiaSourceFinder: return package_paths def _cache_module_path(self, fullname, find_package_only=False): - """ + """ Find module path or package directory paths and save result in the cache find_package_only=True - don't try to find module diff --git a/library/python/runtime_py3/test/test_arcadia_source_finder.py b/library/python/runtime_py3/test/test_arcadia_source_finder.py index ff80d0a0a2..c01435f7df 100644 --- a/library/python/runtime_py3/test/test_arcadia_source_finder.py +++ b/library/python/runtime_py3/test/test_arcadia_source_finder.py @@ -315,3 +315,27 @@ class TestEmptyResources(ArcadiaSourceFinderTestCase): def test_iter_modules(self): assert [] == list(self.arcadia_source_finder.iter_modules('', 'PFX.')) + + +class TestDictionaryChangedSizeDuringIteration(ArcadiaSourceFinderTestCase): + def _get_mock_fs(self): + return ''' + home: + arcadia: + project: + lib1: + mod1.py: '' + lib2: + mod2.py: '' + ''' + + def _get_mock_resources(self): + return { + b'py/namespace/unique_prefix1/project/lib1': b'project.lib1.', + b'py/namespace/unique_prefix1/project/lib2': b'project.lib2.', + } + + def test_no_crash_on_recusive_iter_modules(self): + for package in self.arcadia_source_finder.iter_modules('project.', ''): + for _ in self.arcadia_source_finder.iter_modules(package[0], ''): + pass |