From ab2bd4db2a2c8f0319290d5a78d1d200ea1e7e46 Mon Sep 17 00:00:00 2001 From: Alfredo Luque Date: Fri, 10 May 2024 13:10:13 -0700 Subject: [PATCH] fix: Address (#648) Missing FileMode causes an AttributeError in py-rattler and fix missing properties (#651) --- py-rattler/rattler/package/paths_json.py | 24 ++++++++++++++++--- py-rattler/tests/conftest.py | 3 +++ py-rattler/tests/unit/test_fetch_repo_data.py | 9 ++----- py-rattler/tests/unit/test_prefix_record.py | 8 +++++-- py-rattler/tests/unit/test_solver.py | 14 ++++++++--- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/py-rattler/rattler/package/paths_json.py b/py-rattler/rattler/package/paths_json.py index 313f916e9..ca698c208 100644 --- a/py-rattler/rattler/package/paths_json.py +++ b/py-rattler/rattler/package/paths_json.py @@ -452,7 +452,7 @@ class FileMode: The file mode of the entry. """ - _inner: PyFileMode + _inner: PyFileMode | None = None @property def binary(self) -> bool: @@ -472,7 +472,7 @@ def binary(self) -> bool: >>> ``` """ - return self._inner.binary + return self._inner.binary if self._inner else False @property def text(self) -> bool: @@ -492,7 +492,25 @@ def text(self) -> bool: >>> ``` """ - return self._inner.text + return self._inner.text if self._inner else False + + @property + def unknown(self) -> bool: + """ + The file mode is unknown/unspecified + Examples + -------- + ```python + >>> paths_json = PathsJson.from_package_archive( + ... "../test-data/conda-22.9.0-py38haa244fe_2.tar.bz2" + ... ) + >>> entry = paths_json.paths[-1] + >>> file_mode = entry.prefix_placeholder.file_mode + >>> file_mode.unknown + False + >>> + """ + return self._inner is None @classmethod def _from_py_file_mode(cls, py_file_mode: PyFileMode) -> FileMode: diff --git a/py-rattler/tests/conftest.py b/py-rattler/tests/conftest.py index 9c140ba84..14246c5b8 100644 --- a/py-rattler/tests/conftest.py +++ b/py-rattler/tests/conftest.py @@ -9,14 +9,17 @@ def gateway() -> Gateway: return Gateway() + @pytest.fixture def test_data_dir() -> str: return os.path.normpath(os.path.join(os.path.dirname(__file__), "../../test-data")) + @pytest.fixture def conda_forge_channel(test_data_dir: str) -> Channel: return Channel(os.path.join(test_data_dir, "channels/conda-forge")) + @pytest.fixture def pytorch_channel(test_data_dir: str) -> Channel: return Channel(os.path.join(test_data_dir, "channels/pytorch")) diff --git a/py-rattler/tests/unit/test_fetch_repo_data.py b/py-rattler/tests/unit/test_fetch_repo_data.py index f38792e29..78b80cb13 100644 --- a/py-rattler/tests/unit/test_fetch_repo_data.py +++ b/py-rattler/tests/unit/test_fetch_repo_data.py @@ -12,9 +12,7 @@ def serve_repo_data(xprocess) -> None: port, repo_name = 8912, "test-repo" - test_data_dir = os.path.join( - os.path.dirname(__file__), "../../../test-data/test-server" - ) + test_data_dir = os.path.join(os.path.dirname(__file__), "../../../test-data/test-server") class Starter(ProcessStarter): # startup pattern @@ -70,7 +68,4 @@ async def test_fetch_repo_data( assert repodata_record.channel == f"http://localhost:{port}/{repo}/" assert repodata_record.file_name == "test-package-0.1-0.tar.bz2" assert repodata_record.name == PackageName("test-package") - assert ( - repodata_record.url - == f"http://localhost:{port}/test-repo/noarch/test-package-0.1-0.tar.bz2" - ) + assert repodata_record.url == f"http://localhost:{port}/test-repo/noarch/test-package-0.1-0.tar.bz2" diff --git a/py-rattler/tests/unit/test_prefix_record.py b/py-rattler/tests/unit/test_prefix_record.py index 8f1787747..421c4e92b 100644 --- a/py-rattler/tests/unit/test_prefix_record.py +++ b/py-rattler/tests/unit/test_prefix_record.py @@ -31,9 +31,13 @@ def test_load_prefix_record() -> None: paths_with_placeholder += 1 assert isinstance(entry.file_mode, FileMode) assert entry.file_mode.text or entry.file_mode.binary - assert entry.sha256_in_prefix is not None - assert entry.sha256 is not None + assert entry.sha256_in_prefix.hex() is not None + else: + assert entry.file_mode.unknown + assert entry.sha256.hex() is not None assert entry.size_in_bytes > 0 # check that it implements os.PathLike isinstance(entry, os.PathLike) + + assert paths_with_placeholder == 3 diff --git a/py-rattler/tests/unit/test_solver.py b/py-rattler/tests/unit/test_solver.py index aec3c859b..5d95d5b1b 100644 --- a/py-rattler/tests/unit/test_solver.py +++ b/py-rattler/tests/unit/test_solver.py @@ -3,9 +3,12 @@ from rattler import ( solve, ChannelPriority, - RepoDataRecord, Channel, Gateway, + RepoDataRecord, + Channel, + Gateway, ) + @pytest.mark.asyncio async def test_solve(gateway: Gateway, conda_forge_channel: Channel) -> None: solved_data = await solve( @@ -21,7 +24,9 @@ async def test_solve(gateway: Gateway, conda_forge_channel: Channel) -> None: @pytest.mark.asyncio -async def test_solve_channel_priority_disabled(gateway: Gateway, pytorch_channel: Channel, conda_forge_channel: Channel) -> None: +async def test_solve_channel_priority_disabled( + gateway: Gateway, pytorch_channel: Channel, conda_forge_channel: Channel +) -> None: solved_data = await solve( [conda_forge_channel, pytorch_channel], ["linux-64"], @@ -32,5 +37,8 @@ async def test_solve_channel_priority_disabled(gateway: Gateway, pytorch_channel assert isinstance(solved_data, list) assert isinstance(solved_data[0], RepoDataRecord) - assert list(filter(lambda r: r.file_name.startswith("pytorch-cpu-0.4.1-py36_cpu_1"), solved_data))[0].channel == pytorch_channel.base_url + assert ( + list(filter(lambda r: r.file_name.startswith("pytorch-cpu-0.4.1-py36_cpu_1"), solved_data))[0].channel + == pytorch_channel.base_url + ) assert len(solved_data) == 32