My personal motivating example for PEP 637 was shorthand for protocols.
`x: Protocol[foo=int, bar=Callable[str, int]]` could say x has attribute
foo which is an int and method bar from str to int.



On Wed, Apr 21, 2021 at 4:23 PM Paul Bryan <pbr...@anode.ca> wrote:

> I agree, that's duck typing with a protocol, and precisely the tedious
> type style I would want to avoid.
>
> I don't know what would be a good suggestion. Something where you
> reference a "fully equipped" type and cherry pick the attributes you want?
> Something like `Protocol[Duck, ("quack", "waddle")]`?
>
> Paul
>
>
> On Wed, 2021-04-21 at 16:13 -0700, Jelle Zijlstra wrote:
>
>
>
> El mié, 21 abr 2021 a las 15:30, Paul Bryan (<pbr...@anode.ca>) escribió:
>
> As demonstrated, protocols don't get us there because duck typing isn't a
> matter of having an object exhibit all of the attributes of a duck, but
> rather some subset of attributes to be used by the consumer. I want this
> duck to quack; someone else will want it to waddle. I don't see how type
> hints could reasonably support "file like object" in the duck type sense
> (unless the consumer were to specify the exact attributes of the duck it's
> interested in, which I fear would become a tedious type writing style). '
>
>
> This approach (a Protocol that declares exactly what you need the
> file-like object to do) is in fact what we've been doing in typeshed, the
> repository that provides type hints for the standard library. For those
> unfamiliar, it would look something like this:
>
> from typing import Protocol
>
> class SupportsRead(Protocol):
>     def read(self) -> bytes: ...
>
> def uses_a_file(f: SupportsRead) -> None:
>      f.read()
>
> That's somewhat tedious, to be sure, but it is working duck typing.
>
>
>
> I too have sensed static typing driving the typing development agenda in
> Python recently, causing other typing methods to take a back seat, so to
> speak. I add my voice to those requesting Python handle other typing
> methods.
>
> Barring an innovation to allow a "subset" of a type to be declared in a
> type hint, I would conclude that static typing and duck typing are
> diametrically opposed. If we agree that both are valuable, developers could
> build consensus on that point, and work to ensure that one does not move
> forward at the expense of the other.
>
> What would you suggest? Should the syntax for declaring Protocols be more
> concise?
>
>
>
> Paul
>
> On Wed, 2021-04-21 at 12:36 -0700, Christopher Barker wrote:
>
> Thanks Mark for posting this. I know some of us are uneasy about the pace
> of the typing train ....
>
> On Tue, Apr 20, 2021 at 11:20 AM Nathaniel Smith <n...@pobox.com> wrote:
>
> > If you guarded your code with `isinstance(foo, Sequence)` then I could
> > not use it with my `Foo` even if my `Foo` quacked like a sequence. I was
> > forced to use nominal typing; inheriting from Sequence, or explicitly
> > registering as a Sequence.
>
> You say this like it's a bad thing, but how is this avoidable, even in
> principle? Structural typing lets you check whether Foo is duck-shaped
> -- has appropriate attribute names, etc. But quacking like a duck is
> harder: you also have to implement the Sequence behavioral contract,
> and realistically the only way to know that is if the author of Foo
> tells you.
>
>
> But that's not what duck typing is (at least to me :-) ) For a given
> function, I need the passed in object to quack (and yes, I need that quack
> to sound like a duck) -- but I usually don't care whether that object
> waddles like a duck.
>
> So yes, isinstance(obj, Sequence) is really the only way to know that obj
> is a Sequence in every important way -- but if you only need it to do one
> or two things like a Sequence, then you don't care.
>
> And this is not uncommon -- I suspect it's very rare for a single function
> to use most of the methods of a given ABC (or protocol, or whatever).
>
> And a lot of the standard library works exactly this way. Two examples
> (chosen arbitrarily, I just happen to have thought about how they work):
>
> json.load() simply calls ``fp.read()``, and passes the result on down to
> json.loads(). That's it -- no checking of anything.
>
> If fp does not have a read() method, you get an AttributeError. If fp has
> a read() method, but it returns something other than a string, then you get
> some other Exception. And if it returns a string, but that string isn't
> valid JSON, you get yet another kind of error.
>
> In short, json.load(fp, ...) requires fp to have a read() method that
> returns a valid JSON string. But it doesn't check, nor does it need to, if
> it's getting an actual io.TextIOBase object. Is that the right one? I'm not
> totally sure, which I kind of think makes my point -- I've been using
> "file-like" objects for years (decades) without worrying about it.
>
> Example 2:
>
> The str.translate method takes:
>
> "a mapping of Unicode ordinals to Unicode ordinals, strings, or None"
>
> Ok, then you need to pass in a Mapping, yes? Well, no you don't. The docs
> go on to say:
>
> The table must implement lookup/indexing via __getitem__, for instance a
> dictionary or list.
>
> Ah -- so we don't need a Mapping -- we need anything indexable by an
> integer that contains "ordinals, strings, or None". What the heck ABC could
> we use for that?
>
> The ABCs do have an already complex hierarchy of containers, but there is
> no "Indexable", (quacks) and certainly no "indexable and returns these
> particular things. (quacks a certain way). (maybe there's something in the
> typing module that would work for static typing -- I have no idea).
>
> I'm pretty sure this particular API was designed to accommodate the old
> py2 str.translate, which took a length-256 sequence, while also
> accommodating full Unicode, which would have required a 2^32 length
> sequence to do the same thing :-)
>
> But again -- this is duck typing, built into the stdlib, and it works
> just fine.
>
> Granted, until PEP 563 (kind of) , there has been nothing that weakens or
> disallows such duck typing -- those of us that want to write fully
> duck-typed code can continue to do so.
>
> But there is the "culture" of Python -- and it has been very much shifting
> toward more typing -- A recent publication (sorry can't find it now -- my
> google fu is failing me) examined code on PyPi and found a lot of type
> hints -- many of which were apparently not being used with a static type
> checker. So why were they there?
>
> And I've seen a lot more isinstance(Some_ABC) code lately as well.
>
> From looking at the work of my beginning students, I can tell that they
> are seeing examples out there that use more typing, to the point that they
> think it's a best practice (or maybe even required?). Maybe it is -- but if
> the community is moving that way, we should be honest about it.
>
>
> I'm not even sure that this *is* nominal typing. You could just as
> well argue that "the operation `isinstance(..., Sequence)` returns
> `True`" is just another of the behavioral constraints that are
> required to quack like a sequence.
>
>
> I'm not sure of the definition of "nominal" typing -- but it absolutely is
> NOT duck typing (As Luciano pointed out, Alex Martelli coined the term
> Goose Typing for this).
>
> The big distinction is whether we want to know if the object is a duck, or
> if we only need it to do one or two things like a duck.
>
> -CHB
>
>
> _______________________________________________
> 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/ZXI3RTBVW44WGX44D4OFSH6GXL3SYPVO/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
> _______________________________________________
> 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/PDW6UUK2QFS3J6B6SIQGUE2E7J7IELIS/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
> _______________________________________________
> 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/HY6XET253F6XCSZGPNXESYL3KPOUXI6E/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
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/22F733O3KADULPVRDQPHZBTOGMIOYMQF/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to