abtbb 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- abtbb-0.0.1/.gitignore +25 -0
- abtbb-0.0.1/LICENSE +21 -0
- abtbb-0.0.1/PKG-INFO +111 -0
- abtbb-0.0.1/README.md +88 -0
- abtbb-0.0.1/abt/__init__.py +1 -0
- abtbb-0.0.1/abt/py.typed +0 -0
- abtbb-0.0.1/abt/utils/__init__.py +1 -0
- abtbb-0.0.1/pyproject.toml +160 -0
abtbb-0.0.1/.gitignore
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
|
|
10
|
+
# 工具缓存
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.coverage
|
|
15
|
+
htmlcov/
|
|
16
|
+
|
|
17
|
+
# 本地配置(含密钥,绝不入库)
|
|
18
|
+
.env
|
|
19
|
+
.env.*
|
|
20
|
+
!.env.example
|
|
21
|
+
|
|
22
|
+
# IDE
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
.DS_Store
|
abtbb-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 yayo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
abtbb-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: abtbb
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: abt:一个自己也能读懂、自己也能维护的 Python 底层工具包
|
|
5
|
+
Project-URL: Homepage, https://github.com/yanyue/abt
|
|
6
|
+
Author: yayo
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: library,toolkit,utility
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.7
|
|
20
|
+
Requires-Dist: typing-extensions<4.8,>=4.0; python_version < '3.8'
|
|
21
|
+
Requires-Dist: typing-extensions>=4.0; python_version >= '3.8'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# abt
|
|
25
|
+
|
|
26
|
+
> 一个自己也能读懂、自己也能维护的 Python 底层工具包。
|
|
27
|
+
|
|
28
|
+
## 这是什么
|
|
29
|
+
|
|
30
|
+
`abt` 是对既有工具包 `apiboot` 的**从零重写**。
|
|
31
|
+
|
|
32
|
+
`apiboot` 的功能是 OK 的,但它几乎全部由 AI 生成:代码量涨得很快,却没有一个字是「自己先想清楚再落笔」的。结果是大量冗余封装、过度抽象,作者本人也读不懂——下游项目一旦出问题,除了「再问一次 AI」没有第二条路。
|
|
33
|
+
|
|
34
|
+
`abt` 重写它,**验收标准不是功能跑通,而是作者本人能在不询问任何 AI 的情况下,读懂并定位任意一个函数的实现与问题。**
|
|
35
|
+
|
|
36
|
+
## 两条硬规则
|
|
37
|
+
|
|
38
|
+
1. **不包装 stdlib**。`pathlib` / `datetime` / `json` 能直接用就直接用,只在语义上做了收敛或增强时才封装。
|
|
39
|
+
2. **一次只做一个模块**。每个函数要能一句话说清,docstring 写「为什么」和「不变量」,不写「做了什么」。
|
|
40
|
+
|
|
41
|
+
## 特色:第三方依赖全部懒加载
|
|
42
|
+
|
|
43
|
+
`abt` 的**运行时第三方依赖为零**。
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install abt # 不会顺带装 requests / sqlalchemy / redis
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `import abt` 和 `import abt.<任意子模块>` **绝不会**因为环境里缺某个第三方包而报错。
|
|
50
|
+
- 只有真正**调用到**用到它的那个函数时才会失败,报错信息里会写清楚缺哪个包、为什么要装它、`pip install` 命令是什么。
|
|
51
|
+
|
|
52
|
+
换句话说,装了不炸;缺依赖在调用点才暴露,而不是在 import 阶段就让整个服务起不来。
|
|
53
|
+
|
|
54
|
+
## 运行环境
|
|
55
|
+
|
|
56
|
+
- **Python 3.7+**(最低 3.7;开发环境 3.11)
|
|
57
|
+
- 3.7 的语法下限由 `vermin` 把关:`uv run vermin --target=3.7- --violations abt/` 必须始终通过
|
|
58
|
+
|
|
59
|
+
## 设计文档
|
|
60
|
+
|
|
61
|
+
完整的出发点、验收标准、`apiboot` 模块构成、已知坑位清单、重写路线图,都在 [CLAUDE.md](CLAUDE.md) 里。
|
|
62
|
+
|
|
63
|
+
## 安装
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
uv add abtbb
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from abt import logger
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
> **发布名 ≠ import 名。** PyPI 上的 `abt` 已被他人占用,所以发布名用 `abtbb`;但 import 名仍是 `abt`——它由包目录名决定,跟发布名无关。
|
|
74
|
+
> (`pip install pillow` → `import PIL` 同理。)
|
|
75
|
+
|
|
76
|
+
本地开发:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
uv sync # 装依赖(含 dev group:pytest / mypy / ruff / vermin)
|
|
80
|
+
uv run pytest # 跑测试
|
|
81
|
+
uv run mypy abt # 静态检查
|
|
82
|
+
uv run ruff check .
|
|
83
|
+
uv run vermin --target=3.7- --violations abt/ # Python 3.7 语法下限闸门
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 命令行
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
abtrun --help
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
> 命令名用 `abtrun` 而非 `abt`——`abt` 已被 `apiboot` 的 CLI 占用,两个包共存时会互相覆盖 PATH。
|
|
93
|
+
|
|
94
|
+
## 发布到 PyPI
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv sync # 装齐工具链(含 twine)
|
|
98
|
+
python scripts/upload_pypi.py # 构建 + 输入 token + 确认上传
|
|
99
|
+
python scripts/upload_pypi.py --dry-run # 只构建, 不上传, 不用输 token
|
|
100
|
+
python scripts/upload_pypi.py --repository testpypi # 先发测试仓库试水
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
流程:清理旧 `dist/` → 重新构建 sdist + wheel → 预检版本号是否已存在 → 提示输入 PyPI API Token(输入不回显,不落盘不进 shell history)→ 询问 `y/n` 确认 → 上传。
|
|
104
|
+
|
|
105
|
+
Token 申请:<https://pypi.org/manage/account/token/>,用户名固定 `__token__`。
|
|
106
|
+
|
|
107
|
+
> 同一版本号不能重复发布,报错前请把 `pyproject.toml` 里的 `version` 改大一位。
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
abtbb-0.0.1/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# abt
|
|
2
|
+
|
|
3
|
+
> 一个自己也能读懂、自己也能维护的 Python 底层工具包。
|
|
4
|
+
|
|
5
|
+
## 这是什么
|
|
6
|
+
|
|
7
|
+
`abt` 是对既有工具包 `apiboot` 的**从零重写**。
|
|
8
|
+
|
|
9
|
+
`apiboot` 的功能是 OK 的,但它几乎全部由 AI 生成:代码量涨得很快,却没有一个字是「自己先想清楚再落笔」的。结果是大量冗余封装、过度抽象,作者本人也读不懂——下游项目一旦出问题,除了「再问一次 AI」没有第二条路。
|
|
10
|
+
|
|
11
|
+
`abt` 重写它,**验收标准不是功能跑通,而是作者本人能在不询问任何 AI 的情况下,读懂并定位任意一个函数的实现与问题。**
|
|
12
|
+
|
|
13
|
+
## 两条硬规则
|
|
14
|
+
|
|
15
|
+
1. **不包装 stdlib**。`pathlib` / `datetime` / `json` 能直接用就直接用,只在语义上做了收敛或增强时才封装。
|
|
16
|
+
2. **一次只做一个模块**。每个函数要能一句话说清,docstring 写「为什么」和「不变量」,不写「做了什么」。
|
|
17
|
+
|
|
18
|
+
## 特色:第三方依赖全部懒加载
|
|
19
|
+
|
|
20
|
+
`abt` 的**运行时第三方依赖为零**。
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install abt # 不会顺带装 requests / sqlalchemy / redis
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `import abt` 和 `import abt.<任意子模块>` **绝不会**因为环境里缺某个第三方包而报错。
|
|
27
|
+
- 只有真正**调用到**用到它的那个函数时才会失败,报错信息里会写清楚缺哪个包、为什么要装它、`pip install` 命令是什么。
|
|
28
|
+
|
|
29
|
+
换句话说,装了不炸;缺依赖在调用点才暴露,而不是在 import 阶段就让整个服务起不来。
|
|
30
|
+
|
|
31
|
+
## 运行环境
|
|
32
|
+
|
|
33
|
+
- **Python 3.7+**(最低 3.7;开发环境 3.11)
|
|
34
|
+
- 3.7 的语法下限由 `vermin` 把关:`uv run vermin --target=3.7- --violations abt/` 必须始终通过
|
|
35
|
+
|
|
36
|
+
## 设计文档
|
|
37
|
+
|
|
38
|
+
完整的出发点、验收标准、`apiboot` 模块构成、已知坑位清单、重写路线图,都在 [CLAUDE.md](CLAUDE.md) 里。
|
|
39
|
+
|
|
40
|
+
## 安装
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv add abtbb
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from abt import logger
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> **发布名 ≠ import 名。** PyPI 上的 `abt` 已被他人占用,所以发布名用 `abtbb`;但 import 名仍是 `abt`——它由包目录名决定,跟发布名无关。
|
|
51
|
+
> (`pip install pillow` → `import PIL` 同理。)
|
|
52
|
+
|
|
53
|
+
本地开发:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv sync # 装依赖(含 dev group:pytest / mypy / ruff / vermin)
|
|
57
|
+
uv run pytest # 跑测试
|
|
58
|
+
uv run mypy abt # 静态检查
|
|
59
|
+
uv run ruff check .
|
|
60
|
+
uv run vermin --target=3.7- --violations abt/ # Python 3.7 语法下限闸门
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 命令行
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
abtrun --help
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
> 命令名用 `abtrun` 而非 `abt`——`abt` 已被 `apiboot` 的 CLI 占用,两个包共存时会互相覆盖 PATH。
|
|
70
|
+
|
|
71
|
+
## 发布到 PyPI
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
uv sync # 装齐工具链(含 twine)
|
|
75
|
+
python scripts/upload_pypi.py # 构建 + 输入 token + 确认上传
|
|
76
|
+
python scripts/upload_pypi.py --dry-run # 只构建, 不上传, 不用输 token
|
|
77
|
+
python scripts/upload_pypi.py --repository testpypi # 先发测试仓库试水
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
流程:清理旧 `dist/` → 重新构建 sdist + wheel → 预检版本号是否已存在 → 提示输入 PyPI API Token(输入不回显,不落盘不进 shell history)→ 询问 `y/n` 确认 → 上传。
|
|
81
|
+
|
|
82
|
+
Token 申请:<https://pypi.org/manage/account/token/>,用户名固定 `__token__`。
|
|
83
|
+
|
|
84
|
+
> 同一版本号不能重复发布,报错前请把 `pyproject.toml` 里的 `version` 改大一位。
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# -*- coding:UTF-8 -*-
|
abtbb-0.0.1/abt/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# -*- coding:UTF-8 -*-
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
# ⚠️ 这是【PyPI 发布名】, 不是 import 名。
|
|
7
|
+
# 发布名用 `abtbb` —— PyPI 上的 `abt` 已被他人注册, 不能再用, 否则下游
|
|
8
|
+
# `pip install abt` 会装到别人的包(供应链安全问题)。
|
|
9
|
+
#
|
|
10
|
+
# 发布名与 import 名是两套独立命名空间, 标准做法是二者不同:
|
|
11
|
+
# pip install abtbb → import abt
|
|
12
|
+
# import 名由下面 [tool.hatch.build.targets.wheel].packages 指定的
|
|
13
|
+
# 目录名决定, 与本字段无关。改发布名只需改本字段一行。
|
|
14
|
+
#
|
|
15
|
+
# 注意 PyPI 名称归一化: abtbb / abt-bb / abt_bb 是同一个项目。
|
|
16
|
+
# 发布前请先确认目标名未被占用:
|
|
17
|
+
# curl -s -o /dev/null -w "%{http_code}\n" https://pypi.org/pypi/<name>/json
|
|
18
|
+
name = "abtbb"
|
|
19
|
+
version = "0.0.1"
|
|
20
|
+
description = "abt:一个自己也能读懂、自己也能维护的 Python 底层工具包"
|
|
21
|
+
readme = "README.md"
|
|
22
|
+
requires-python = ">=3.7"
|
|
23
|
+
license = { text = "MIT" }
|
|
24
|
+
authors = [{ name = "yayo" }]
|
|
25
|
+
keywords = ["toolkit", "utility", "library"]
|
|
26
|
+
classifiers = [
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3.7",
|
|
29
|
+
"Programming Language :: Python :: 3.8",
|
|
30
|
+
"Programming Language :: Python :: 3.9",
|
|
31
|
+
"Programming Language :: Python :: 3.10",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
"License :: OSI Approved :: MIT License",
|
|
35
|
+
"Operating System :: OS Independent",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
# 运行时依赖 —— 刻意保持为零。
|
|
40
|
+
#
|
|
41
|
+
# abt 的核心特色: 所有第三方包都是【懒加载】的。
|
|
42
|
+
# pip install abtbb 之后, `import abt` 和 import 任意子模块都【绝不】因为
|
|
43
|
+
# 环境里没装 requests / sqlalchemy / redis 而报错;
|
|
44
|
+
# 只有真正调用到用到它的那个函数时才会失败, 并在报错里告诉用户装什么。
|
|
45
|
+
#
|
|
46
|
+
# 所以下面这份列表里只允许出现两类东西:
|
|
47
|
+
# 1) 纯类型兼容层 (typing_extensions) —— 3.7~3.9 没有 typing.Protocol 等
|
|
48
|
+
# 2) 真正的标准库替代品 —— 目前没有
|
|
49
|
+
# 新增可选第三方库时: 写进 [dependency-groups].dev (供 IDE 解析 import),
|
|
50
|
+
# 由使用方自己 pip install, 【不要】加进本段。
|
|
51
|
+
# ---------------------------------------------------------------------------
|
|
52
|
+
dependencies = [
|
|
53
|
+
# ⚠️ marker 必须覆盖到 3.9(即 < '3.10'), 不能只写 < '3.8'。
|
|
54
|
+
# typing.Protocol / get_args / get_origin 是 3.8+, typing.Annotated 是 3.9+,
|
|
55
|
+
# typing.ParamSpec 是 3.10+ —— 写窄了 3.8/3.9 环境直接 ModuleNotFoundError。
|
|
56
|
+
#
|
|
57
|
+
# 3.7 单独写死上限: typing_extensions 4.8.0 起要求 >=3.8,
|
|
58
|
+
# 3.7 最高只能用 4.7.1。显式写出来, 不依赖 uv 的版本 fork 行为。
|
|
59
|
+
"typing_extensions>=4.0,<4.8; python_version < '3.8'",
|
|
60
|
+
"typing_extensions>=4.0; python_version >= '3.8'",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[project.urls]
|
|
64
|
+
Homepage = "https://github.com/yanyue/abt"
|
|
65
|
+
|
|
66
|
+
# CLI 入口: pip install abtbb 后进入 PATH。
|
|
67
|
+
# 命令名用 `abtrun`, 不用 `abt` —— `abt` 已被 apiboot 的 [project.scripts] 占用,
|
|
68
|
+
# 两个包共存时 PATH 上的 `abt` 会互相覆盖。
|
|
69
|
+
# ⚠️ 注意: 命令名是【全局】的, 不像包名有 PyPI 命名空间保护。
|
|
70
|
+
# 发布前确认 `abtrun` 不会和别人撞名: `which -a abtrun`
|
|
71
|
+
[project.scripts]
|
|
72
|
+
abtrun = "abt.cli:main"
|
|
73
|
+
|
|
74
|
+
# 只打包 abt/ 包目录 —— 这一行决定了【import 名】是 abt。
|
|
75
|
+
# scripts/、tests/、examples/、.venv/ 永远不会进 wheel。
|
|
76
|
+
# .env 显式排除, 防止本地 token 泄露 (白名单 + 黑名单双保险)。
|
|
77
|
+
[tool.hatch.build.targets.wheel]
|
|
78
|
+
packages = ["abt"]
|
|
79
|
+
exclude = [".env", ".env.*", ".envrc"]
|
|
80
|
+
|
|
81
|
+
[tool.hatch.build.targets.sdist]
|
|
82
|
+
include = ["abt", "README.md", "pyproject.toml", "LICENSE"]
|
|
83
|
+
exclude = ["scripts", "tests", "examples", ".venv", ".idea", ".env", ".env.*", ".envrc"]
|
|
84
|
+
|
|
85
|
+
# dev 依赖: `uv sync` 时随 dev group 一起装, 不影响 `pip install abtbb` 的用户。
|
|
86
|
+
#
|
|
87
|
+
# 这个 group 同时承担两个职责:
|
|
88
|
+
# 1) 开发工具链 (pytest / mypy / ruff / vermin)
|
|
89
|
+
# 2) 【所有可选第三方库都列在这里】—— 装上后 IDE/Pylance 才能解析这些
|
|
90
|
+
# `import`, 不再报红; 运行时用户装什么版本就用什么版本, 一个都不装也能跑。
|
|
91
|
+
#
|
|
92
|
+
# ⚠️ 每条都带 `python_version >= '3.8'` marker, 原因:
|
|
93
|
+
# uv sync 做的是 universal resolution —— 会为 requires-python 覆盖到的
|
|
94
|
+
# 每一个 Python 版本(含 3.7)各求一次解。dev 工具链【不需要】跑在 3.7 上,
|
|
95
|
+
# 但只要它们参与 3.7 的求解, 就会因为新版 pytest / python-dotenv / twine
|
|
96
|
+
# 都要求 >=3.8 而直接 "No solution found"。
|
|
97
|
+
# 加上 marker 后, 3.7 的求解里只剩运行时依赖, 立刻有解。
|
|
98
|
+
# 运行时依赖(typing_extensions)仍然正常覆盖 3.7 —— 这是 3.7 兼容性的关键。
|
|
99
|
+
[dependency-groups]
|
|
100
|
+
dev = [
|
|
101
|
+
# 开发 / 发布
|
|
102
|
+
"build; python_version >= '3.8'",
|
|
103
|
+
"twine; python_version >= '3.8'",
|
|
104
|
+
# 测试
|
|
105
|
+
"pytest>=7.4.4; python_version >= '3.8'",
|
|
106
|
+
# 静态检查
|
|
107
|
+
"mypy>=1.4.1; python_version >= '3.8'",
|
|
108
|
+
"ruff>=0.1.0; python_version >= '3.8'",
|
|
109
|
+
# Python 3.7 兼容性闸门 (mypy >=1.5 已不支持把 3.7 当 target, 改用 vermin)
|
|
110
|
+
"vermin>=1.6.0; python_version >= '3.8'",
|
|
111
|
+
# ---- 可选第三方库 (运行时懒加载, 这里只为了 IDE 能解析 import) ----
|
|
112
|
+
# 配置模块
|
|
113
|
+
"python-dotenv>=1.0.0; python_version >= '3.8'",
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
# 使用阿里 PyPI 镜像加速装包(国内开发)
|
|
117
|
+
[tool.uv]
|
|
118
|
+
index-url = "https://mirrors.aliyun.com/pypi/simple/"
|
|
119
|
+
# `uv sync` 默认装 dev group, 免得每次都要 --group dev
|
|
120
|
+
default-groups = ["dev"]
|
|
121
|
+
|
|
122
|
+
[tool.pytest.ini_options]
|
|
123
|
+
testpaths = ["tests"]
|
|
124
|
+
python_files = ["test_*.py"]
|
|
125
|
+
|
|
126
|
+
[tool.mypy]
|
|
127
|
+
# ⚠️ 不写 python_version: mypy >=1.5 已拒绝 `--python-version 3.7`。
|
|
128
|
+
# Python 3.7 的语法下限改由下面的 vermin 把关, mypy 只管类型正确性。
|
|
129
|
+
strict = true
|
|
130
|
+
warn_unused_ignores = true
|
|
131
|
+
show_error_codes = true
|
|
132
|
+
warn_unreachable = true
|
|
133
|
+
# 第三方库缺类型标注时不要连带报错
|
|
134
|
+
[[tool.mypy.overrides]]
|
|
135
|
+
module = ["apscheduler.*", "redis.*", "fakeredis.*"]
|
|
136
|
+
ignore_missing_imports = true
|
|
137
|
+
|
|
138
|
+
[tool.ruff]
|
|
139
|
+
line-length = 100
|
|
140
|
+
# Python 3.7 语法下限。ruff 若在某个版本里不再接受 py37, 改成 py38 即可 ——
|
|
141
|
+
# 真正的下限闸门是上面的 vermin, ruff 这里只用来管现代化改写建议。
|
|
142
|
+
target-version = "py37"
|
|
143
|
+
|
|
144
|
+
[tool.ruff.lint]
|
|
145
|
+
select = ["E", "F", "W", "I", "UP", "B", "C4", "SIM"]
|
|
146
|
+
ignore = ["E501"]
|
|
147
|
+
|
|
148
|
+
[tool.ruff.lint.per-file-ignores]
|
|
149
|
+
# 测试里允许长断言行、允许未使用的 fixture 参数
|
|
150
|
+
"tests/*" = ["E501", "B011"]
|
|
151
|
+
|
|
152
|
+
# Python 3.7 兼容性的唯一闸门: 静态算出每个文件/特性需要的最低 Python 版本。
|
|
153
|
+
# 命令: uv run vermin --target=3.7- --violations abt/
|
|
154
|
+
[tool.vermin]
|
|
155
|
+
target = "3.7-"
|
|
156
|
+
violations = true
|
|
157
|
+
# 评估字符串注解。默认 vermin 把注解当字符串、不求值, 于是 `int | None` (PEP 604,
|
|
158
|
+
# 3.10+) 这类写法会被漏掉。但 pydantic / SQLModel 的模型类【会】在类定义时求值注解,
|
|
159
|
+
# 3.7 上直接 TypeError —— 所以这里必须开启, 宁可误报也不能漏报。
|
|
160
|
+
eval-annotations = true
|