[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-21 Thread Christopher Barker
>
> On Thu, 21 Apr 2022 at 02:45, malmiteria  wrote:
> > 4) Lib refactoring are breaking changes
> > A Lib author refactoring his code by extracting a class as a parent
> class of multiple of the class provided is introducing a breaking change.
>


> > After refactoring, the MRO is now N1, N2, GP. Which do behave
> differently, in general.
>

Sure -- but there's nothing special or difficult here -- refactoring can
create breaking changes. I believe it was part of Hettinger's thesis in
"Super Considered Super" that the use of super() is part of the API of a
class hierarchy. Indeed, the MRO of a class hierarchy is part of the API.
If you change the MRO, it is a potentially breaking change, just as if a
method is added or removed, or renamed, or ...

Nothing to see here -- this is all deliberate, and useful.

-CHB

-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/TLMQKK4OAPALUZJHZVJI7BLZZ4PQ7QVF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-21 Thread Matsuoka Takuo
On Thu, 21 Apr 2022 at 02:45, malmiteria  wrote:
>
> 4) Lib refactoring are breaking changes
> A Lib author refactoring his code by extracting a class as a parent class of 
> multiple of the class provided is introducing a breaking change.
> Because any user's code inheriting from at least 2 of the class impacted by 
> this refactoring will now exhibit a different behavior.
> If O1 and O2 are refactored into N1(GP) and N2(GP)
> the MRO as it was before refactoring was essentially N1, GP, N2, GP, as what 
> was O1 before refactoring is equivalent to N1, GP after refactoring.
> After refactoring, the MRO is now N1, N2, GP. Which do behave differently, in 
> general.

This seems important.  The refactoring can cause a problem if both of
O1 and O2 have an attribute (or method) say "a", and O1.a goes to GP,
and O2.a goes to N2.  While O1.a would more naturally be going to N1
(or some class between N1 and GP), the fact is it must!  I don't think
I have ever been told a refactoring like that shouldn't involve a new
instance of overriding.  Is this known to most Python programmers?  I
wish every Python programmer will know it.

Best regards,
Takuo Matsuoka
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/F3VEMOUPZ7JQZ3FPQ25HF7HRG7IDCLGZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Auto assignment of attributes

2022-04-21 Thread Josh Rosenberg
On Wed, Apr 20, 2022 at 3:31 PM Pablo Alcain  wrote:

>
> About dataclasses, the point that Chris mentions, I think that they are in
> a different scope from this, since they do much more stuff. But, beyond
> this, a solution on the dataclass style would face a similar scenario:
> since the `__init__` is autogenerated, you would also be in a tight spot in
> the situation of "how would I bind only one of the items?". Again, now I'm
> talking about my experience, but I think that it's very hard to think that
> we could replace "classes" with "dataclasses" altogether. Here's an example
> of one of the (unexpected for me) things that happen when you try to do
> inheritance on dataclasses: https://peps.python.org/pep-0557/#inheritance.
>
> dataclasses, by default, do four things with the annotated fields defined
in the class:

1. Generate a __init__
2. Generate a reasonable __repr__
3. Generate a reasonable __eq__
4. Automatically support destructuring with match statements

And you can independently disable any/all of them with arguments to the
decorator. They *can* do much more, but I find it pretty unusual to *ever*
write a class that I wouldn't want most of those for. The __init__ it
generates is essentially automatically writing the boilerplate you're
trying to avoid, so it seems entirely reasonable to consider this the same
scope.

As for "how would I bind only one/some of the items?", dataclasses already
support this with dataclasses.InitVar and a custom __post_init__ method; so:

class MyClass:

def __init__(self, @a, @b, c):

... do something with c that doesn't just assign it as self.c...

where you directly move values from the a and b arguments to self.a and
self.b, but use c for some other purpose, is spelled (using typing.Any as a
placeholder annotation when there's no better annotation to use):

@dataclass
class MyClass:
a: Any
b: Any
c: InitVar[Any]
def __post_init__(self, c):
... do something with c that doesn't just assign it as self.c;
self.a and self.b already exist ...

The only name repeated is c (because you're not doing trivial assignment
with it), and it's perfectly readable. I'm really not seeing how this is
such an unwieldy solution that it's worth adding dedicated syntax to avoid
a pretty trivial level of boilerplate that is already avoidable with
dataclasses anyway.

-Josh
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/SSG2VXIMBQI5FC5S3G72GQ3XQTL6RSWS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Auto assignment of attributes

2022-04-21 Thread Joao S. O. Bueno
On Thu, Apr 21, 2022 at 5:17 PM Pablo Alcain  wrote:

> Hey Joao! For what it's worth, I'm not a big fan of the proposal to be
> honest, for the reasons I have already mentioned. I'm not heavily against
> it, but I would most likely not use it. Nevertheless, I believe it would
> need a PEP since it probably can change substantially the way Python code
> is being written.
>
> I think that discussion can probably belong to a specific thread with the
> proposal with your questions summary there so everyone can contribute to
> the implementation that, clearly, has some interesting points that it would
> be better if we could discuss in detail.
>
> I would very much like for us to evaluate, in this thread, the original
> proposal we sent, regarding if anyone else thinks it would make sense to
> add a new syntax for the binding of attributes.
>
>
Sorry. It looks like you are claiming... the _thread_ , is that it?

Very well. The thread may be all yours!

BTW, I am -1 on these changes.


> Pablo
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/MSNOSJK2M3QLCUDUBVQNEFMDQF3YWIWD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Auto assignment of attributes

2022-04-21 Thread Pablo Alcain
Hey Joao! For what it's worth, I'm not a big fan of the proposal to be
honest, for the reasons I have already mentioned. I'm not heavily against
it, but I would most likely not use it. Nevertheless, I believe it would
need a PEP since it probably can change substantially the way Python code
is being written.

I think that discussion can probably belong to a specific thread with the
proposal with your questions summary there so everyone can contribute to
the implementation that, clearly, has some interesting points that it would
be better if we could discuss in detail.

I would very much like for us to evaluate, in this thread, the original
proposal we sent, regarding if anyone else thinks it would make sense to
add a new syntax for the binding of attributes.

Pablo
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/7FKGRN2NQOZJK5MPVCYGDHDM6L2VCA4D/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Auto assignment of attributes

2022-04-21 Thread Joao S. O. Bueno
I take the freedom to interpret 'no news == good news' on this thread -
nominally that there are no major disagreements that a decorator
to auto-commit `__init__` atributes to the instance could be a nice addition
to the stdlib.

I also assume it is uncontroversial enough for not needing a PEP.

I remember a similar thread from a couple years ago where the thread ended
up agreeing on such a decorator as well.

I would then like to take the opportunity to bike-shed  a bit on this, and
maybe we
can get out of here with a BPO and an actual implementation.

So,

1) Would it live better in "dataclasses" or "functools"? Or some other
package?

