15

I have a function of this form:

def foo(o: "hello") -> dict:
    # pass

I understand that the "-> dict" means that foo returns a dictionary. What I don't understand is the "hello" part. Why is this type hint given as a string? What is "hello"?

Possibly relevant - this is an autogenerated file.

1
  • 3
    Usually that means that, within the scope of your code, 'hello' is a type. Commented Aug 1, 2018 at 8:57

1 Answer 1

37

type annotations sometimes need to be set before the object has been created, for example:

class Node:
    def next() -> Node:
        pass

This piece of code actually fails, because Node is referenced as an annotation of Node.next while the class Node is still being created. This is the same reason why the following fails:

class T:
    t = T()

To get around this, you can use a string instead

class Node:
    def next() -> 'Node':
        pass

so the typechecker will only evaluate Node later (a forward reference).


This was actually decided to be a design flaw so in python 3.7 you can use from __future__ import annotations and the first example will work.


Edit April 2022

So a lot has changed (and yet a lot hasn't) since this was made. The most important difference is that string annotations was deferred from py 3.10 and it sounds like it will never be stabilized. Instead the steering committee will probably end up stabilizing PEP 649 instead which has slightly more complex behavior, but still supports self-referential type hints. See the PEP for details.

Sign up to request clarification or add additional context in comments.

2 Comments

What is preferred though (Python 3.9) ?
It's a bit up in the air. annotations were deferred for 3.10. Do whichever you prefer for now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.