如何禁止向特定函数传入f-string?含Pylint检测方案需求
解决方案:强制
summary参数为静态字符串 一、代码层面的强制约束
1. 字符串字面量类型提示(Python 3.10+)
Python 3.10引入的LiteralString类型(从typing导入),可以直接限定参数只能接受静态字符串字面量,f-string、动态拼接字符串等都会触发类型检查报错。
示例代码:
from typing import LiteralString def report_test_data(summary: LiteralString, details: str) -> None: # 函数实现逻辑 pass # 合法调用 report_test_data(summary="condition met", details=f"{component} ended with {state}") # 非法调用(类型检查工具会报错) report_test_data(summary=f"{component} ended with {state} - condition met", details="")
2. 运行时验证
如果需要在代码运行阶段强制校验,可以借助ast和inspect模块,检查传入的summary是否为静态字面量:
import ast import inspect def is_literal_string(s: str) -> bool: frame = inspect.currentframe().f_back if not frame: return False source = inspect.getsource(frame) tree = ast.parse(source) for node in ast.walk(tree): if isinstance(node, ast.Call) and getattr(node.func, 'id', '') == 'report_test_data': for kw in node.keywords: if kw.arg == 'summary': return isinstance(kw.value, ast.Constant) and isinstance(kw.value.value, str) return False def report_test_data(summary: str, details: str) -> None: if not is_literal_string(summary): raise ValueError("summary必须是静态字符串字面量,不能传入动态生成的字符串") # 后续业务逻辑
二、Pylint自定义检测规则
通过编写Pylint插件,可以在代码检查阶段就拦截不符合规范的调用。
1. 编写插件代码
创建pylint_static_summary.py文件:
from astroid import nodes from pylint.checkers import BaseChecker from pylint.interfaces import IAstroidChecker class StaticSummaryChecker(BaseChecker): __implements__ = IAstroidChecker name = 'static-summary' priority = -1 msgs = { 'E9999': ( 'summary参数必须为静态字符串字面量', 'non-static-summary', '当report_test_data的summary参数传入动态字符串时触发', ), } def visit_call(self, node: nodes.Call) -> None: if hasattr(node.func, 'name') and node.func.name == 'report_test_data': for kw in node.keywords: if kw.arg == 'summary': if not isinstance(kw.value, nodes.Const) or not isinstance(kw.value.value, str): self.add_message('non-static-summary', node=kw.value) def register(linter): linter.register_checker(StaticSummaryChecker(linter))
2. 启用插件
在项目的.pylintrc中添加配置:
[MASTER] load-plugins=pylint_static_summary
或者直接在命令行指定插件运行:
pylint --load-plugins=pylint_static_summary your_test_code.py
触发违规时,Pylint会抛出E9999错误提示。
三、优化的预定义方案:枚举类
如果之前用普通类维护summary字符串太繁琐,可以改用枚举类,既保证静态性,又便于扩展和维护:
from enum import Enum class TestSummary(Enum): CONDITION_MET = "condition met" CONDITION_NOT_MET = "condition not met" # 新增测试状态直接在这里添加即可 def report_test_data(summary: TestSummary, details: str) -> None: print(f"Summary: {summary.value}, Details: {details}") # 调用方式 report_test_data(summary=TestSummary.CONDITION_MET, details=f"{component} ended with {state}")
这种方式还能借助IDE自动补全减少拼写错误,比普通类更易用。
内容的提问来源于stack exchange,提问作者tigerninjaman
相关产品推荐
相关产品推荐

