Skip to content

Commit f3b0bc9

Browse files
committed
Optimize subprocess
增加一批异常处理机制,增强代码健壮性(感谢“通义灵码”!);
1 parent c4e9591 commit f3b0bc9

2 files changed

Lines changed: 74 additions & 27 deletions

File tree

src/py2exe_gui/Utilities/platform_specifc_funcs.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88

99
import subprocess
10+
import warnings
1011
from pathlib import Path
1112
from typing import Union
1213

@@ -19,13 +20,22 @@ def open_dir_in_explorer(dir_path: Union[str, Path]) -> None:
1920
:param dir_path: 待打开的目录路径
2021
"""
2122

22-
if RUNTIME_INFO.platform == PLATFORM.windows:
23-
import os # fmt: skip
24-
os.startfile(dir_path) # type: ignore
25-
elif RUNTIME_INFO.platform == PLATFORM.linux:
26-
subprocess.call(["xdg-open", dir_path])
27-
elif RUNTIME_INFO.platform == PLATFORM.macos:
28-
subprocess.call(["open", dir_path])
23+
try:
24+
if RUNTIME_INFO.platform == PLATFORM.windows:
25+
import os # fmt: skip
26+
os.startfile(dir_path) # type: ignore
27+
elif RUNTIME_INFO.platform == PLATFORM.linux:
28+
subprocess.call(["xdg-open", dir_path])
29+
elif RUNTIME_INFO.platform == PLATFORM.macos:
30+
subprocess.call(["open", dir_path])
31+
else:
32+
raise ValueError(f"Unsupported platform: {RUNTIME_INFO.platform}.")
33+
except OSError as e:
34+
warnings.warn(
35+
f"Error occurred while trying to open directory: {e}",
36+
RuntimeWarning,
37+
stacklevel=2,
38+
)
2939

3040

3141
def get_sys_python() -> str:
@@ -35,10 +45,24 @@ def get_sys_python() -> str:
3545
"""
3646

3747
if RUNTIME_INFO.platform == PLATFORM.windows:
38-
cmd = "powershell.exe (Get-Command python).Path" # PowerShell
48+
cmd = ["powershell.exe", "(Get-Command python).Path"] # PowerShell
3949
elif RUNTIME_INFO.platform in (PLATFORM.linux, PLATFORM.macos):
40-
cmd = "which python3"
50+
cmd = ["which", "python3"]
4151
else:
4252
raise ValueError("Current OS is not supported.")
4353

44-
return subprocess.getoutput(cmd)
54+
try:
55+
result = subprocess.run(cmd, capture_output=True, text=True)
56+
python_path = result.stdout.strip()
57+
except subprocess.CalledProcessError as e:
58+
warnings.warn(
59+
f"Error occurred while trying to get system default Python interpreter: {e.output}",
60+
RuntimeWarning,
61+
stacklevel=2,
62+
)
63+
raise
64+
65+
if not Path(python_path).exists():
66+
raise FileNotFoundError(f"Python interpreter not found: {python_path}")
67+
68+
return python_path

src/py2exe_gui/Utilities/python_env.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,16 @@ def get_py_version(executable_path: Union[str, Path]) -> str:
3838
:return: Version of the Python interpreter, such as "3.11.7".
3939
"""
4040

41-
cmd = f"{executable_path} -c \"import platform;print(platform.python_version(), end='')\""
42-
version = subprocess.getoutput(cmd, encoding="utf-8")
41+
cmd = [
42+
f"{executable_path}",
43+
"-c",
44+
"import platform;print(platform.python_version(), end='')",
45+
]
46+
try:
47+
result = subprocess.run(cmd, capture_output=True, text=True)
48+
version = result.stdout
49+
except subprocess.CalledProcessError as e:
50+
raise RuntimeError(f"Failed to get Python version: {e.output}") from e
4351
return version
4452

4553
@staticmethod
@@ -50,14 +58,33 @@ def get_installed_packages(executable_path: Union[str, Path]) -> list[dict]:
5058
:return: 包列表,形如 [{'name': 'aiohttp', 'version': '3.9.1'}, {'name': 'aiosignal', 'version': '1.3.1'}, ...]
5159
"""
5260

53-
cmd = (
54-
f"{executable_path} -m pip list --format json "
55-
"--disable-pip-version-check --no-color "
56-
"--no-python-version-warning"
57-
)
58-
pip_list = subprocess.getoutput(cmd)
59-
# TODO 添加异常处理机制
60-
installed_packages: list[dict] = json.loads(pip_list)
61+
cmd = [
62+
f"{executable_path}",
63+
"-m",
64+
"pip",
65+
"list",
66+
"--format",
67+
"json",
68+
"--disable-pip-version-check",
69+
"--no-color",
70+
"--no-python-version-warning",
71+
]
72+
73+
try:
74+
# 运行 pip list 命令,获取输出
75+
result = subprocess.run(cmd, capture_output=True, text=True)
76+
pip_list = result.stdout
77+
except subprocess.CalledProcessError as e:
78+
raise RuntimeError(f"Failed to get installed packages: {e.output}") from e
79+
except Exception as e:
80+
raise RuntimeError(f"An error occurred: {e}") from e
81+
82+
try:
83+
# json 解析
84+
installed_packages: list[dict] = json.loads(pip_list)
85+
except json.decoder.JSONDecodeError as e:
86+
raise RuntimeError(f"Failed to parse installed packages: {e}") from e
87+
6188
return installed_packages
6289

6390
@classmethod
@@ -70,16 +97,12 @@ def infer_type(cls, executable_path: Union[str, Path]) -> PyEnvType:
7097

7198
def pkg_installed(self, package_name: str) -> bool:
7299
"""
73-
检索某个包是否已安装 \n
74-
:param package_name: 待检索的包名
100+
检查特定软件包是否已安装 \n
101+
:param package_name: 待检索的软件包名称
75102
:return: 是否已安装
76103
"""
77104

78-
for package in self.installed_packages:
79-
if package["name"] == package_name:
80-
return True
81-
else:
82-
return False
105+
return any(pkg["name"] == package_name for pkg in self.installed_packages)
83106

84107

85108
if __name__ == "__main__":

0 commit comments

Comments
 (0)