本地与GitHub Action中Mypy检查结果不一致问题排查
问题
我为Python代码配置了GitHub Action和pre-commit钩子,两者均使用Mypy 1.7.0版本,依赖包、配置参数完全一致。pre-commit执行Mypy检查无报错,但GitHub Action却提示sum_total_size_query需要类型注解,且本地执行GitHub Action的Mypy命令也无报错,请问如何实现两者行为一致?
GitHub Action配置文件
name: Mypy on: [push] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.11"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | pip install "mypy==1.7.0" "pydantic>=2.4" "alembic>=1.8.1" "types-aiofiles>=23.2.0" "types-redis>=4.6.0" --quiet - name: Running mypy checks run: | mypy . --ignore-missing-imports --config-file backend/app/mypy.ini
pre-commit配置文件
repos: - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.7.0 hooks: - id: mypy args: [--ignore-missing-imports, --config-file, backend/app/mypy.ini] verbose: true additional_dependencies: - "pydantic>=2.4" - "alembic>=1.8.1" - "types-aiofiles>=23.2.0" - "types-redis>=4.6.0"
待检查代码
async def total_monthly_size(self, user_id: int) -> int: now = utcnow() current_month = datetime(now.year, now.month, 1) sum_total_size_query = select(func.sum(self.model.total_size or self.model.estimated_total_size)).where( self.model.user_id == user_id, self.model.is_failed.is_(False), self.model.requested_at > current_month, ) sum_total_size_result = await self._db.execute(sum_total_size_query) sum_total_size = sum_total_size_result.scalar() return int(sum_total_size or 0)
报错信息
error: Need type annotation for "sum_total_size_query" [var-annotated]
解决方案
以下是几种可行的修复方案,按优先级排序:
1. 统一检查范围,验证本地pre-commit行为
pre-commit默认仅检查暂存区的文件,而GitHub Action会检查仓库内所有文件。如果代码修改未被暂存,pre-commit不会触发对应检查:
- 运行
pre-commit run --all-files模拟GitHub Action的全量检查,确认是否会出现相同报错 - 若希望pre-commit默认检查所有文件,可在mypy钩子中添加
pass_filenames: false参数:hooks: - id: mypy # 其他参数不变 pass_filenames: false
2. 补全SQLAlchemy类型依赖
sum_total_size_query是SQLAlchemy的查询对象,Mypy需要对应的类型存根才能自动推断其类型。当前配置缺失types-sqlalchemy依赖,导致GitHub Action的干净环境中无法推断类型:
- 更新GitHub Action的依赖安装命令:
pip install "mypy==1.7.0" "pydantic>=2.4" "alembic>=1.8.1" "types-aiofiles>=23.2.0" "types-redis>=4.6.0" "types-sqlalchemy>=2.0.23" --quiet - 更新pre-commit的
additional_dependencies:additional_dependencies: - "pydantic>=2.4" - "alembic>=1.8.1" - "types-aiofiles>=23.2.0" - "types-redis>=4.6.0" - "types-sqlalchemy>=2.0.23"
3. 清除pre-commit缓存
pre-commit会缓存钩子的运行环境,可能导致依赖未更新:
- 运行
pre-commit clean清除缓存,然后重新执行pre-commit检查
4. 显式添加类型注解(兜底方案)
如果不想依赖类型存根,直接给变量添加明确的类型注解,确保Mypy在任何环境下都能识别:
from sqlalchemy import Select # ... sum_total_size_query: Select[int] = select(func.sum(self.model.total_size or self.model.estimated_total_size)).where( self.model.user_id == user_id, self.model.is_failed.is_(False), self.model.requested_at > current_month, )
内容的提问来源于stack exchange,提问作者taras
相关产品推荐
相关产品推荐

