[Python-ideas] Structural type checking for PEP 484

Jukka Lehtosalo jlehtosalo at gmail.com
Thu Sep 10 06:34:47 CEST 2015

On Wed, Sep 9, 2015 at 3:08 PM, Andrew Barnert via Python-ideas <
python-ideas at python.org> wrote:

> On Sep 9, 2015, at 13:17, Guido van Rossum <guido at python.org> wrote:
> Jukka wrote up a proposal for structural subtyping. It's pretty good.
> Please discuss.
> https://github.com/ambv/typehinting/issues/11#issuecomment-138133867
> Are we going to continue to have (both implicit and explicit) ABCs in
> collections.abc, numbers, etc., and also have protocols that are also ABCs
> and are largely parallel to them (and implicit at static checking time
> whether they're implicit or explicit at runtime) In typing? If so, I think
> we've reached the point where the two parallel hierarchies are a problem.

I'm not proposing creating protocols for numbers or most collection types.
I'd change some of the existing ABCs (mentioned in the proposal, including
things like Sized) in typing into equivalent protocols, but they'd still
support isinstance as before and would be functionally almost identical to
the existing ABCs. I clarified the latter fact in the github issue.

> Also, why are both the terminology and implementation so different from
> what we already have for ABCs? Why not just have a decorator or metaclass
> that can be added to ABCs that makes them implicit (rather than writing a
> manual __subclasshook__ for each one), which also makes them implicit at
> static type checking time, which means there's no need for a whole separate
> but similar notion?

Protocol would use a metaclass that is derived from the ABC metaclass, and
it would be similar to the Generic class that we already have. The reason
why the proposal doesn't use an explicit metaclass or a class decorator is
consistency. It's possible to define generic protocols by having
Protocol[t, ...] as a base class, which is consistent with how Generic[...]
works. The latter is already part of typing, and introducing a similar
concept with a different syntax seems inelegant to me.

Consider a generic class:

class Bucket(Generic[T]): ...

Now we can have a generic protocol using a very similar syntax:

class BucketProtocol(Protocol[T]): ...

I wonder how we'd use a metaclass or a class decorator to represent generic
protocols. Maybe something like this:

class BucketProtocol: ...

However, this looks quite different from the Generic[...] case and thus I'd
rather not use it. I guess if we'd have picked this syntax for generic
classes it would make more sense:

class Bucket: ...

> I'm not sure why it's important to also have some times that are implicit
> at static type checking time but not at runtime, but if there is a good
> reason, that just means two different decorators/metaclasses/whatever (or a
> flag passed to the decorator, etc.). Compare:
> Hashable is an implicit ABC, Sequence is an explicit ABC, Reversible is an
> implicit-static/explicit-runtime ABC.
> Hashable is an implicit ABC and also a Protocol that's an explicit ABC,
> Sequence is an explicit ABC and not a Protocol, Reversible is a Protocol
> that's an explicit ABC.
> The first one is clearly simpler; is there some compelling reason that
> makes the second one better anyway?

I'm not sure if I fully understand what you mean by implicit vs. explicit
ABCs (and the static/runtime distinction). Could you define these terms and
maybe give some examples of each? Note that in my proposal a protocol is
just a kind of ABC, as GenericMeta is a subclass of ABCMeta and protocol
would have a similar metaclass (or maybe even the same one), even though
I'm not sure if I explicitly mentioned that. Every protocol is also an ABC.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150909/ada2d0c2/attachment.html>

More information about the Python-ideas mailing list