/
niceSOFT
/
python3-installer
Обзор
Документация
Войти
/
niceSOFT
/
python3-installer
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/test_core.py
989 строк
35 KB
Randy Döring
do not install __pycache__ files from wheels (#307)
24 янв 2026, 15:40
Не верифицирован
24 янв 2026, 15:40
a0d3b80
Код
Авторство
О чём код?
import hashlib import textwrap from io import BytesIO from unittest import mock import pytest from installer import install from installer.exceptions import InvalidWheelSource from installer.records import RecordEntry from installer.sources import WheelSource # -------------------------------------------------------------------------------------- # Helpers # -------------------------------------------------------------------------------------- def hash_and_size(data): return hashlib.sha256(data).hexdigest(), len(data) @pytest.fixture def mock_destination(): retval = mock.Mock() # A hacky approach to making sure we got the right objects going in. def custom_write_file(scheme, path, stream, is_executable): assert isinstance(stream, BytesIO) return (path, scheme, 0) def custom_write_script(name, module, attr, section): return (name, module, attr, section) retval.write_file.side_effect = custom_write_file retval.write_script.side_effect = custom_write_script return retval class FakeWheelSource(WheelSource): def __init__(self, *, distribution, version, regular_files, dist_info_files): super().__init__(distribution, version) self.dist_info_files = { file: textwrap.dedent(content.decode("utf-8")) for file, content in dist_info_files.items() } self.regular_files = { file: textwrap.dedent(content.decode("utf-8")).encode("utf-8") for file, content in regular_files.items() } # Compute RECORD file. _records = [record for record, _, _ in self.get_contents()] self.dist_info_files["RECORD"] = "\n".join( sorted( ",".join([file, "sha256=" + hash_, str(size)]) for file, hash_, size in _records ) ) @property def dist_info_filenames(self): return list(self.dist_info_files) def read_dist_info(self, filename): return self.dist_info_files[filename] def validate_record(self) -> None: # Skip validation since the logic is different. return def get_contents(self): # Sort for deterministic behaviour for Python versions that do not preserve # insertion order for dictionaries. for file, content in sorted(self.regular_files.items()): hashed, size = hash_and_size(content) record = (file, f"sha256={hashed}", str(size)) with BytesIO(content) as stream: yield record, stream, False # Sort for deterministic behaviour for Python versions that do not preserve # insertion order for dictionaries. for file, text in sorted(self.dist_info_files.items()): content = text.encode("utf-8") hashed, size = hash_and_size(content) record = ( self.dist_info_dir + "/" + file, f"sha256={hashed}", str(size), ) with BytesIO(content) as stream: yield record, stream, False # -------------------------------------------------------------------------------------- # Actual Tests # -------------------------------------------------------------------------------------- class TestInstall: def test_calls_destination_correctly(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ def main(): print("I'm a fancy package") """, "fancy/__main__.py": b"""\ if __name__ == "__main__": from . import main main() """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "entry_points.txt": b"""\ [console_scripts] fancy = fancy:main [gui_scripts] fancy-gui = fancy:main """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) install( source=source, destination=mock_destination, additional_metadata={ "fun_file.txt": b"this should be in dist-info!", }, ) mock_destination.assert_has_calls( [ mock.call.write_script( name="fancy", module="fancy", attr="main", section="console", ), mock.call.write_script( name="fancy-gui", module="fancy", attr="main", section="gui", ), mock.call.write_file( scheme="purelib", path="fancy/__init__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy/__main__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/METADATA", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/WHEEL", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/entry_points.txt", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/top_level.txt", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/fun_file.txt", stream=mock.ANY, is_executable=False, ), mock.call.finalize_installation( scheme="purelib", record_file_path="fancy-1.0.0.dist-info/RECORD", records=[ ("scripts", ("fancy", "fancy", "main", "console")), ("scripts", ("fancy-gui", "fancy", "main", "gui")), ("purelib", ("fancy/__init__.py", "purelib", 0)), ("purelib", ("fancy/__main__.py", "purelib", 0)), ("purelib", ("fancy-1.0.0.dist-info/METADATA", "purelib", 0)), ("purelib", ("fancy-1.0.0.dist-info/WHEEL", "purelib", 0)), ( "purelib", ("fancy-1.0.0.dist-info/entry_points.txt", "purelib", 0), ), ( "purelib", ("fancy-1.0.0.dist-info/top_level.txt", "purelib", 0), ), ( "purelib", ("fancy-1.0.0.dist-info/fun_file.txt", "purelib", 0), ), ( "purelib", RecordEntry("fancy-1.0.0.dist-info/RECORD", None, None), ), ], ), ] ) def test_no_entrypoints_is_ok(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ def main(): print("I'm a fancy package") """, "fancy/__main__.py": b"""\ if __name__ == "__main__": from . import main main() """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) install( source=source, destination=mock_destination, additional_metadata={ "fun_file.txt": b"this should be in dist-info!", }, ) mock_destination.assert_has_calls( [ mock.call.write_file( scheme="purelib", path="fancy/__init__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy/__main__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/METADATA", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/WHEEL", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/top_level.txt", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/fun_file.txt", stream=mock.ANY, is_executable=False, ), mock.call.finalize_installation( scheme="purelib", record_file_path="fancy-1.0.0.dist-info/RECORD", records=[ ("purelib", ("fancy/__init__.py", "purelib", 0)), ("purelib", ("fancy/__main__.py", "purelib", 0)), ("purelib", ("fancy-1.0.0.dist-info/METADATA", "purelib", 0)), ("purelib", ("fancy-1.0.0.dist-info/WHEEL", "purelib", 0)), ( "purelib", ("fancy-1.0.0.dist-info/top_level.txt", "purelib", 0), ), ( "purelib", ("fancy-1.0.0.dist-info/fun_file.txt", "purelib", 0), ), ( "purelib", RecordEntry("fancy-1.0.0.dist-info/RECORD", None, None), ), ], ), ] ) def test_handles_platlib(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ def main(): print("I'm a fancy package") """, "fancy/__main__.py": b"""\ if __name__ == "__main__": from . import main main() """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "entry_points.txt": b"""\ [console_scripts] fancy = fancy:main [gui_scripts] fancy-gui = fancy:main """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: false Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) install( source=source, destination=mock_destination, additional_metadata={ "fun_file.txt": b"this should be in dist-info!", }, ) mock_destination.assert_has_calls( [ mock.call.write_script( name="fancy", module="fancy", attr="main", section="console", ), mock.call.write_script( name="fancy-gui", module="fancy", attr="main", section="gui", ), mock.call.write_file( scheme="platlib", path="fancy/__init__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy/__main__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy-1.0.0.dist-info/METADATA", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy-1.0.0.dist-info/WHEEL", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy-1.0.0.dist-info/entry_points.txt", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy-1.0.0.dist-info/top_level.txt", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy-1.0.0.dist-info/fun_file.txt", stream=mock.ANY, is_executable=False, ), mock.call.finalize_installation( scheme="platlib", record_file_path="fancy-1.0.0.dist-info/RECORD", records=[ ("scripts", ("fancy", "fancy", "main", "console")), ("scripts", ("fancy-gui", "fancy", "main", "gui")), ("platlib", ("fancy/__init__.py", "platlib", 0)), ("platlib", ("fancy/__main__.py", "platlib", 0)), ("platlib", ("fancy-1.0.0.dist-info/METADATA", "platlib", 0)), ("platlib", ("fancy-1.0.0.dist-info/WHEEL", "platlib", 0)), ( "platlib", ("fancy-1.0.0.dist-info/entry_points.txt", "platlib", 0), ), ( "platlib", ("fancy-1.0.0.dist-info/top_level.txt", "platlib", 0), ), ( "platlib", ("fancy-1.0.0.dist-info/fun_file.txt", "platlib", 0), ), ( "platlib", RecordEntry("fancy-1.0.0.dist-info/RECORD", None, None), ), ], ), ] ) def test_accepts_newer_minor_wheel_versions(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ def main(): print("I'm a fancy package") """, "fancy/__main__.py": b"""\ if __name__ == "__main__": from . import main main() """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "entry_points.txt": b"""\ [console_scripts] fancy = fancy:main [gui_scripts] fancy-gui = fancy:main """, "WHEEL": b"""\ Wheel-Version: 1.1 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) install( source=source, destination=mock_destination, additional_metadata={ "fun_file.txt": b"this should be in dist-info!", }, ) # no assertions necessary, since we want to make sure this test didn't # raises errors. assert True def test_rejects_newer_major_wheel_versions(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ def main(): print("I'm a fancy package") """, "fancy/__main__.py": b"""\ if __name__ == "__main__": from . import main main() """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "entry_points.txt": b"""\ [console_scripts] fancy = fancy:main [gui_scripts] fancy-gui = fancy:main """, "WHEEL": b"""\ Wheel-Version: 2.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) with pytest.raises(InvalidWheelSource) as ctx: install( source=source, destination=mock_destination, additional_metadata={ "fun_file.txt": b"this should be in dist-info!", }, ) assert "Incompatible Wheel-Version" in str(ctx.value) def test_handles_data_properly(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ # put me in purelib """, "fancy-1.0.0.data/purelib/fancy/purelib.py": b"""\ # put me in purelib """, "fancy-1.0.0.data/platlib/fancy/platlib.py": b"""\ # put me in platlib """, "fancy-1.0.0.data/scripts/fancy/scripts.py": b"""\ # put me in scripts """, "fancy-1.0.0.data/headers/fancy/headers.py": b"""\ # put me in headers """, "fancy-1.0.0.data/data/fancy/data.py": b"""\ # put me in data """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "entry_points.txt": b"""\ [console_scripts] fancy = fancy:main [gui_scripts] fancy-gui = fancy:main """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) install( source=source, destination=mock_destination, additional_metadata={}, ) mock_destination.assert_has_calls( [ mock.call.write_script( name="fancy", module="fancy", attr="main", section="console", ), mock.call.write_script( name="fancy-gui", module="fancy", attr="main", section="gui", ), mock.call.write_file( scheme="data", path="fancy/data.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="headers", path="fancy/headers.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="platlib", path="fancy/platlib.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy/purelib.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="scripts", path="fancy/scripts.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy/__init__.py", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/METADATA", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/WHEEL", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/entry_points.txt", stream=mock.ANY, is_executable=False, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/top_level.txt", stream=mock.ANY, is_executable=False, ), mock.call.finalize_installation( scheme="purelib", record_file_path="fancy-1.0.0.dist-info/RECORD", records=[ ("scripts", ("fancy", "fancy", "main", "console")), ("scripts", ("fancy-gui", "fancy", "main", "gui")), ("data", ("fancy/data.py", "data", 0)), ("headers", ("fancy/headers.py", "headers", 0)), ("platlib", ("fancy/platlib.py", "platlib", 0)), ("purelib", ("fancy/purelib.py", "purelib", 0)), ("scripts", ("fancy/scripts.py", "scripts", 0)), ("purelib", ("fancy/__init__.py", "purelib", 0)), ("purelib", ("fancy-1.0.0.dist-info/METADATA", "purelib", 0)), ("purelib", ("fancy-1.0.0.dist-info/WHEEL", "purelib", 0)), ( "purelib", ("fancy-1.0.0.dist-info/entry_points.txt", "purelib", 0), ), ( "purelib", ("fancy-1.0.0.dist-info/top_level.txt", "purelib", 0), ), ( "purelib", RecordEntry("fancy-1.0.0.dist-info/RECORD", None, None), ), ], ), ] ) def test_errors_out_when_given_invalid_scheme_in_data(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ # put me in purelib """, "fancy-1.0.0.data/purelib/fancy/purelib.py": b"""\ # put me in purelib """, "fancy-1.0.0.data/invalid/fancy/invalid.py": b"""\ # i am invalid """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "entry_points.txt": b"""\ [console_scripts] fancy = fancy:main [gui_scripts] fancy-gui = fancy:main """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) with pytest.raises(InvalidWheelSource) as ctx: install( source=source, destination=mock_destination, additional_metadata={}, ) assert "fancy-1.0.0.data/invalid/fancy/invalid.py" in str(ctx.value) def test_ensure_non_executable_for_additional_metadata(self, mock_destination): # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ "fancy/__init__.py": b"""\ # put me in purelib """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 Summary: A fancy package Author: Agendaless Consulting Author-email: nobody@example.com License: MIT Keywords: fancy amazing Platform: UNKNOWN Classifier: Intended Audience :: Developers """, }, ) all_contents = list(source.get_contents()) source.get_contents = lambda: ( (*contents, True) for (*contents, _) in all_contents ) install( source=source, destination=mock_destination, additional_metadata={ "fun_file.txt": b"this should be in dist-info!", }, ) mock_destination.assert_has_calls( [ mock.call.write_file( scheme="purelib", path="fancy/__init__.py", stream=mock.ANY, is_executable=True, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/METADATA", stream=mock.ANY, is_executable=True, ), mock.call.write_file( scheme="purelib", path="fancy-1.0.0.dist-info/fun_file.txt", stream=mock.ANY, is_executable=False, ), ], any_order=True, ) def test_skips_pycache_and_warns(self, mock_destination): """Files inside a __pycache__ directory should be skipped and a RuntimeWarning emitted describing the skipped file. """ top_pycache_path = "__pycache__/bad.cpython-312.pyc" top_good_path = "good.py" sub_pycache_path = "fancy/__pycache__/bad.cpython-312.pyc" sub_good_path = "fancy/good.py" # Create a fake wheel source = FakeWheelSource( distribution="fancy", version="1.0.0", regular_files={ top_pycache_path: b"""\ # compiled bytecode """, top_good_path: b"""\ # good source file """, sub_pycache_path: b"""\ # compiled bytecode """, sub_good_path: b"""\ # good source file """, }, dist_info_files={ "top_level.txt": b"""\ fancy """, "WHEEL": b"""\ Wheel-Version: 1.0 Generator: magic (1.0.0) Root-Is-Purelib: true Tag: py3-none-any """, "METADATA": b"""\ Metadata-Version: 2.1 Name: fancy Version: 1.0.0 """, }, ) # Installing should warn and skip the __pycache__ files. with pytest.warns(RuntimeWarning) as record: install( source=source, destination=mock_destination, additional_metadata={}, ) # Ensure warnings mentioning the __pycache__ paths were emitted. messages = [str(w.message) for w in record] assert len(messages) == 2 assert any(top_pycache_path in m for m in messages) assert any(sub_pycache_path in m for m in messages) # Ensure write_file was not called for the __pycache__ paths. written_files = { kwargs.get("path") for __, kwargs in mock_destination.write_file.call_args_list } assert top_good_path in written_files assert sub_good_path in written_files assert top_pycache_path not in written_files assert sub_pycache_path not in written_files # Ensure finalize_installation's records do not include __pycache__ paths. assert mock_destination.finalize_installation.called records = mock_destination.finalize_installation.call_args[1]["records"] record_paths = { rec.path if isinstance(rec, RecordEntry) else rec[0] for __, rec in records } assert top_good_path in record_paths assert sub_good_path in record_paths assert top_pycache_path not in record_paths assert sub_pycache_path not in record_paths