new hyrdusupdate
This commit is contained in:
@@ -692,12 +692,146 @@ IMPORT_NAME_OVERRIDES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_python_command(python_cmd: Optional[Sequence[str] | str]) -> list[str]:
|
||||||
|
if python_cmd is None:
|
||||||
|
return [sys.executable]
|
||||||
|
if isinstance(python_cmd, (str, Path)):
|
||||||
|
return [str(python_cmd)]
|
||||||
|
return [str(part) for part in python_cmd]
|
||||||
|
|
||||||
|
|
||||||
|
def get_python_version_info(python_cmd: Optional[Sequence[str] | str] = None) -> Optional[tuple[int, int, int]]:
|
||||||
|
cmd = normalize_python_command(python_cmd)
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
cmd + [
|
||||||
|
"-c",
|
||||||
|
"import sys; print('.'.join(str(part) for part in sys.version_info[:3]))",
|
||||||
|
],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
version_text = (result.stdout or "").strip()
|
||||||
|
major, minor, micro = version_text.split(".", 2)
|
||||||
|
return (int(major), int(minor), int(micro))
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def is_hydrus_repo(repo_root: Path) -> bool:
|
||||||
|
return (repo_root / "setup_venv.py").exists() and (repo_root / "hydrus_client.py").exists()
|
||||||
|
|
||||||
|
|
||||||
|
def select_hydrus_python_command() -> tuple[list[str], tuple[int, int, int]]:
|
||||||
|
candidates: list[list[str]] = []
|
||||||
|
|
||||||
|
if os.name == "nt" and shutil.which("py"):
|
||||||
|
for version in ("3.12", "3.11", "3.10", "3.13", "3.14"):
|
||||||
|
candidates.append(["py", f"-{version}"])
|
||||||
|
|
||||||
|
candidates.append([sys.executable])
|
||||||
|
|
||||||
|
for name in ("python3.12", "python3.11", "python3.10", "python3", "python"):
|
||||||
|
resolved = shutil.which(name)
|
||||||
|
if resolved:
|
||||||
|
candidates.append([resolved])
|
||||||
|
|
||||||
|
seen: set[tuple[str, ...]] = set()
|
||||||
|
best_fallback: Optional[tuple[list[str], tuple[int, int, int]]] = None
|
||||||
|
|
||||||
|
for candidate in candidates:
|
||||||
|
normalized = tuple(candidate)
|
||||||
|
if normalized in seen:
|
||||||
|
continue
|
||||||
|
seen.add(normalized)
|
||||||
|
|
||||||
|
version = get_python_version_info(candidate)
|
||||||
|
if version is None or version < (3, 10):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if version < (3, 13):
|
||||||
|
return candidate, version
|
||||||
|
|
||||||
|
if best_fallback is None or version < best_fallback[1]:
|
||||||
|
best_fallback = (candidate, version)
|
||||||
|
|
||||||
|
if best_fallback is not None:
|
||||||
|
return best_fallback
|
||||||
|
|
||||||
|
version = get_python_version_info([sys.executable])
|
||||||
|
if version is None:
|
||||||
|
raise RuntimeError("Could not determine a usable Python interpreter for Hydrus")
|
||||||
|
return [sys.executable], version
|
||||||
|
|
||||||
|
|
||||||
|
def build_hydrus_install_targets(
|
||||||
|
req_path: Path,
|
||||||
|
repo_root: Path,
|
||||||
|
python_version: tuple[int, int, int],
|
||||||
|
) -> list[str]:
|
||||||
|
if not is_hydrus_repo(repo_root) or python_version < (3, 13):
|
||||||
|
return ["-r", str(req_path)]
|
||||||
|
|
||||||
|
overrides = {
|
||||||
|
"pyside6": "PySide6==6.10.1",
|
||||||
|
"qtpy": "QtPy==2.4.3",
|
||||||
|
"opencv-python-headless": "opencv-python-headless==4.13.0.90",
|
||||||
|
"numpy": "numpy==2.4.1",
|
||||||
|
}
|
||||||
|
targets: list[str] = []
|
||||||
|
seen_packages: set[str] = set()
|
||||||
|
|
||||||
|
for raw_line in req_path.read_text(encoding="utf-8").splitlines():
|
||||||
|
line = raw_line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
package_name = re.split(r"[<>=!~\[]", line, maxsplit=1)[0].strip().lower()
|
||||||
|
if package_name in overrides:
|
||||||
|
line = overrides[package_name]
|
||||||
|
|
||||||
|
targets.append(line)
|
||||||
|
seen_packages.add(package_name)
|
||||||
|
|
||||||
|
if os.name == "nt" and "pywin32" not in seen_packages:
|
||||||
|
targets.append("pywin32")
|
||||||
|
|
||||||
|
logging.info(
|
||||||
|
"Using Hydrus compatibility dependency set for Python %s.%s.%s",
|
||||||
|
python_version[0],
|
||||||
|
python_version[1],
|
||||||
|
python_version[2],
|
||||||
|
)
|
||||||
|
return targets
|
||||||
|
|
||||||
|
|
||||||
def ensure_repo_venv(
|
def ensure_repo_venv(
|
||||||
repo_root: Path,
|
repo_root: Path,
|
||||||
venv_name: str = ".venv",
|
venv_name: str = ".venv",
|
||||||
recreate: bool = False,
|
recreate: bool = False,
|
||||||
purpose: Optional[str] = None,
|
purpose: Optional[str] = None,
|
||||||
) -> Path:
|
) -> Path:
|
||||||
|
python_cmd: list[str]
|
||||||
|
python_version: Optional[tuple[int, int, int]]
|
||||||
|
if is_hydrus_repo(repo_root):
|
||||||
|
python_cmd, python_version = select_hydrus_python_command()
|
||||||
|
if python_version is not None:
|
||||||
|
logging.info(
|
||||||
|
"Using Python %s.%s.%s for Hydrus venv creation via %s",
|
||||||
|
python_version[0],
|
||||||
|
python_version[1],
|
||||||
|
python_version[2],
|
||||||
|
" ".join(python_cmd),
|
||||||
|
)
|
||||||
|
if python_version >= (3, 13):
|
||||||
|
logging.info(
|
||||||
|
"Hydrus is running on a newer Python; installer will apply compatibility package overrides."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
python_cmd = [sys.executable]
|
||||||
|
|
||||||
venv_dir = repo_root / str(venv_name)
|
venv_dir = repo_root / str(venv_name)
|
||||||
if venv_dir.exists():
|
if venv_dir.exists():
|
||||||
if recreate:
|
if recreate:
|
||||||
@@ -711,7 +845,7 @@ def ensure_repo_venv(
|
|||||||
logging.info("Creating venv at %s for %s", venv_dir, purpose)
|
logging.info("Creating venv at %s for %s", venv_dir, purpose)
|
||||||
else:
|
else:
|
||||||
logging.info("Creating venv at %s", venv_dir)
|
logging.info("Creating venv at %s", venv_dir)
|
||||||
subprocess.run([sys.executable, "-m", "venv", str(venv_dir)], check=True)
|
subprocess.run(python_cmd + ["-m", "venv", str(venv_dir)], check=True)
|
||||||
|
|
||||||
venv_py = get_python_in_venv(venv_dir)
|
venv_py = get_python_in_venv(venv_dir)
|
||||||
if not venv_py:
|
if not venv_py:
|
||||||
@@ -727,6 +861,10 @@ def install_requirements_into_venv(
|
|||||||
req_path: Path,
|
req_path: Path,
|
||||||
reinstall: bool = False,
|
reinstall: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
python_version = get_python_version_info([str(venv_py)])
|
||||||
|
if python_version is None:
|
||||||
|
raise RuntimeError(f"Could not determine python version for {venv_py}")
|
||||||
|
|
||||||
logging.info(
|
logging.info(
|
||||||
"Installing dependencies from %s into venv (reinstall=%s)",
|
"Installing dependencies from %s into venv (reinstall=%s)",
|
||||||
req_path,
|
req_path,
|
||||||
@@ -751,10 +889,11 @@ def install_requirements_into_venv(
|
|||||||
"pip",
|
"pip",
|
||||||
"install",
|
"install",
|
||||||
"--disable-pip-version-check",
|
"--disable-pip-version-check",
|
||||||
|
"--prefer-binary",
|
||||||
]
|
]
|
||||||
if reinstall:
|
if reinstall:
|
||||||
cmd.extend(["--upgrade", "--force-reinstall"])
|
cmd.extend(["--upgrade", "--force-reinstall"])
|
||||||
cmd.extend(["-r", str(req_path)])
|
cmd.extend(build_hydrus_install_targets(req_path, repo_root, python_version))
|
||||||
subprocess.run(cmd, cwd=str(repo_root), check=True)
|
subprocess.run(cmd, cwd=str(repo_root), check=True)
|
||||||
logging.info("Dependencies installed successfully")
|
logging.info("Dependencies installed successfully")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user