# -*- coding: utf-8 -*- # Copyright (c) 2025 relakkes@gmail.com # # This file is part of MediaCrawler project. # Repository: https://github.com/NanmiCoder/MediaCrawler/blob/main/tests/test_interpreter.py # GitHub: https://github.com/NanmiCoder # Licensed under NON-COMMERCIAL LEARNING LICENSE 1.1 # # 声明:本代码仅供学习和研究目的使用。使用者应遵守以下原则: # 1. 不得用于任何商业用途。 # 2. 使用时应遵守目标平台的使用条款和robots.txt规则。 # 3. 不得进行大规模爬取或对平台造成运营干扰。 # 4. 应合理控制请求频率,避免给目标平台带来不必要的负担。 # 5. 不得用于任何非法或不当的用途。 # # 详细许可条款请参阅项目根目录下的LICENSE文件。 # 使用本代码即表示您同意遵守上述原则和LICENSE中的所有条款。 """Tests for the subprocess interpreter resolver.""" import sys from pathlib import Path from api.services.interpreter import ( describe_interpreter, resolve_python_cmd, venv_python_path, ) def _make_venv(root: Path) -> Path: """Create a fake venv layout and return the expected python path.""" exe = venv_python_path(root) exe.parent.mkdir(parents=True, exist_ok=True) exe.write_text("", encoding="utf-8") return exe def test_prefers_uv_when_available(monkeypatch, tmp_path): monkeypatch.setattr("shutil.which", lambda name: "/usr/bin/uv" if name == "uv" else None) _make_venv(tmp_path) # uv wins even when a venv exists, matching the upstream documented workflow. assert resolve_python_cmd(tmp_path) == ["uv", "run", "python"] def test_falls_back_to_project_venv(monkeypatch, tmp_path): monkeypatch.setattr("shutil.which", lambda name: None) exe = _make_venv(tmp_path) assert resolve_python_cmd(tmp_path) == [str(exe)] def test_falls_back_to_current_interpreter(monkeypatch, tmp_path): monkeypatch.setattr("shutil.which", lambda name: None) # No uv, no venv anywhere under the given root. assert resolve_python_cmd(tmp_path) == [sys.executable] def test_describe_is_human_readable(monkeypatch, tmp_path): monkeypatch.setattr("shutil.which", lambda name: None) _make_venv(tmp_path) assert "virtualenv" in describe_interpreter(tmp_path) monkeypatch.setattr("shutil.which", lambda name: "/usr/bin/uv" if name == "uv" else None) assert describe_interpreter(tmp_path) == "uv run python"