Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Type hints for decorators

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading