Outlines库Prompt装饰器类型提示问题:Pyright误判如何解决?
问题:Outlines库Prompt装饰器的类型推断问题
Outlines库的Prompt类实现了__call__方法,调用时会返回字符串;而prompt装饰器直接返回Prompt实例,而非常见的嵌套函数结构。当按如下方式使用时:
@prompt def my_system_prompt(): """This is system prompt.""" system_prompt = my_system_prompt()
Pyright会将system_prompt的类型推断为str,如果开发者期望保留Prompt实例而非渲染后的字符串,就会引发类型匹配问题。
解决方案
1. 直接保留Prompt实例(推荐)
如果不需要立即渲染模板,不要调用装饰后的函数,直接赋值即可:
@prompt def my_system_prompt(): """This is system prompt.""" # 直接保留Prompt实例,跳过调用步骤 system_prompt = my_system_prompt
此时Pyright会正确推断system_prompt的类型为Prompt,后续可按需调用它生成字符串。
2. 修改Prompt类设计(需修改库代码)
如果需要调用实例但仍保留Prompt类型,可以调整__call__方法的职责,新增专门的渲染方法:
from dataclasses import dataclass import inspect from typing import List, Callable, cast # 假设render是库中已存在的模板渲染函数 def render(template: str, **kwargs) -> str: return template.format(**kwargs) @dataclass class Prompt: template: str signature: inspect.Signature def __post_init__(self): self.parameters: List[str] = list(self.signature.parameters.keys()) self.bound_args = None def __call__(self, *args, **kwargs) -> "Prompt": """绑定参数并返回自身,不直接渲染""" self.bound_args = self.signature.bind(*args, **kwargs) self.bound_args.apply_defaults() return self def render(self) -> str: """专门的渲染方法,返回字符串结果""" if not self.bound_args: self.bound_args = self.signature.bind() self.bound_args.apply_defaults() return render(self.template, **self.bound_args.arguments) def __str__(self): return self.template def prompt(fn: Callable) -> Prompt: signature = inspect.signature(fn) docstring = fn.__doc__ if docstring is None: raise TypeError("Could not find a template in the function's docstring.") template = cast(str, docstring) return Prompt(template, signature)
使用方式:
@prompt def my_system_prompt(name: str): """Hello, {name}!""" # 调用后仍得到Prompt实例 system_prompt = my_system_prompt("Alice") # 需要字符串时调用render方法 prompt_str = system_prompt.render()
3. 显式类型注解(仅类型检查层面生效)
如果必须调用且无法修改库代码,可通过显式类型注解强制指定变量类型,但需注意运行时实际值仍为字符串:
from typing import cast @prompt def my_system_prompt(): """This is system prompt.""" # 强制指定类型(仅用于类型检查,运行时system_prompt仍是字符串) system_prompt = cast(Prompt, my_system_prompt())
⚠️ 注意:这种方法仅能骗过类型检查器,若后续调用Prompt类的方法会触发运行时错误,仅适用于特殊场景。
内容的提问来源于stack exchange,提问作者Vikash Balasubramanian
相关产品推荐
相关产品推荐

