Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protocols #417

Closed
wants to merge 19 commits into from
Closed

Protocols #417

wants to merge 19 commits into from

Conversation

ilevkivskyi
Copy link
Member

Fixes #11

This is a runtime implementation of protocols as per draft PEP 544. (The mypy counterpart is python/mypy#3132)

The implementation is straightforward (mostly I just made current version to behave more similar to __subclasshook__ in collections.abc and added support for __annotations__ in Python 3.6).
Nevertheless, I add a lot of tests. Some of them may look trivial, but previous experience with generics shows that it is better to have them.

There is probably only one corner case worth noting. Consider this situation with for variable annotations:

@runtime
class Proto(Protocol):
    attr: int
class OtherProto(Protocol):
    attr: int
class BadConcrete:
    attr: int
class GoodConcrete:
    attr = 1

Then I propose the following subclass check results:

issubclass(GoodConcrete, Proto) == True
issubclass(BadConcrete, Proto) == False # This is a bit questionable, maybe return True?
issubclass(OtherProto, Proto) == True

The first one is probably obvious, the second one returns False to make this safe:

if issubclass(BadConcrete, Proto):
    BadConcrete().attr

The last one although safe since one cannot instantiate protocols, and this is probably what one would expect.

Attn: @JukkaL @ambv @gvanrossum

@ilevkivskyi
Copy link
Member Author

ilevkivskyi commented May 10, 2017

Something strange happened here (or maybe the comment was deleted), but here is an interesting note to make: because of how NamedTuple behaves at runtime (just making a collectios.namedtuple) it implements corresponding protocols already at the class level, for example:

@runtime
class P(Protocol):
    x: int
class N(NamedTuple):
    x: int

assert issubclass(N, P)  # OK

@Daenyth
Copy link

Daenyth commented May 10, 2017

I left a comment that I realized was completely incorrect so I deleted it

@ilevkivskyi ilevkivskyi mentioned this pull request May 16, 2017
@ilevkivskyi
Copy link
Member Author

I will soon make another PR that will add (simplified) Protocol to typing_extensions. We cannot add
all the functionality while Protocol will be in typing_extensions since several classes (like SupportsInt etc.) subclass _Protocol in typing, ideally they should subclass the new Protocol, this is however quite minor thing.

I will keep this PR open (and update depending on the outcome of experiments with typing_extensions).

ilevkivskyi added a commit to ilevkivskyi/typehinting that referenced this pull request Aug 19, 2017
@gvanrossum
Copy link
Member

So IIUC we should first merge #464 and defer this one until the PEP has been accepted, right?

@ilevkivskyi
Copy link
Member Author

So IIUC we should first merge #464 and defer this one until the PEP has been accepted, right?

Yes, also if there will be something we discover while playing with typing_extensions, I will update this PR accordingly (actually there are already few minor tweaks that I need to make here following the review of #464).

@ilevkivskyi
Copy link
Member Author

This was superseded by #649

@ilevkivskyi ilevkivskyi deleted the protocols branch June 18, 2019 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Protocols (a.k.a. structural subtyping)
4 participants