What’s the difference between these two functions? I’ve seen people put quotes around type annotations and other times leave them out but I couldn’t find why people choose to use one or the other.
def do_something(entity: Entity): pass def do_something(entity: 'Entity'): pass
Are there advantages or disadvantages to any of these?
Putting quotes around type hints is something that makes sense when making a Forward Reference according to PEP 484. In this case putting quotes around a name is used to subdue a NameError that would occur.
In other cases, don’t use quotes, it doesn’t result in the hint you want:
>>> def bad_foo(a: 'int'): ... pass >>> def good_foo(a: int): ... pass >>> bad_foo.__annotations__['a'] == good_foo.__annotations__['a'] False
though for now type checkers (mypy, atleast) don’t seem to treat these differently, I wouldn’t be sure if that would be the case in the future. Best to be clear and not use quotes when you actually don’t need them.
Apparently it can also cause runtime exceptions if you don’t quote them in some situations. See this comment. I have no idea why, but it definitely does:
~ python3 Python 3.9.2 (default, Mar 26 2021, 23:27:12) [Clang 12.0.0 (clang-122.214.171.124)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> def main() -> OrderedDict[str, str]: ... x: OrderedDict[str, str] = OrderedDict() ... print(x) ... return x ... Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'OrderedDict' is not defined >>> def main() -> 'OrderedDict[str, str]': ... x: OrderedDict[str, str] = OrderedDict() ... print(x) ... return x ... >>>
However you can avoid it by using
from __future__ import annotations.