[Python-Dev] Please reject or postpone PEP 526

Koos Zevenhoven k7hoven at gmail.com
Mon Sep 5 04:19:38 EDT 2016


On Mon, Sep 5, 2016 at 5:21 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 5 September 2016 at 04:40, Koos Zevenhoven <k7hoven at gmail.com> wrote:
>> On Sun, Sep 4, 2016 at 9:13 PM, Ivan Levkivskyi <levkivskyi at gmail.com> wrote:
>>> On 4 September 2016 at 19:59, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> [...]
>>>>
>>>> Similarly, it would be reasonable to say that these three snippets
>>>> should all be equivalent from a typechecking perspective:
>>>>
>>>>     x = None # type: Optional[T]
>>>>
>>>>     x: Optional[T] = None
>>>>
>>>>     x: Optional[T]
>>>>     x = None
>>>
>>>
>>> Nice idea, explicit is better than implicit.
>>
>> How is it going to help that these are equivalent within one checker,
>> if the meaning may differ across checkers?
>
> For typechecker developers, it provides absolute clarity that the
> semantics of the new annotations should match the behaviour of
> existing type comments when there's an initialiser present,

I understood that, but what's the benefit? I hope there will be a type
checker that breaks this "rule".

> or of a
> parameter annotation when there's no initialiser present.

No, your suggested addition does not provide any reference to this.
(...luckily, because that would have been worse.)

> For folks following along without necessarily keeping up with all the
> nuances, it makes it more explicit what Guido means when he says "PEP
> 526 does not make a stand on the
> behavior of type checkers (other than deferring to PEP 484)."

What you are proposing is exactly "making a stand on the behavior of
type checkers", and the examples you provide below are all variations
of the same situation and provide no justification for a general rule.

Here's a general rule:

    The closer it gets to the end of drafting a PEP [1],
    the more carefully you have to justify changes.

Justification is left as an exercise ;-).

--Koos

[1] or any document (or anything, I suppose)

> For example, the formulation of the divergent initialisation case
> where I think the preferred semantics are already implied by PEP 484
> can be looked at this way:
>
>     x = None # type: Optional[List[T]]
>     if arg is not None:
>         x = list(arg)
>         if other_arg is not None:
>             x.extend(arg)
>
> It would be a strange typechecker indeed that handled that case
> differently from the new spellings made possible by PEP 526:
>
>     x: Optional[List[T]] = None
>     if arg is not None:
>         x = list(arg)
>         if other_arg is not None:
>             x.extend(arg)
>
>     x: Optional[List[T]]
>     if arg is None:
>         x = None
>     else:
>         x = list(arg)
>         if other_arg is not None:
>             x.extend(arg)
>
>     x: Optional[List[T]]
>     if arg is not None:
>         x = list(arg)
>         if other_arg is not None:
>             x.extend(arg)
>     else:
>         x = None
>
> Or from the semantics of PEP 484 parameter annotations:
>
>     def my_func(arg:Optional[List[T]], other_arg=None):
>         # other_arg is implicitly Optional[Any]
>         if arg is not None and other_arg is not None:
>             # Here, "arg" can be assumed to be List[T]
>             # while "other_arg" is Any
>             arg.extend(other_arg)
>
> A self-consistent typechecker will either allow all of the above, or
> prohibit all of the above, while a typechecker that *isn't*
> self-consistent would be incredibly hard to use.
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



-- 
+ Koos Zevenhoven + http://twitter.com/k7hoven +


More information about the Python-Dev mailing list