Search code examples
pythonpython-3.xgrammar

Why is a `lambdef` allowed as a type-hint for variables?


The Python grammar has this rule:

assignment:
    | NAME ':' expression ['=' annotated_rhs ] 
    # other options for rule omitted

while the expression rules permit a lambda definition (lambdef).

That means this python syntax is valid:

q: lambda p: p * 4 = 1

Is there a use case for permitting a lambda there, or is this just a quirk of a somewhat loose grammar? Similarly, this allows conditional types a: int if b > 3 else str = quux, which seems a bit more sane but still unexpected.


Solution

  • This is specified under the PEP-0526(Syntax for Variable Annotations). Python does not care about the annotation as long as “it evaluates without raising”. It's the duty of the type-checker to flag it as invalid annotation.

    Quoting from the PEP:

    Other uses of annotations

    While Python with this PEP will not object to:

    alice: 'well done' = 'A+'

    bob: 'what a shame' = 'F-'

    since it will not care about the type annotation beyond “it evaluates without raising”, a type checker that encounters it will flag it, unless disabled with #type: ignore or @no_type_check.

    However, since Python won’t care what the “type” is, if the above snippet is at the global level or in a class, __annotations__ will include {'alice': 'well done', 'bob': 'what a shame'}.

    These stored annotations might be used for other purposes, but with this PEP we explicitly recommend type hinting as the preferred use of annotations.

    For example, running your snippet with mypy will produce the following error:

    file.py:1: error: Invalid type comment or annotation  [valid-type]