I think what Christopher says is fair. My question (with little understanding of the underlying infrastructure) is can we define a 'type' that communicates that? Something like 'object that implements .read', or '.upper and .__iter__ for a spring-like object's?

toonarmycaptain 







-------- Original message --------
From: python-dev-request@python.org
Date: 4/21/21 2:44 PM (GMT-06:00)
To: python-dev@python.org
Subject: Python-Dev Digest, Vol 213, Issue 128

Send Python-Dev mailing list submissions to
        python-dev@python.org

To subscribe or unsubscribe via the World Wide Web, visit
        https://mail.python.org/mailman3/lists/python-dev.python.org/
or, via email, send a message with subject or body 'help' to
        python-dev-request@python.org

You can reach the person managing the list at
        python-dev-owner@python.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Python-Dev digest..."

Today's Topics:

   1. Re: PEP 654: Exception Groups and except* [REPOST]
      (srkunze@mail.de)
   2. Re: PEP 654: Exception Groups and except* [REPOST]
      (Yury Selivanov)
   3. Re: Keeping Python a Duck Typed Language. (Christopher Barker)


----------------------------------------------------------------------

Message: 1
Date: Wed, 21 Apr 2021 20:48:29 +0200
From: "srkunze@mail.de" <srkunze@mail.de>
Subject: [Python-Dev] Re: PEP 654: Exception Groups and except*
        [REPOST]
To: Irit Katriel <iritkatriel@googlemail.com>
Cc: Irit Katriel <iritkatriel@yahoo.com>, python-dev
        <python-dev@python.org>, Yury Selivanov <yselivanov@gmail.com>
Message-ID: <04512110-64B5-4AB3-AE54-AE6889C77C30@mail.de>
Content-Type: text/plain; charset=utf-8

Removing two concepts and preserving semantics simplifies the matter for users. People need less to memorize and less to learn.

Or am I missing something here? Couldn’t we achieve our goal without these two new classes?

Splitting, wrapping and exception handling semantics are perfectly fine and serve their purposes. So, of course this still needs to be implemented.

> On 20. Apr 2021, at 23:26, Irit Katriel <iritkatriel@googlemail.com> wrote:
>
> I don’t see what this simplifies. We still need to implement split, and to worry about wrapping or not wrapping BaseExceptions and we still need to define exception handling semantics (except/except*).
>
>
>> On 20 Apr 2021, at 22:12, srkunze@mail.de wrote:
>>
>> So, forgive me my relatively simple mental model about ExceptionGroup. I still try to create one for daily use.
>>
>> As noted in the discussion, an EG provides a way to collect exceptions from different sources and raise them as a bundle. They have no apparent relation up until this point in time (for whatever reason they have been separate and for whatever reason they are bundled now). The result would be a tree graph in any case.
>>
>> A usual datastructure for a tree is to store all child nodes at the parent node.
>>
>> That was the idea behind the content of BaseException.__group__: it’s the list of child exceptions bundled at a specific point in time and raise as such a bundle. So all exceptions could become EGs with the additional semantics you‘ve described in the PEP.
>>
>> Illustrative Example:
>>>>> bundle_exc.__group__
>> [IOError(123), RuntimerError(‘issue somewhere’)]
>>
>> I was wondering what of the PEP could be removed to make it simpler and more acceptable/less confusing (also looking at reactions from Twitter etc.) and I found these additional classes to be a part of it. Additionally, I fail to see how to access these bundled exceptions in an easy manner like __cause__ and __context__. (As the PEP also referring to them). So, I removed the classes and added a regular attribute.
>>
>> The reason I brought this up what the section “rejected ideas” didn’t showed anything in this direction (or I managed to missed that).
>>
>> Sven
>>
>>>
>>>> On 20. Apr 2021, at 22:05, Irit Katriel <iritkatriel@yahoo.com> wrote:
>>>
>>> Hi Sven,
>>>
>>> I don’t follow.  What would the value of __group__ be and how would it work?
>>>
>>> Irit
>>>
>>>>> On 20 Apr 2021, at 20:44, srkunze@mail.de wrote:
>>>> 
>>>> Hi Irit,
>>>> reading this subthread specifically, I just got a wild idea and I couldn‘t find any related information in the PEP:
>>>> Why not extending BaseException by __group__ among __cause__ and __context__?
>>>> Would this reduce some of the added complexity and thus increase broader acceptance?
>>>> Cheers,
>>>> Sven
>>


------------------------------

Message: 2
Date: Wed, 21 Apr 2021 11:58:23 -0700
From: Yury Selivanov <yselivanov.ml@gmail.com>
Subject: [Python-Dev] Re: PEP 654: Exception Groups and except*
        [REPOST]
To: "srkunze@mail.de" <srkunze@mail.de>
Cc: Irit Katriel <iritkatriel@googlemail.com>, Irit Katriel
        <iritkatriel@yahoo.com>, python-dev <python-dev@python.org>, Yury
        Selivanov <yselivanov@gmail.com>
Message-ID:
        <CA+St6D0V8-bOAQUgGVsQ1kT_7NkRd4Q96rUnk7h8xHRwNSrwCw@mail.gmail.com>
Content-Type: text/plain; charset="UTF-8"

On Wed, Apr 21, 2021 at 11:50 AM srkunze@mail.de <srkunze@mail.de> wrote:
>
> Removing two concepts and preserving semantics simplifies the matter for users. People need less to memorize and less to learn.
>
> Or am I missing something here? Couldn’t we achieve our goal without these two new classes?

No, we can't. What you are proposing would make it very hard for users
to understand at a glance if what you have in an innocently looking
`except Exception` is correct or not.  In my async/await code I'd have
to always check the `__group__` attribute to make sure it's not an
exception group in disguise.

So while you're "simplifying" the proposal by removing a couple of
types, you're complicating it in all other places. Besides, I don't
think that adding the ExceptionGroup type is a controversial idea that
needs any simplification.

Yury

------------------------------

Message: 3
Date: Wed, 21 Apr 2021 12:36:34 -0700
From: Christopher Barker <pythonchb@gmail.com>
Subject: [Python-Dev] Re: Keeping Python a Duck Typed Language.
To: Nathaniel Smith <njs@pobox.com>
Cc: Python Dev <python-dev@python.org>
Message-ID:
        <CALn7ch9VvMx1b=AB46On=x5xvbaP1usGAbAgfe12DsQUKYBiUA@mail.gmail.com>
Content-Type: multipart/alternative;
        boundary="00000000000023a40905c080af6d"

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 <njs@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


--
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
-------------- next part --------------
A message part incompatible with plain text digests has been removed ...
Name: not available
Type: text/html
Size: 6277 bytes
Desc: not available

------------------------------

Subject: Digest Footer

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/


------------------------------

End of Python-Dev Digest, Vol 213, Issue 128
********************************************