mirror of
https://github.com/muziing/Py2exe-GUI.git
synced 2025-01-27 17:02:55 +08:00
Update PyEnv
更新 `PyEnv` 模块: 极大丰富注释与文档; 初步实现 `infer_type()` 方法; 删除不必要的实例属性;
This commit is contained in:
parent
40e3941c86
commit
bc035f955b
@ -1,18 +1,28 @@
|
||||
# Licensed under the GPLv3 License: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
# For details: https://github.com/muziing/Py2exe-GUI/blob/main/README.md#license
|
||||
|
||||
"""此模块主要包含 Python 解释器环境类 `PyEnv`
|
||||
|
||||
用于存储 Python 环境的相关信息,如解释器可执行文件路径、Python 版本、已安装的包等
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Optional, Union
|
||||
|
||||
from ..Constants import PyEnvType
|
||||
from ..Utilities import get_sys_python
|
||||
|
||||
|
||||
class PyEnv:
|
||||
"""
|
||||
Python 解释器环境类,存储某个 Python 解释器对应的环境中的各种信息,如
|
||||
解释器可执行文件路径、Python 版本、已安装的包等 \n
|
||||
"""Python 解释器环境类,存储某个 Python 解释器对应的环境中的各种信息,如
|
||||
解释器可执行文件路径、Python 版本、已安装的包等
|
||||
|
||||
静态方法:
|
||||
`PyEnv.get_py_version()` 用于获取 Python 版本号,返回 "3.11.7" 形式的字符串;
|
||||
`PyEnv.get_installed_packages()` 用于获取已安装的包,返回一个包含包名和版本的列表;
|
||||
`PyEnv.infer_type()` 用于推断 Python 解释器类型,返回 PyEnvType 枚举类的成员;
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
@ -20,21 +30,26 @@ class PyEnv:
|
||||
executable_path: Union[str, Path],
|
||||
type_: Optional[PyEnvType] = PyEnvType.unknown,
|
||||
):
|
||||
self._executable_path = Path(executable_path)
|
||||
self.exe_path = str(executable_path)
|
||||
self.type = type_
|
||||
"""
|
||||
:param executable_path: Python 可执行文件路径
|
||||
:param type_: Python 解释器类型,PyEnvType 枚举类的成员。传入显式的 None 则会触发自动识别。
|
||||
"""
|
||||
|
||||
self.exe_path = str(Path(executable_path).absolute())
|
||||
self.pyversion = self.get_py_version(self.exe_path)
|
||||
self.installed_packages = self.get_installed_packages(self.exe_path)
|
||||
|
||||
if type_ is None:
|
||||
# type_ 为 None 表示特殊含义——待推断
|
||||
self.type_ = self.infer_type(self._executable_path)
|
||||
|
||||
self.pyversion = self.get_py_version(self._executable_path)
|
||||
self.installed_packages = self.get_installed_packages(self._executable_path)
|
||||
# type_ 为 None 表示特殊含义“待推断”
|
||||
self.type = self.infer_type(self.exe_path)
|
||||
else:
|
||||
self.type = type_
|
||||
|
||||
@staticmethod
|
||||
def get_py_version(executable_path: Union[str, Path]) -> str:
|
||||
"""
|
||||
获取Python解释器的版本,以形如 "3.11.7" 的字符串形式返回 \n
|
||||
"""获取Python解释器的版本,以形如 "3.11.7" 的字符串形式返回
|
||||
|
||||
:param executable_path: Python 可执行文件路径
|
||||
:return: Version of the Python interpreter, such as "3.11.7".
|
||||
"""
|
||||
|
||||
@ -52,8 +67,8 @@ class PyEnv:
|
||||
|
||||
@staticmethod
|
||||
def get_installed_packages(executable_path: Union[str, Path]) -> list[dict]:
|
||||
"""
|
||||
获取该 Python 环境中已安装的包信息 \n
|
||||
"""获取该 Python 环境中已安装的包信息
|
||||
|
||||
:param executable_path: Python 解释器可执行文件路径
|
||||
:return: 包列表,形如 [{'name': 'aiohttp', 'version': '3.9.1'}, {'name': 'aiosignal', 'version': '1.3.1'}, ...]
|
||||
"""
|
||||
@ -87,26 +102,53 @@ class PyEnv:
|
||||
|
||||
return installed_packages
|
||||
|
||||
@classmethod
|
||||
def infer_type(cls, executable_path: Union[str, Path]) -> PyEnvType:
|
||||
"""
|
||||
推断 Python 环境类型,如 venv Poetry Conda 等 \n
|
||||
@staticmethod
|
||||
def infer_type(executable_path: Union[str, Path]) -> PyEnvType:
|
||||
"""推断 Python 环境类型,如 system venv Poetry Conda 等
|
||||
|
||||
暂时仅通过解析解释器绝对路径,字符串正则匹配来判断,有待改进
|
||||
|
||||
:param executable_path: Python 可执行文件路径
|
||||
:return: PyEnvType 枚举类的成员
|
||||
"""
|
||||
|
||||
pass
|
||||
# 确保路径为 POSIX 风格的绝对路径
|
||||
exe_path = Path(executable_path).absolute().as_posix()
|
||||
|
||||
# # 使用正则表达式匹配来检测不同的环境类型
|
||||
# regexes = [
|
||||
# (r"^.*venv.*", PyEnvType.venv),
|
||||
# (r"^.*pypoetry.*", PyEnvType.poetry),
|
||||
# (r"^.*conda.*", PyEnvType.conda),
|
||||
# (
|
||||
# re.escape(f"{Path(get_sys_python()).absolute().as_posix()}"),
|
||||
# PyEnvType.system
|
||||
# )]
|
||||
# for regex, env_type in regexes:
|
||||
# match = re.search(regex, str(exe_path))
|
||||
# if match:
|
||||
# return env_type
|
||||
|
||||
# 简单的字符串 in 方法,效率应该远高于正则匹配
|
||||
match_pair = [
|
||||
("venv", PyEnvType.venv),
|
||||
("pypoetry", PyEnvType.poetry),
|
||||
("conda", PyEnvType.conda),
|
||||
(f"{Path(get_sys_python()).absolute().as_posix()}", PyEnvType.system),
|
||||
]
|
||||
|
||||
for patten, env_type in match_pair:
|
||||
if patten in exe_path:
|
||||
return env_type
|
||||
|
||||
# 如果没有匹配到,返回 unknown
|
||||
return PyEnvType.unknown
|
||||
|
||||
def pkg_installed(self, package_name: str) -> bool:
|
||||
"""
|
||||
检查特定软件包是否已安装 \n
|
||||
"""检查特定软件包是否已安装
|
||||
|
||||
:param package_name: 待检索的软件包名称
|
||||
:return: 是否已安装
|
||||
"""
|
||||
|
||||
return any(pkg["name"] == package_name for pkg in self.installed_packages)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_env = PyEnv("/usr/bin/python")
|
||||
print(test_env.pyversion)
|
||||
# print(test_env.installed_packages)
|
||||
print(test_env.pkg_installed("yaml"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user