2) What about: the usage of the decorator without arguments would imply in
committing all of
`__init__` arguments as instance attributes, and two, mutually exclusive,
optional kwonly
 "parameters" and "except" parameters could be used with a list of
arguments to set?

2.1)  The usage of a "parameters" argument to the decorator would even pick
names from an
eventual "**kwargs" "__init__" parameter, which otherwise would be
commited be left alone/
2.2) would it make sense to have another argument to specify how "**kwargs"
should be treated?
I see three options: (i) ignore it altogether, (ii) commit it  as a
dictionary, (iii) commit all keys in kwargs as
instance attributes, (iii.a) "safe commit" keys in kwargs, avoiding
overriding methods and class attributes.
(whatever the option here, while the principle of "less features are
safer" in a first release, should consider
 if it would be possible to include the new features later in a
backwards compatible way)

3) While the Python implementation for such a decorator is somewhat
straightforward, are there any chances
of making it static-annotation friendly? AFAIK dataclasses just work with
static type checking because
the @dataclass thecorator is special-cased in the checker tools themselves.
Would that be the same case here?

4) Naming. What about "@commitargs"?

5) Should it emit a warning (or TypeError) when decorating anything but a
function named `__init__ ` ?



On Wed, Apr 20, 2022 at 3:14 PM Joao S. O. Bueno 
wrote:

>
>
> On Wed, Apr 20, 2022 at 12:30 PM Pablo Alcain 
> wrote:
>
>>
>> Regarding the usage of a decorator to do the auto-assignment, I think
>> that it has an issue regarding how to select a subset of the variables that
>> you would be setting. In the general case, you can probably get away with
>> calling `autoassign`. But, for example, if you want to set a but not b,
>> you'd probably have to use a string as the identifier of the parameters
>> that you want to assign:
>>
>> ```
>> class MyKlass:
>> @autoassign('a')
>> def __init__(self, a, b):
>> print(b)
>>
>> ```
>>
>> This, in my perspective, brings two things: the first one is that you'd
>> be repeating everywhere the list of names, so for example doing refactors
>> like changing a variable name would be a bit error-prone: If you change the
>> variable from `a` to `my_var_name`, you'd have to also change the list in
>> the autoassign. It's not a lot, but it can induce some errors because of
>> the repetition. On the other hand, I guess it would be a bit hard for IDEs
>> and static checkers to follow this execution path. I know that I'm only one
>> data point, but for what it's worth, I was very excited with the idea but
>> this prevented me from actually implementing this solution on a day-to-day
>> basis: it felt a bit fragile and induced me to some errors.
>>
>
> IMO, that is trivially resolvable by doing the decorator, by default,
> assign all parameters. If it tkaes a string or sequence with parameter
> names, then, it will just bind those (still shorter than one line
> `self.attr = attr` for each attribute.
>
> And for the fragility: that is the advantage of having a robust
> implementation of something like this on the stdlib: it is not something
> most people will go out of their way to write their own, since the tradeoff
> is just
> copy and paste a bunch of plain assignments.
>
> But having it right and known, could chop off tens of lines of useless
> code in, probably the majority of Python projects.
>
>
> Also answering Christopher Barker:
>
> This has a subtle, but different use than dataclasses.
> It might be grouped in the dataclasses module, on the stdlib.
>
>
>
>>
>> About dataclasses, the point that Chris mentions, I think that they are
>> in a different scope from this, since they do much more stuff. But, beyond
>> this, a solution on the dataclass style would face a similar scenario:
>> since the `__init__` is autogenerated, you would also be in a tight spot in
>> the situation of "how would I bind only one of the items?". Again, now I'm
>> talking about my experience, but I think that it's very hard to think that
>> we could replace "classes" with "dataclasses" altogether. Here's an example
>> of one of the (unexpected for me) things that happen when you try to do
>> inheritance on dataclasses: