gravitas-python
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGRAVITAS — Python Extension
GRAVITAS — Python 扩展
Extends the base GRAVITAS skill with Python-specific patterns.
Load first, then this file.
skills/gravitas/SKILL.md扩展基础 GRAVITAS skill,添加 Python 专属模式。
先加载 ,然后加载本文件。
skills/gravitas/SKILL.mdPython Recon Additions
Python 侦察补充项
□ pyproject.toml — [tool.mypy], [tool.ruff], [tool.pytest.ini_options]
□ setup.py / setup.cfg — legacy config
□ requirements.txt / requirements-dev.txt — dependency versions
□ conftest.py — pytest fixtures (critical for understanding test patterns)
□ __init__.py — package structure
□ Type stubs — are there py.typed markers? stub packages installed?□ pyproject.toml — [tool.mypy], [tool.ruff], [tool.pytest.ini_options]
□ setup.py / setup.cfg — legacy config
□ requirements.txt / requirements-dev.txt — dependency versions
□ conftest.py — pytest fixtures (critical for understanding test patterns)
□ __init__.py — package structure
□ Type stubs — are there py.typed markers? stub packages installed?Read pyproject.toml for type strictness
读取 pyproject.toml 了解类型严格程度
bash
cat pyproject.toml | grep -A 10 "\[tool.mypy\]"
cat pyproject.toml | grep -A 10 "\[tool.ruff\]"bash
cat pyproject.toml | grep -A 10 "\[tool.mypy\]"
cat pyproject.toml | grep -A 10 "\[tool.ruff\]"Python Verification Chain
Python 验证链
bash
undefinedbash
undefinedFull chain — in this order
Full chain — in this order
mypy . --strict # type correctness
ruff check . # lint (fast, Rust-based)
ruff format --check . # format check
pytest -v --tb=short # all tests
mypy . --strict # type correctness
ruff check . # lint (fast, Rust-based)
ruff format --check . # format check
pytest -v --tb=short # all tests
With coverage
With coverage
pytest --cov=src --cov-report=term-missing -v
pytest --cov=src --cov-report=term-missing -v
Type coverage
Type coverage
mypy . --strict 2>&1 | tail -5 # summary line shows error count
---mypy . --strict 2>&1 | tail -5 # summary line shows error count
---Python-Specific Anti-Patterns
Python 专属反模式
Never use bare except
except切勿使用裸 except
exceptpython
BAD: except:
GOOD: except ValueError as e:
GOOD: except (TypeError, ValueError) as e:python
BAD: except:
GOOD: except ValueError as e:
GOOD: except (TypeError, ValueError) as e:Never shadow builtins
切勿遮蔽内置函数
python
BAD: list = [1, 2, 3] # shadows list()
BAD: id = user.id # shadows id()
GOOD: items = [1, 2, 3]
GOOD: user_id = user.idpython
BAD: list = [1, 2, 3] # shadows list()
BAD: id = user.id # shadows id()
GOOD: items = [1, 2, 3]
GOOD: user_id = user.idType annotations required (with mypy strict)
必须添加类型注解(配合 mypy strict)
python
BAD: def process(data):
GOOD: def process(data: dict[str, Any]) -> ProcessResult:python
BAD: def process(data):
GOOD: def process(data: dict[str, Any]) -> ProcessResult:Use dataclasses or Pydantic over dicts for structured data
结构化数据优先使用 dataclasses 或 Pydantic,而非 dicts
python
BAD: return {"user_id": 1, "name": "Alice"} # no type safety
GOOD: return UserResponse(user_id=1, name="Alice")python
BAD: return {"user_id": 1, "name": "Alice"} # no type safety
GOOD: return UserResponse(user_id=1, name="Alice")Common Python Failure Modes
常见的 Python 故障模式
| Failure | Root Cause | Fix |
|---|---|---|
| None not handled | Add |
| Wrong return type | Check function signature |
| Not all paths return | Add explicit return |
| Wrong import | Check module with |
| Missing stub | Install |
| Circular import | Import at module level | Move to function level or restructure |
| 故障 | 根本原因 | 修复方式 |
|---|---|---|
| 未处理 None | 添加 |
| 返回类型错误 | 检查函数签名 |
| 并非所有路径都会返回 | 添加显式 return |
| 导入错误 | 使用 |
| 缺少 stub | 安装 |
| Circular import | 在模块级导入 | 移至函数级或重构 |
Test Patterns (pytest)
测试模式(pytest)
Fixture pattern
Fixture 模式
python
undefinedpython
undefinedconftest.py
conftest.py
import pytest
from myapp.db import get_db
@pytest.fixture
def db():
conn = get_db(":memory:")
yield conn
conn.close()
@pytest.fixture
def client(db):
from myapp import create_app
app = create_app({"TESTING": True})
with app.test_client() as c:
yield c
undefinedimport pytest
from myapp.db import get_db
@pytest.fixture
def db():
conn = get_db(":memory:")
yield conn
conn.close()
@pytest.fixture
def client(db):
from myapp import create_app
app = create_app({"TESTING": True})
with app.test_client() as c:
yield c
undefinedStandard test structure
标准测试结构
python
class TestUserAuth:
def test_login_success(self, client, db):
# Arrange
db.execute("INSERT INTO users VALUES (1, 'alice', 'hash')")
# Act
response = client.post("/login", json={"username": "alice", "password": "pw"})
# Assert
assert response.status_code == 200
assert response.json["token"] is not None
def test_login_wrong_password(self, client, db):
response = client.post("/login", json={"username": "alice", "password": "wrong"})
assert response.status_code == 401python
class TestUserAuth:
def test_login_success(self, client, db):
# Arrange
db.execute("INSERT INTO users VALUES (1, 'alice', 'hash')")
# Act
response = client.post("/login", json={"username": "alice", "password": "pw"})
# Assert
assert response.status_code == 200
assert response.json["token"] is not None
def test_login_wrong_password(self, client, db):
response = client.post("/login", json={"username": "alice", "password": "wrong"})
assert response.status_code == 401Parametrize for edge cases
使用 Parametrize 覆盖边界情况
python
@pytest.mark.parametrize("input,expected", [
("", ValueError),
(None, TypeError),
("valid@email.com", None),
("not-an-email", ValueError),
])
def test_validate_email(input, expected):
if expected:
with pytest.raises(expected):
validate_email(input)
else:
validate_email(input) # should not raisepython
@pytest.mark.parametrize("input,expected", [
("", ValueError),
(None, TypeError),
("valid@email.com", None),
("not-an-email", ValueError),
])
def test_validate_email(input, expected):
if expected:
with pytest.raises(expected):
validate_email(input)
else:
validate_email(input) # should not raiseFramework-Specific Notes
框架专属说明
FastAPI
FastAPI
python
undefinedpython
undefinedAlways test with TestClient, not raw function calls
Always test with TestClient, not raw function calls
from fastapi.testclient import TestClient
client = TestClient(app)
from fastapi.testclient import TestClient
client = TestClient(app)
Type all path/query params and bodies
Type all path/query params and bodies
@router.post("/users", response_model=UserResponse)
async def create_user(body: CreateUserRequest) -> UserResponse:
...
undefined@router.post("/users", response_model=UserResponse)
async def create_user(body: CreateUserRequest) -> UserResponse:
...
undefinedDjango
Django
python
undefinedpython
undefinedUse pytest-django
Use pytest-django
settings for tests
settings for tests
@pytest.mark.django_db
def test_user_creation():
user = User.objects.create_user(username="test", password="pass")
assert user.id is not None
---@pytest.mark.django_db
def test_user_creation():
user = User.objects.create_user(username="test", password="pass")
assert user.id is not None
---Quick Reference
快速参考
bash
undefinedbash
undefinedRun single test file
Run single test file
pytest src/auth/test_session.py -v
pytest src/auth/test_session.py -v
Run single test
Run single test
pytest src/auth/test_session.py::TestSession::test_timeout -v
pytest src/auth/test_session.py::TestSession::test_timeout -v
Run with pdb on failure
Run with pdb on failure
pytest --pdb
pytest --pdb
Show slowest tests
Show slowest tests
pytest --durations=10
pytest --durations=10
Type check single file
Type check single file
mypy src/auth/session.py --strict
undefinedmypy src/auth/session.py --strict
undefined