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/