Skip to content

Commit 2afb08d

Browse files
authored
fix: handle pip install execution in frozen runtime (#4985)
* fix: handle pip install execution in frozen runtime * fix: harden pip subprocess fallback handling
1 parent 06b2c7c commit 2afb08d

1 file changed

Lines changed: 45 additions & 8 deletions

File tree

astrbot/core/utils/pip_installer.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import locale
66
import logging
77
import os
8+
import shutil
89
import sys
10+
from pathlib import Path
911

1012
from astrbot.core.utils.astrbot_path import get_astrbot_site_packages_path
1113

@@ -34,6 +36,28 @@ def _is_frozen_runtime() -> bool:
3436
return bool(getattr(sys, "frozen", False))
3537

3638

39+
def _get_pip_subprocess_executable() -> str | None:
40+
candidates = [
41+
getattr(sys, "_base_executable", None),
42+
sys.executable,
43+
shutil.which("python3"),
44+
shutil.which("python"),
45+
]
46+
47+
for candidate in candidates:
48+
if not candidate:
49+
continue
50+
51+
candidate_path = Path(candidate)
52+
with contextlib.suppress(OSError):
53+
candidate_path = candidate_path.resolve()
54+
55+
if candidate_path.is_file() and os.access(candidate_path, os.X_OK):
56+
return str(candidate_path)
57+
58+
return None
59+
60+
3761
def _get_pip_main():
3862
try:
3963
from pip._internal.cli.main import main as pip_main
@@ -92,13 +116,26 @@ async def install(
92116

93117
logger.info(f"Pip 包管理器: pip {' '.join(args)}")
94118
result_code = None
95-
if _is_frozen_runtime():
96-
result_code = await self._run_pip_in_process(args)
97-
else:
119+
120+
subprocess_executable = _get_pip_subprocess_executable()
121+
if subprocess_executable:
98122
try:
99-
result_code = await self._run_pip_subprocess(args)
100-
except FileNotFoundError:
101-
result_code = await self._run_pip_in_process(args)
123+
result_code = await self._run_pip_subprocess(
124+
subprocess_executable, args
125+
)
126+
except OSError as exc:
127+
logger.warning(
128+
"Failed to launch pip subprocess (%r). Falling back to in-process pip: %s",
129+
subprocess_executable,
130+
exc,
131+
)
132+
else:
133+
logger.debug(
134+
"No suitable Python executable found for pip subprocess; using in-process pip"
135+
)
136+
137+
if result_code is None:
138+
result_code = await self._run_pip_in_process(args)
102139

103140
if result_code != 0:
104141
raise Exception(f"安装失败,错误码:{result_code}")
@@ -107,9 +144,9 @@ async def install(
107144
sys.path.insert(0, target_site_packages)
108145
importlib.invalidate_caches()
109146

110-
async def _run_pip_subprocess(self, args: list[str]) -> int:
147+
async def _run_pip_subprocess(self, executable: str, args: list[str]) -> int:
111148
process = await asyncio.create_subprocess_exec(
112-
sys.executable,
149+
executable,
113150
"-m",
114151
"pip",
115152
*args,

0 commit comments

Comments
 (0)