From 190699b4470a85121e1e478752d047937f80924d Mon Sep 17 00:00:00 2001 From: pluvium27 Date: Mon, 4 May 2026 13:55:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=AE=97=E6=B3=95=E8=83=BD?= =?UTF-8?q?=E8=A2=AB=E8=87=AA=E5=8A=A8=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 4 +- README.md | 76 ++++++++----------- data/config/services/audio.toml | 2 +- pyproject.toml | 20 ++--- requirements.txt | 1 - src/heurams/__main__.py | 4 +- src/heurams/kernel/algorithms/__init__.py | 29 +++----- src/heurams/kernel/algorithms/base.py | 9 +++ src/heurams/kernel/algorithms/nsp0.py | 2 +- src/heurams/kernel/algorithms/sm2.py | 2 +- uv.lock | 91 ++++++++++------------- 11 files changed, 101 insertions(+), 139 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c676379..4477447 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,7 +70,7 @@ uv sync --all-extras # 同步开发运行环境 uv run heurams # 验证包安装 -uv run tui # 启动 TUI +uv run heurams-tui # 启动 TUI # 如果决定使用原生 python 环境 (不推荐, 但我们保留了这种方式以便在不便支持 uv 与硬链接的环境和文件系统(例如 termux)运行 HeurAMS) @@ -79,7 +79,7 @@ python3 -m pip install -r requirements.txt python3 -m pip install -e . python3 -m heurams # 验证安装 -python3 -m heurams.__interface__ # 启动 TUI +python3 -m heurams.interface # 启动 TUI ``` ## 许可证与外部引用 diff --git a/README.md b/README.md index c263eff..1cd9925 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,14 @@ ## 项目结构 -这个仓库是 "潜进" 的核心程序库在 python 语言下的实现 +此仓库为 "潜进" 的核心程序库在 python 语言下的实现 包含数据模型与框架, 并内置了基于 textual 框架的前端实现 (interface 子模块) 除了通过内置前端进行学习外, 开发者也能在 python 环境中导入 `heurams` 库或使用 `RPC` 与 `heurams` 程序库实例通讯, 使用框架构建其他辅助记忆功能前端或其他应用程序 > [!NOTE] > 我们已经开始着手于基于 KDE 用户界面框架 `Kirigami` 的现代跨平台前端开发, 称作 "KiriMemo", 包名是 "org.kde.kirimemo", 但其并非 KDE 项目 -> 它通过 `PyOtherSide` 直接复用 python 内核, 为 Windows, Linux, macOS, Android 和 Plasma Mobile 提供现代用户界面 -> 如果您善于开发 C++, QML, Qt 与 KDE 框架, 欢迎加入到 KiriMemo 项目的开发 +> 它通过 `PyOtherSide` 直接复用 python 内核, 为 Windows, Linux, macOS, Android 和 Plasma Mobile 提供现代用户界面 +> 如果您善于开发 C++, QML, Qt 与 KDE 框架, 欢迎加入到 KiriMemo 项目的开发 ## 特性 @@ -57,19 +57,22 @@ 潜进(heurams) 处于早期开发考虑, 尚未上架 PyPI, 但您可以用我们的基础设施安装稳定版和开发版本. +#### 稳定版本 + +``` +python -m pip install heurams[basic] -i https://pypi.pluv27.top/root/stable/+simple/ # 安装适用于用户体验的可选依赖(推荐) +``` +``` +python -m pip install heurams[audio-playsound] -i https://pypi.pluv27.top/root/stable/+simple/ # 安装适用于一般计算机的通用音频模块(不适用于 termux, termux 的音频支持是内建的) +``` + +#### 开发版本 + > [!CAUTION] > 对于部分 Linux 发行版和 Android Termux 用户: > 您需要先行安装 `cmake` 和 `libzmq` 才能正确安装项目的 `zmq` 依赖 > 例如在 termux 上先运行 `pkg install cmake clang libzmq` -> 项目功能本身不依赖它, 但需要该依赖用于启动可选的调试服务器 - -#### 稳定版本 - -``` -python -m pip install heurams[all] -i https://pypi.pluv27.top/root/stable/+simple/ # 安装全部可选依赖(推荐) -``` - -#### 开发版本 +> 项目功能本身不依赖它, 但需要该依赖用于启动可选的调试服务器 ``` python -m pip install heurams[all] -i https://pypi.pluv27.top/root/dev/+simple/ # 安装全部可选依赖(推荐) @@ -79,34 +82,21 @@ python -m pip install heurams[all] -i https://pypi.pluv27.top/root/dev/+simple/ 由于部分依赖只被少数功能需要, 所以我们把可选依赖分得比较细, 前面提供的命令会安装所有可选依赖, 以下是依赖组列表 -- 基础依赖: (只能驱动程序库) - - tabulate: 终端表格生成 - - toml: TOML 文件加载 - - transitions: 状态机依赖 -- `interface` 依赖组: (基本用户界面依赖) - - textual: 终端用户界面 - - psutil: 获取系统信息 -- `algo-fsrs` 依赖组: - - py-fsrs: FSRS 算法模块需要 -- `tts-edgetts` 依赖组: - - edge-tts:微软文本转语音 -- `misc-jieba` 依赖组: - - jieba: 中文智能分词所需 -- `llm-openai` 依赖组: - - openai: OpenAI API 所需 -- `audio-playsound` 依赖组: - - playsound: 通用音频播放 - - pygobject: playsound 依赖 -- `dev` 依赖组: - - zmq: 远程调试服务器所需 - - pytest: 测试所需 - - pytest-cov: 测试所需 -- `all` 依赖组: - - 包含以上所有依赖 +| 依赖组 | 包含模块 | 说明 | +|--------|----------|------| +| 最小化安装 | tabulate, toml, transitions | 核心驱动程序库,始终必需 | +| interface | textual, psutil | 基本用户界面依赖 | +| algo-fsrs | py-fsrs | FSRS 算法模块 | +| tts-edgetts | edge-tts | 微软文本转语音 | +| llm | openai | OpenAI API 调用 | +| audio-playsound | playsound, pygobject | 通用音频播放及依赖 | +| dev | zmq, pytest, pytest-cov | 开发调试与测试工具 | +| basic | [tts-edgetts], [llm-openai], [algo-fsrs] | 适用于用户体验的较轻依赖组(推荐) | +| all | 以上所有依赖 | 完整安装组 | ### 从源码安装 -我们提供原生 python 和 uv 两种安装方式.\ +我们提供原生 python 和 uv 两种安装方式. 详见[贡献指南](CONTRIBUTING.md). ## 项目结构 @@ -115,7 +105,8 @@ python -m pip install heurams[all] -i https://pypi.pluv27.top/root/dev/+simple/ ## 参与项目 -欢迎参与到项目协作中! 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解贡献指南. +欢迎参与到项目协作中! +请参阅[贡献指南](CONTRIBUTING.md). ## 许可证 @@ -128,15 +119,6 @@ python -m pip install heurams[all] -i https://pypi.pluv27.top/root/dev/+simple/ 项目在 `src/heurams/vendor/` 目录下嵌入或在其他位置间接使用了以下第三方代码(可能有修改): -#### py-fsrs (open-spaced-repetition) - -- 上游版本: 6.3.1 -- 引用方式: vendor -- 位置: `src/heurams/vendor/pyfsrs/` -- 原项目: [py-fsrs](https://github.com/open-spaced-repetition/py-fsrs) -- 原版权: Copyright (c) 2026 Open Spaced Repetition Contributors -- 原许可证: MIT License - #### SM.js (slaypni) - 上游版本: commit `6e3bb4afaf484426deb4a9fa3bcffe42ac066b45` (2015年2月4日上游已停止维护) diff --git a/data/config/services/audio.toml b/data/config/services/audio.toml index ac42f77..abf97a9 100644 --- a/data/config/services/audio.toml +++ b/data/config/services/audio.toml @@ -2,7 +2,7 @@ provider = "playsound" _provider_desc = "音频驱动类型" [_provider_candidate] -playsound = "python 跨平台音频系统" +playsound = "Python 桌面跨平台音频系统, 使用了 playsound3 替代了老旧的 playsound" termux = "Android Termux 音频系统" mpg123 = "通用音频系统, 依赖系统 mpg123" pulseaudio = "高级音频路由系统" diff --git a/pyproject.toml b/pyproject.toml index baaa567..b2b1f67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,29 +29,24 @@ algo-fsrs = [ tts-edgetts = [ "edge-tts>=7.2.8", # 微软 TTS ] -misc-jieba = [ - "jieba>=0.42.1", # 用于中文智能分词 -] -llm-openai = [ - "openai>=2.32.0", -] +llm = ["openai>=2.32.0"] audio-playsound = [ - "playsound==1.2.2", - "pygobject>=3.56.2", # playsound 依赖它 + "playsound3==3.3.1", + #"pygobject>=3.56.2", # playsound 依赖它 ] dev = [ # 调试所需依赖 - "zmq>=0.0.0", # 用于 ZMQ 远程调试服务器, 在 linux 上建议先安装 libzmq - "pytest>=8.0.0", # 用于普通测试 + "zmq>=0.0.0", # 用于 ZMQ 远程调试服务器, 在 linux 上建议先安装 libzmq + "pytest>=8.0.0", # 用于普通测试 "pytest-cov>=6.0.0", ] all = [ "heurams[algo-fsrs]", "heurams[tts-edgetts]", - "heurams[misc-jieba]", - "heurams[llm-openai]", + "heurams[llm]", "heurams[audio-playsound]", "heurams[dev]", ] +basic = ["heurams[algo-fsrs]", "heurams[tts-edgetts]", "heurams[llm]"] [project.urls] Homepage = "https://ams.pluv.top" @@ -59,7 +54,6 @@ Issues = "https://github.com/heurams/heurams/issues" [project.scripts] heurams = "heurams.__main__:main" -tui = "heurams.interface.__main__:main" heurams-tui = "heurams.interface.__main__:main" [tool.pytest.ini_options] diff --git a/requirements.txt b/requirements.txt index f172b4a..38e0d15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ edge-tts==7.0.2 -jieba==0.42.1 openai==1.0.0 playsound==1.2.2 tabulate>=0.9.0 diff --git a/src/heurams/__main__.py b/src/heurams/__main__.py index a68b5e7..8c9c913 100644 --- a/src/heurams/__main__.py +++ b/src/heurams/__main__.py @@ -12,8 +12,8 @@ python 代指您使用的解释器, 在某些发行版中可能是 python3, 而 尽管项目保留了 requirements.txt, 我们仍不推荐使用系统 python 和原始 venv 进行开发. 项目的推荐开发环境工具是 uv. 如果你的环境已经安装了 uv: - 先运行 uv sync 同步环境, 此命令只需要执行一遍, uv 会自动处理依赖. - 然后通过运行 uv run tui 启动内置基本用户界面. + 先运行 uv sync --all-extras 同步环境, 此命令只需要执行一遍, uv 会自动处理依赖. + 然后通过运行 uv run heurams-tui 启动内置基本用户界面. 此时您的解释器在项目目录里的 .venv/bin 中, 使用 IDE 开发前, 务必切换解释器! 注意: 一个常见的误区是, 执行 interface 下的 __main__.py 运行基本用户界面, 这会导致 Python 上下文环境异常, 请不要这样做.""" print(prompt) diff --git a/src/heurams/kernel/algorithms/__init__.py b/src/heurams/kernel/algorithms/__init__.py index 6461b06..7634458 100644 --- a/src/heurams/kernel/algorithms/__init__.py +++ b/src/heurams/kernel/algorithms/__init__.py @@ -1,21 +1,14 @@ +import importlib +import pkgutil +from pathlib import Path + from .base import BaseAlgorithm -from .sm2 import SM2Algorithm -from .sm15m import SM15MAlgorithm -from .nsp0 import NSP0Algorithm -from .fsrs import FSRSAlgorithm -__all__ = [ - "SM2Algorithm", - "BaseAlgorithm", - "SM15MAlgorithm", - "NSP0Algorithm", - "FSRSAlgorithm", -] +__path__ = [str(Path(__file__).parent)] -algorithms = { - "SM-2": SM2Algorithm, - "NSP-0": NSP0Algorithm, - "SM-15M": SM15MAlgorithm, - "FSRS": FSRSAlgorithm, - "Base": BaseAlgorithm, -} +for _finder, _name, _ispkg in pkgutil.iter_modules(__path__): + if _name == "base": + continue + importlib.import_module(f".{_name}", __package__) + +algorithms = BaseAlgorithm.get_registry() \ No newline at end of file diff --git a/src/heurams/kernel/algorithms/base.py b/src/heurams/kernel/algorithms/base.py index 85d184e..3960ae1 100644 --- a/src/heurams/kernel/algorithms/base.py +++ b/src/heurams/kernel/algorithms/base.py @@ -5,11 +5,20 @@ from heurams.services.logger import get_logger logger = get_logger(__name__) +_registry: dict[str, type["BaseAlgorithm"]] = {} class BaseAlgorithm: algo_name = "BaseAlgorithm" desc = "算法基类" + def __init_subclass__(cls, **kwargs): + super().__init_subclass__(**kwargs) + _registry[cls.algo_name] = cls + + @classmethod + def get_registry(cls) -> dict[str, type["BaseAlgorithm"]]: + return dict(_registry) + class AlgodataDict(TypedDict): real_rept: int rept: int diff --git a/src/heurams/kernel/algorithms/nsp0.py b/src/heurams/kernel/algorithms/nsp0.py index cf8933a..6c4cacd 100644 --- a/src/heurams/kernel/algorithms/nsp0.py +++ b/src/heurams/kernel/algorithms/nsp0.py @@ -10,7 +10,7 @@ logger = get_logger(__name__) class NSP0Algorithm(BaseAlgorithm): algo_name = "NSP-0" - desc = "快速筛选用特殊调度器" + desc = "快速筛选用非间隔重复调度器" class AlgodataDict(TypedDict): real_rept: int diff --git a/src/heurams/kernel/algorithms/sm2.py b/src/heurams/kernel/algorithms/sm2.py index bb8d187..2c7a34f 100644 --- a/src/heurams/kernel/algorithms/sm2.py +++ b/src/heurams/kernel/algorithms/sm2.py @@ -10,7 +10,7 @@ logger = get_logger(__name__) class SM2Algorithm(BaseAlgorithm): algo_name = "SM-2" - desc = "经典间隔重复算法" + desc = "SuperMemo2 (1987) 简单间隔重复调度器" class AlgodataDict(TypedDict): efactor: float diff --git a/uv.lock b/uv.lock index 3c80a4d..3c5ba2d 100644 --- a/uv.lock +++ b/uv.lock @@ -450,17 +450,19 @@ algo-fsrs = [ all = [ { name = "edge-tts" }, { name = "fsrs" }, - { name = "jieba" }, { name = "openai" }, - { name = "playsound" }, - { name = "pygobject" }, + { name = "playsound3" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "zmq" }, ] audio-playsound = [ - { name = "playsound" }, - { name = "pygobject" }, + { name = "playsound3" }, +] +basic = [ + { name = "edge-tts" }, + { name = "fsrs" }, + { name = "openai" }, ] dev = [ { name = "pytest" }, @@ -471,12 +473,9 @@ interface = [ { name = "psutil" }, { name = "textual" }, ] -llm-openai = [ +llm = [ { name = "openai" }, ] -misc-jieba = [ - { name = "jieba" }, -] tts-edgetts = [ { name = "edge-tts" }, ] @@ -486,16 +485,16 @@ requires-dist = [ { name = "edge-tts", marker = "extra == 'tts-edgetts'", specifier = ">=7.2.8" }, { name = "fsrs", marker = "extra == 'algo-fsrs'", specifier = ">=6.3.1" }, { name = "heurams", extras = ["algo-fsrs"], marker = "extra == 'all'" }, + { name = "heurams", extras = ["algo-fsrs"], marker = "extra == 'basic'" }, { name = "heurams", extras = ["audio-playsound"], marker = "extra == 'all'" }, { name = "heurams", extras = ["dev"], marker = "extra == 'all'" }, - { name = "heurams", extras = ["llm-openai"], marker = "extra == 'all'" }, - { name = "heurams", extras = ["misc-jieba"], marker = "extra == 'all'" }, + { name = "heurams", extras = ["llm"], marker = "extra == 'all'" }, + { name = "heurams", extras = ["llm"], marker = "extra == 'basic'" }, { name = "heurams", extras = ["tts-edgetts"], marker = "extra == 'all'" }, - { name = "jieba", marker = "extra == 'misc-jieba'", specifier = ">=0.42.1" }, - { name = "openai", marker = "extra == 'llm-openai'", specifier = ">=2.32.0" }, - { name = "playsound", marker = "extra == 'audio-playsound'", specifier = "==1.2.2" }, + { name = "heurams", extras = ["tts-edgetts"], marker = "extra == 'basic'" }, + { name = "openai", marker = "extra == 'llm'", specifier = ">=2.32.0" }, + { name = "playsound3", marker = "extra == 'audio-playsound'", specifier = "==3.3.1" }, { name = "psutil", marker = "extra == 'interface'", specifier = ">=7.2.2" }, - { name = "pygobject", marker = "extra == 'audio-playsound'", specifier = ">=3.56.2" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, { name = "tabulate", specifier = ">=0.10.0" }, @@ -504,7 +503,7 @@ requires-dist = [ { name = "transitions", specifier = ">=0.9.3" }, { name = "zmq", marker = "extra == 'dev'", specifier = ">=0.0.0" }, ] -provides-extras = ["interface", "algo-fsrs", "tts-edgetts", "misc-jieba", "llm-openai", "audio-playsound", "dev", "all"] +provides-extras = ["interface", "algo-fsrs", "tts-edgetts", "llm", "audio-playsound", "dev", "all", "basic"] [[package]] name = "httpcore" @@ -552,12 +551,6 @@ wheels = [ { url = "https://mirrors.ustc.edu.cn/pypi/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] -[[package]] -name = "jieba" -version = "0.42.1" -source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } -sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/c6/cb/18eeb235f833b726522d7ebed54f2278ce28ba9438e3135ab0278d9792a2/jieba-0.42.1.tar.gz", hash = "sha256:055ca12f62674fafed09427f176506079bc135638a14e23e25be909131928db2", size = 19214172, upload-time = "2020-01-20T14:27:23.5Z" } - [[package]] name = "jiter" version = "0.14.0" @@ -817,11 +810,15 @@ wheels = [ ] [[package]] -name = "playsound" -version = "1.2.2" +name = "playsound3" +version = "3.3.1" source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } +dependencies = [ + { name = "pywin32", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/6b/93/39f2296a69fe2c70dcc9b9724147ffc9d7f676f67eb3cbad3baa725ae32d/playsound3-3.3.1.tar.gz", hash = "sha256:3f0eb87d5ff2061d07663c4b010b8e7d66c274344712b01d561a0a73447ef41d", size = 608340, upload-time = "2026-01-22T18:05:55.444Z" } wheels = [ - { url = "https://mirrors.ustc.edu.cn/pypi/packages/f5/16/10d897b0a83fb4b05b03a63d7a2667ab75f857f67f7062fd447dd3f49bf7/playsound-1.2.2-py2.py3-none-any.whl", hash = "sha256:1e83750a5325cbccee03d6e751ba3e78c037ac95b95a3ba1f38d0c5aca9e1a34", size = 5960, upload-time = "2017-06-29T14:08:29.207Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/62/9d/8b97af915bd8a9e2b17b08bb9d62d45cce5c00a28a64b08324bb5895145b/playsound3-3.3.1-py3-none-any.whl", hash = "sha256:8e606115c3630762a7136579ceb25fbf725768a31f7d0bfc2883154d8c50205d", size = 9697, upload-time = "2026-01-22T18:05:53.783Z" }, ] [[package]] @@ -945,25 +942,6 @@ wheels = [ { url = "https://mirrors.ustc.edu.cn/pypi/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, ] -[[package]] -name = "pycairo" -version = "1.29.0" -source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } -sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/22/d9/1728840a22a4ef8a8f479b9156aa2943cd98c3907accd3849fb0d5f82bfd/pycairo-1.29.0.tar.gz", hash = "sha256:f3f7fde97325cae80224c09f12564ef58d0d0f655da0e3b040f5807bd5bd3142", size = 665871, upload-time = "2025-11-11T19:13:01.584Z" } -wheels = [ - { url = "https://mirrors.ustc.edu.cn/pypi/packages/f6/28/6363087b9e60af031398a6ee5c248639eefc6cc742884fa2789411b1f73b/pycairo-1.29.0-cp312-cp312-win32.whl", hash = "sha256:91bcd7b5835764c616a615d9948a9afea29237b34d2ed013526807c3d79bb1d0", size = 751486, upload-time = "2025-11-11T19:11:54.451Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/3a/d2/d146f1dd4ef81007686ac52231dd8f15ad54cf0aa432adaefc825475f286/pycairo-1.29.0-cp312-cp312-win_amd64.whl", hash = "sha256:3f01c3b5e49ef9411fff6bc7db1e765f542dc1c9cfed4542958a5afa3a8b8e76", size = 845383, upload-time = "2025-11-11T19:12:01.551Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/01/16/6e6f33bb79ec4a527c9e633915c16dc55a60be26b31118dbd0d5859e8c51/pycairo-1.29.0-cp312-cp312-win_arm64.whl", hash = "sha256:eafe3d2076f3533535ad4a361fa0754e0ee66b90e548a3a0f558fed00b1248f2", size = 694518, upload-time = "2025-11-11T19:12:06.561Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/f0/21/3f477dc318dd4e84a5ae6301e67284199d7e5a2384f3063714041086b65d/pycairo-1.29.0-cp313-cp313-win32.whl", hash = "sha256:3eb382a4141591807073274522f7aecab9e8fa2f14feafd11ac03a13a58141d7", size = 750949, upload-time = "2025-11-11T19:12:12.198Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/43/34/7d27a333c558d6ac16dbc12a35061d389735e99e494ee4effa4ec6d99bed/pycairo-1.29.0-cp313-cp313-win_amd64.whl", hash = "sha256:91114e4b3fbf4287c2b0788f83e1f566ce031bda49cf1c3c3c19c3e986e95c38", size = 844149, upload-time = "2025-11-11T19:12:19.171Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/15/43/e782131e23df69e5c8e631a016ed84f94bbc4981bf6411079f57af730a23/pycairo-1.29.0-cp313-cp313-win_arm64.whl", hash = "sha256:09b7f69a5ff6881e151354ea092137b97b0b1f0b2ab4eb81c92a02cc4a08e335", size = 693595, upload-time = "2025-11-11T19:12:23.445Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/2d/fa/87eaeeb9d53344c769839d7b2854db7ff2cd596211e00dd1b702eeb1838f/pycairo-1.29.0-cp314-cp314-win32.whl", hash = "sha256:69e2a7968a3fbb839736257bae153f547bca787113cc8d21e9e08ca4526e0b6b", size = 767198, upload-time = "2025-11-11T19:12:42.336Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/3c/90/3564d0f64d0a00926ab863dc3c4a129b1065133128e96900772e1c4421f8/pycairo-1.29.0-cp314-cp314-win_amd64.whl", hash = "sha256:e91243437a21cc4c67c401eff4433eadc45745275fa3ade1a0d877e50ffb90da", size = 871579, upload-time = "2025-11-11T19:12:48.982Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/5e/91/93632b6ba12ad69c61991e3208bde88486fdfc152be8cfdd13444e9bc650/pycairo-1.29.0-cp314-cp314-win_arm64.whl", hash = "sha256:b72200ea0e5f73ae4c788cd2028a750062221385eb0e6d8f1ecc714d0b4fdf82", size = 719537, upload-time = "2025-11-11T19:12:55.016Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/93/23/37053c039f8d3b9b5017af9bc64d27b680c48a898d48b72e6d6583cf0155/pycairo-1.29.0-cp314-cp314t-win_amd64.whl", hash = "sha256:5e45fce6185f553e79e4ef1722b8e98e6cde9900dbc48cb2637a9ccba86f627a", size = 874015, upload-time = "2025-11-11T19:12:28.47Z" }, - { url = "https://mirrors.ustc.edu.cn/pypi/packages/d7/54/123f6239685f5f3f2edc123f1e38d2eefacebee18cf3c532d2f4bd51d0ef/pycairo-1.29.0-cp314-cp314t-win_arm64.whl", hash = "sha256:caba0837a4b40d47c8dfb0f24cccc12c7831e3dd450837f2a356c75f21ce5a15", size = 721404, upload-time = "2025-11-11T19:12:36.919Z" }, -] - [[package]] name = "pycparser" version = "3.0" @@ -1072,15 +1050,6 @@ wheels = [ { url = "https://mirrors.ustc.edu.cn/pypi/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] -[[package]] -name = "pygobject" -version = "3.56.2" -source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } -dependencies = [ - { name = "pycairo" }, -] -sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/a2/80/09247a2be28af2c2240132a0af6c1005a2b1d089242b13a2cd782d2de8d7/pygobject-3.56.2.tar.gz", hash = "sha256:b816098969544081de9eecedb94ad6ac59c77e4d571fe7051f18bebcec074313", size = 1409059, upload-time = "2026-03-25T16:14:04.008Z" } - [[package]] name = "pytest" version = "9.0.3" @@ -1111,6 +1080,22 @@ wheels = [ { url = "https://mirrors.ustc.edu.cn/pypi/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, ] +[[package]] +name = "pywin32" +version = "311" +source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } +wheels = [ + { url = "https://mirrors.ustc.edu.cn/pypi/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" }, + { url = "https://mirrors.ustc.edu.cn/pypi/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" }, +] + [[package]] name = "pyzmq" version = "27.1.0"