The outlines library has a prompt class like this
@dataclass
class Prompt:
"""Represents a prompt function.
We return a `Prompt` class instead of a simple function so the
template defined in prompt functions can be accessed.
"""
template: str
signature: inspect.Signature
def __post_init__(self):
self.parameters: List[str] = list(self.signature.parameters.keys())
def __call__(self, *args, **kwargs) -> str:
"""Render and return the template.
Returns
-------
The rendered template as a Python ``str``.
"""
bound_arguments = self.signature.bind(*args, **kwargs)
bound_arguments.apply_defaults()
return render(self.template, **bound_arguments.arguments)
def __str__(self):
return self.template
It has a prompt decorator like this
def prompt(fn: Callable) -> Prompt:
signature = inspect.signature(fn)
# The docstring contains the template that will be rendered to be used
# as a prompt to the language model.
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)
This seems very different from the decorators I have seen with decorator and wrapper nested functions.
If I try to use this prompt like
@prompt
def my_system_prompt():
"""This is system prompt."""
system_prompt = query_gen_system_prompt()
Pyright seems to be inferring type of system_prompt as str instead of Prompt (probably because of the call?) which is causing issues.
How do I resolve this?
>Solution :
If you reduce your problem down, you will see that Pyright is correct:
class Thing:
def __call__(self):
return 'hello, world'
def deco(fn):
return Thing()
@deco
def f():
return 'world, hello'
# returns the value for Thing.__call__
f()
hello, world
This is because, in the decorator, you are returning your class which is callable. The class is then called when you invoke the function, returning the value of __call__, which is str.
Prompt is the nested wrapper in this case, since it is technically a callable just like def wrapper(*args, **kwargs) would be in a more traditional decorator.