Others have replied with most of this covering my opinion but there's a
point I'd like to highlight here

On Fri, 20 Nov 2020 at 14:23, Mark Shannon <m...@hotpy.org> wrote:

> Hi Daniel,
>
> On 20/11/2020 10:50 am, Daniel Moisset wrote:
> >  (... snipping for brevity ...)
> >
> >  1. You mention a goal about "erroneous patterns" (which I'm still not
> >     sure I agree on), and your proposal addresses that by forcing
> >     classes to be explicit (via __atributes__ and __deconstruct__) about
> >     what attributes are accepted as matches. This is against one design
> >     principle that's not in your list but it was (at least implicitly)
> >     in PEP622 and 634: "pattern matching must allow matching objects on
> >     types not specifically designed for it"; this will allow to apply
> >     this feature to classes that you can not modify (like instances
> >     created by a 3rd party library ). That's why PEP634 relies on
> >     getattr() ; that could be extended in the feature (providing some
> >     override using attributes like yours) but that wouldn't be required
> >     by default
>
> Why force pattern matching onto library code that was not designed for
> pattern matching? It seems risky.
>
> Fishing arbitrary attributes out of an object and assuming that the
> values returned by attribute lookup are equivalent to the internal
> structure breaks abstraction and data-hiding.
>
> An object's API may consist of methods only. Pulling arbitrary
> attributes out of that object may have all sorts of unintended
> side-effects.
>
> PEP 634 and the DLS paper assert that deconstruction, by accessing
> attributes of an object, is the opposite of construction.
> This assertion seems false in OOP.
>
>
I think your description about what you and I call OOP lies at the center
of why we're unlikely to agree on what's the best approach on class
patterns.

The Python I write and tend to use allows and encourages the use of the dot
operator (aka "Fishing arbitrary attributes out of an object") and the
libraries I use expose through it important parts of the API which
doesn't follow the style you mention where  "An object's API may consist of
methods only.". Of course I rely on properly documented attributes, like
datetime.date.year, Fractional.denominator, JSONDEcodeError.message (in the
stdlib) or fields I defined in my django models, or things like
requests.response.status_code (in 3rd party libraries that I used as is or
by extending). Those are all types of objects that I'd like the proposal to
allow as subjects of a match statement and attributes that I'd like to have
in lookups. Given that I can not force a lot of 3rd party libraries to add
a new special attribute `__attributes__`, our proposal relies on the
standard `getattr()` API (which is the core operation on Python object
model to doing most things with an object, even calling methods).

I've used other OOP languages within that style were attributes have to be
explicitly exposed, and even so that's disencouraged and they follow the
principle of "API=only methods". And I can imagine some people could choose
to write Python like that, even if I don't and most of the libraries I use
don't either. For people with that philosophy about OOP, our pattern
matching proposal will be horrible and useless and they can choose not to
use the match statement, ever. The argumentation behind the proposal is
implicitly based on the assumption that *most* Python developers consider
the dot operator one of the "natural" ways to expose object interfaces in
Python, even if it can pull attributes and use non-method APIs. If you
think that assumption is false, we'll have to agree to disagree but I don't
see how we could get to a common vision on how class patterns should behave.

(...)
> When we added the "with" statement, there was no attempt to force
> existing code to support it. We made the standard library support it,
> and let the community add support as and when it suited them.
>
> We should do the same with pattern matching.
>

With our proposal, nothing forces the existing code to support it, they
support it naturally using their existing attribute access API (through the
dot operator). One advantage that the with statement had is that it's quite
easy to wrap an object that wasn't designed to be used as context manager
in another that can (the stdlib even provides a common example of that with
contextlib.closing). Trying to use something like that (writing "match
wrapper(obj): ..." where obj doesn't support some match protocol and the
wrapper adds it) is non viable in pattern matching, because there are many
cases where the object that needs support might be many levels of
indirection (through item/key/attribute access) behind the subject object.

The current proposals using getattr is useful as is (Even if limited in
some cases). Again that doesn't discard the opportunity of adding an
extended protocol that allows decomposing using other APIs beyond attribute
access (I would love to match datetime.dates on weekday, for example, but
that's a method), but that doesn't need to be in place for the first
version and can be added later.

Best,
    Daniel
_______________________________________________
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/E76IOQH5WWH2RDVSAIFGMOLJVBG3S35C/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to