[Python-Dev] Please reject or postpone PEP 526 (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Sun Sep 4 12:43:06 EDT 2016


On 4 September 2016 at 21:32, Ivan Levkivskyi <levkivskyi at gmail.com> wrote:

The first form still could be interpreted by type checkers as annotation for value (a cast to more precise type):

variable = cast(annotation, value) # visually also looks similar

I think a function based spelling needs to be discussed further, as it seems to me that at least some of the goals of the PEP could be met with a suitable definition of "cast" and "declare", with no syntactic changes to Python. Specifically, consider:

def cast(value, annotation):
    return value

def declare(annotation):
    return object()

The idea here is that "cast" would be used as a hint to type checkers to annotate an expression, with the runtime semantic impact being exactly nil - the value just gets passed through unmodified.

Annotated initialisations would then look like:

from typing import cast
primes = cast([], List[int])

class Starship:
    stats = cast({}, ClassVar[Dict[str, int]])

This preserves the relative annotation order of current type hints, where the item being annotated (parameter, function declaration, assignment statement) is on the left, and the annotation is on the right.

In cases where the typechecker is able to infer a type for the expression, it may complain here when there's a mismatch between the type inference and the explicit declaration, so these would also be a form of type assertion.

That leaves the case of declarations, where the aim is to provide a preemptive declaration that all assignments to a particular variable will include an implicit casting of the RHS. That would look like:

from typing import declare

captain = declare(str)

Until it left the scope, or saw a new target declaration, a typechecker would then interpret future assignments to "captain" as if they had been written:

captain = cast(RHS, str)

With the above definition, this would have the runtime consequence of setting "captain" to a unique object() instance until the first assignment took place. Both that assignment, and the runtime overhead of evaluating the declaration, can be avoided by moving the declaration into otherwise dead code:

if 0: captain = declare(str)

Considering the goals and problems listed in the PEP, this would be sufficient to address many of them:

For the other goals, the function-based approach may not help:

However, exploring this possibility still seems like a good idea to me, as it should allow many of the currently thorny semantic questions to be resolved, and a future syntax-only PEP for 3.7+ can just be about defining syntactic sugar for semantics that can (by then) already be expressed via appropriate initialisers.

Regards, Nick.

-- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia



More information about the Python-Dev mailing list