On Thu, Apr 22, 2021 at 6:57 AM Paul Moore <p.f.mo...@gmail.com> wrote:
>
> On Thu, 22 Apr 2021 at 09:46, Chris Angelico <ros...@gmail.com> wrote:
> > Maybe in some cases, the "smaller protocols" option is practical, but
> > it would need to have a useful name. For instance, if it needs to be
> > readable, iterable, closeable, and autocloseable via
> > __enter__/__exit__, that's ... uhh.... a readable, iterable, closeable
> > context manager? Not an improvement over "file-like object".
>
> Note: I've not used protocols myself, so this is speculation.
>
> Is the name of the protocol important? Specifically, if I do, in my code
>
> class X(Protocol):
>     def read(self): ...
>     def __iter__(self): ...
>     def close(self): ...
>     def __enter__(self): ...
>     def __exit__(self, exc_type, exc_val, exc_tb): ...
>
> def my_fn(fileobj: X) -> None:
>     # my stuff
>

That is not a very good example of a Protocol. If you google for best
practices for interfaces in Go (#golang), you'll find they advocate
for very narrow protocols—what they call "interfaces" we decided to
call "protocols".

Many (perhaps most) protocols in the Go standard library define a single method.

I highly recommend reading up on how "interfaces" are used in Go to
reason about how "protocols" should be used in Python (*)

Cheers,

Luciano

(*) That reminded me of how I found Python. In 1998 I was using Perl,
which had just started to support classes. So in the Perl mailing
lists there were quite a few messages then about how classes were used
in Python. After a few mentions, I read the Python tutorial and never
looked back.

On Thu, Apr 22, 2021 at 6:57 AM Paul Moore <p.f.mo...@gmail.com> wrote:
>
> On Thu, 22 Apr 2021 at 09:46, Chris Angelico <ros...@gmail.com> wrote:
> > Maybe in some cases, the "smaller protocols" option is practical, but
> > it would need to have a useful name. For instance, if it needs to be
> > readable, iterable, closeable, and autocloseable via
> > __enter__/__exit__, that's ... uhh.... a readable, iterable, closeable
> > context manager? Not an improvement over "file-like object".
>
> Note: I've not used protocols myself, so this is speculation.
>
> Is the name of the protocol important? Specifically, if I do, in my code
>
> class X(Protocol):
>     def read(self): ...
>     def __iter__(self): ...
>     def close(self): ...
>     def __enter__(self): ...
>     def __exit__(self, exc_type, exc_val, exc_tb): ...
>
> def my_fn(fileobj: X) -> None:
>     # my stuff
>
> would that not work? An argument is checked to see if it conforms with
> a protocol by confirming it has the right methods, not by name,
> inheritance or registration. And if you want, you can just call X
> "FileLike", it's only a local name so it won't clash with whatever
> other people (or you, in a different module) want to say is
> "file-like". Of course, that's incredibly verbose and messy, and it
> would result in a huge proliferation of throw-away protocol classes,
> which is probably not a good practice that we'd want to encourage, but
> it works.
>
> IMO, the problem isn't that *technically* static typing excludes the
> more traditional duck typing, but rather that the design, approach and
> as a result the emerging "best practices" are focused around
> inheritance based (is that what people mean by "nominal"?) models, to
> the point where duck typing feels like an afterthought that you have
> to work to include.
>
> I wonder whether type checkers could handle a "magic" type (let's call
> it DuckTyped for now :-)) which basically means "infer a protocol
> based on usage in this function". So if I do:
>
> def my_fn(f: DuckTyped):
>     with f:
>         data = f.read()
>         for line in f:
>             print(line)
>         f.close()
>
> then the type checker would automatically build a protocol type like
> the one I defined above and use that as the type of f? That would make
> it much easier to include duck typed arguments in function signatures
> while keeping the benefits of static type checking.
>
> I will say that at the moment, this doesn't bother me much personally.
> On the larger projects where I've used typing, we've been fine with
> class-based typing and haven't really needed anything more complex
> like protocols. On smaller projects, I just don't use typing at all.
> Whether this will change if I decide to introduce typing in more
> places, I don't know at the moment. I've also not really used typing
> for public APIs, where an over-restrictive type would be more of an
> issue.
>
> Paul
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-dev@python.org/message/EQDLTZDXEE7RRFCAVCGLR5OTJOWFVXH5/
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
Luciano Ramalho
|  Author of Fluent Python (O'Reilly, 2015)
|     http://shop.oreilly.com/product/0636920032519.do
|  Technical Principal at ThoughtWorks
|  Twitter: @ramalhoorg
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/EV47IGMOVRAFAK7GCFPNCTOYEQK5SM4Z/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to