Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Juancarlo Añez
On Tue, Apr 25, 2017 at 6:09 PM, Paul Moore  wrote:

> (Arguing for auto_args to be in the stdlib may be a better option than
> arguing for new syntax, BTW...)
>

Having such a decorator in the stdlib would allow IDEs and syntax
highlighters to know what's going on.


-- 
Juancarlo *Añez*
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Nathaniel Smith
On Tue, Apr 25, 2017 at 3:30 PM, Erik  wrote:
> On 25/04/17 23:05, Paul Moore wrote:
>>
>> 1. Writing out the assignments "longhand" is an unacceptable burden.
>
>
> There are reasons why augmented assignment was implemented. One of them was
> to make the code easier to read:
>
>   foil = foil + 1
>   foil = foi1 + 1
>   foil += 1
>
> Should one be silly enough to have a "foil" and "foi1" variable in scope,
> only one of those is clearly incrementing a variable without requiring a
> slightly harder look ;)

But if this were the only argument for +=, then I'm not sure it would
have ever been added :-).

The really compelling cases for += are things like:

foo.some_attr[get_the_key(kwarg=something)] =
foo.some_attr[get_the_key(kwarg=something)] + 1

vs

foo.some_attr[get_the_key(kwarg=something)] += 1

where the latter is *much* more readable, and it only calls
get_the_key once, which (depending on what it does) may be both a
substantial efficiency win and also guarantees this is actually an
increment – we don't have to read get_the_key's source code first to
figure out if the two calls actually return the same value.

Another example:

arr = arr + 1
arr += 1

If 'arr' is a numpy array then these actually do very different
things: the first one allocates a new array and then rebinds the name
'arr' to the copy; the second modifies the array object in place. The
former is usually what you want, but without augmented assignment you
have to remember to do awkward things like 'arr[...] = arr + 1'. And
it gets worse: since 'arr[...] = arr + 1' has to make a copy, it's
about twice as slow as 'arr += 1'. The real equivalent of 'arr += 1'
is 'np.add(arr, 1, out=arr)', which is *really* bad.

Are there any similar arguments for .=?

-n

-- 
Nathaniel J. Smith -- https://vorpus.org
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Chris Angelico
On Wed, Apr 26, 2017 at 10:05 AM, Ryan Gonzalez  wrote:
> FWIW I always liked
> Dart's/Ruby's/Crystal's/(Coffee|Moon)Script's/WhateverElse's style:
>
>
> class Cls {
>   Cls(this.a);  // IT'S MAGIC
> }
>
>
> but the Python equivalent is admittedly weirder:
>
>
> def ___init__(self, self.attr):

In a sense, what you have is this (modulo keyword arguments):

def __init__(*args):
self, self.attr = args

which is perfectly legal, albeit weird. So it needn't actually be
magic per se, just a change in the definition of an argument name
(from NAME to whatever is legal as an assignment target).

I don't think it's particularly useful, though.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Ryan Gonzalez
FWIW I always liked
Dart's/Ruby's/Crystal's/(Coffee|Moon)Script's/WhateverElse's style:


class Cls {
  Cls(this.a);  // IT'S MAGIC
}


but the Python equivalent is admittedly weirder:


def ___init__(self, self.attr):


partly because, it'd have to work on pretty much any other variable name,
yet there's no other real use case outside of methods.


--
Ryan (ライアン)
Yoko Shimomura > ryo (supercell/EGOIST) > Hiroyuki Sawano >> everyone else
http://refi64.com

On Apr 24, 2017 8:08 PM, "Erik"  wrote:

> Hi. I suspect that this may have been discussed to death at some point in
> the past, but I've done some searching and I didn't come up with much.
> Apologies if I'm rehashing an old argument ;)
>
> I often find myself writing __init__ methods of the form:
>
> def __init__(self, foo, bar, baz, spam, ham):
>   self.foo = foo
>   self.bar = bar
>   self.baz = baz
>   self.spam = spam
>   self.ham = ham
>
> This seems a little wordy and uses a lot of vertical space on the screen.
> Occasionally, I have considered something like:
>
> def __init__(self, foo, bar, baz, spam, ham):
>   self.foo, self.bar, self.baz, self.spam, self.ham = \
>  foo, bar, baz, spam, ham
>
> ... just to make it a bit more compact - though in practice, I'd probably
> not do that with a list quite that long ... two or three items at most:
>
> def __init__(self, foo, bar, baz):
>self.foo, self.bar, self.baz = foo, bar, baz
>
> When I do that I'm torn because I know it has a runtime impact to create
> and unpack the implicit tuples and I'm also introducing a style asymmetry
> in my code just because of the number of parameters a method happens to
> have.
>
> So why not have an augmented assignment operator for object attributes? It
> addresses one of the same broad issues that the other augmented assignment
> operators were introduced for (that of repeatedly spelling names).
>
> The suggestion therefore is:
>
> def __init__(self, foo, bar, baz, spam, ham):
>   self .= foo, bar, baz, spam, ham
>
> This is purely syntactic sugar for the original example:
>
> def __init__(self, foo, bar, baz, spam, ham):
>   self.foo = foo
>   self.bar = bar
>   self.baz = baz
>   self.spam = spam
>   self.ham = ham
>
> ... so if any of the attributes have setters, then they are called as
> usual. It's purely a syntactic shorthand. Any token which is not suitable
> on the RHS of the dot in a standard "obj.attr =" assignment is a syntax
> error (no "self .= 1").
>
> The comma-separators in the example are not creating a tuple object, they
> would work at the same level in the parser as the import statement's
> comma-separated lists - in the same way that "from pkg import a, b, c" is
> the same as saying:
>
> import pkg
> a = pkg.a
> b = pkg.b
> c = pkg.c
>
> ... "self .= a, b, c" is the same as writing:
>
> self.a = a
> self.b = b
> self.c = c
>
> E.
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Matt Gilson
On Tue, Apr 25, 2017 at 4:31 PM, Erik  wrote:

> On 25/04/17 22:15, Brice PARENT wrote:
>
>> it may be easier to get something like this
>> (I think, as there is no new operator involved) :
>>
>
> No new operator, but still a syntax change, so that doesn't help from that
> POV.
>
>
>> def __init__(self, *args, **kwargs):
>>   self.* = *args
>>   self.** = **kwargs
>>
>
> What is "self.* = *args" supposed to do? For each positional argument,
> what name in the object is it bound to?
>
> E.


For what it's worth, that's what I don't really like about the initially
proposed syntax too ...

self .= foo, bar, baz

works OK, but:

tup = foo, bar, baz
self .= tup

doesn't work.  Admittedly, that could be part of the definition of this
feature, but it feels really unexpected to all of a sudden give my tuple a
temporary name and have the code behave in a dramatically different fashion.


>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 

Matt Gilson | Pattern

Software Engineer
getpattern.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Erik

On 25/04/17 22:15, Brice PARENT wrote:

it may be easier to get something like this
(I think, as there is no new operator involved) :


No new operator, but still a syntax change, so that doesn't help from 
that POV.




def __init__(self, *args, **kwargs):
  self.* = *args
  self.** = **kwargs


What is "self.* = *args" supposed to do? For each positional argument, 
what name in the object is it bound to?


E.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Erik

On 25/04/17 02:15, Chris Angelico wrote:

Bikeshedding: Your example looks a lot more like tuple assignment than
multiple assignment.


Well, originally, I thought it was just the spelling-the-same-name-twice 
thing that irritated me and I was just going to suggest a single 
assignment version like:


  self .= foo
  self .= bar

Then I thought that this is similar to importing (referencing an object 
from one namespace in another under the same name). In that scenario, 
instead of:


  from other import foo
  from other import bar

we have:

  from other import foo, bar

That's where the comma-separated idea came from, and I understand it 
looks like a tuple (which is why I explicitly mentioned that) but it 
does in the import syntax too ;)


The single argument version (though it doesn't help with vertical space) 
still reads better to me for the same reason that augmented assignment 
is clearer - there is no need to mentally parse that the same name is 
being used on both sides of the assignment because it's only spelled once.



self .= foo .= bar .= baz .= spam .= ham


Thanks for being the only person so far to understand that I don't 
necessarily want to bind ALL of the __init__ parameters to the object, 
just the ones I explicitly reference, but I'm not convinced by this 
suggestion. In chained assignment the thing on the RHS is bound to each 
name to the left of it and that is really not happening here.



The trouble is that this syntax is really only going to be used inside
__init__.


Even if that was true, who ever writes one of those? :D

E.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Mike Miller



On 2017-04-25 14:15, Brice PARENT wrote:

But, any of these proposals, mine and yours, if you really need this to shorten
the code writing time or vertical space only, is not a better idea than to
propose a macro to your IDE editor, or a pull request if it's open source. Such
a macro would generate automatically those long-to-write lines, and maybe
implement some code folding if vertical space is an issue.


I'm personally not bothered by vertical space, but rather typing the same thing 
three times with self's and ='s.  That's more boilerplate than Java.  ;)

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Mike Miller
Agreed with Steven, although I do find myself a little more annoyed and bothered 
by a typical init than him I guess.


Even so I didn't think the current proposals went far enough.  To tilt the 
balance farther, to make it easier, let's go all the way!  Instead of continuing 
duplication:



>>> def __init__(self, foo, bar, baz, spam, ham):
  self .= foo, bar, baz, spam, ham


or


# object member assignment
self .= foo .= bar .= baz .= spam .= ham


How about?

def __init__(self, foo, bar, baz, spam, ham):
  self .= *

The asterisk here used to be reminiscent of argument unpacking (minus self). 
That would imply a double asterisk for keyword assignment which could be used as 
well.


Also, I did find the decorator proposal intriguing, though have to say I 
probably wouldn't bother to use it unless it were a builtin or I had a dozen 
parameters to deal with.


-Mike
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Binary arithmetic does not always call subclasses first

2017-04-25 Thread Guido van Rossum
Now that I am with a real keyboard and screen and have tried to understand
the OP, I can actually write up my thoughts on the matter.

There are two aspects to the behavior. Giving preference to the class of
the right operand if it is a subclass of the left operand's class is
reasonable and explained in the docs.

Only doing this if the right operand actually overrides __rop__ was perhaps
meant as an optimization, and I expect that when I introduced that rule I
hadn't thought of the kind of classes that use type(self) or self.__class__
to return an instance of the runtime class.

However there's also another thing to consider. Consider a variant of the
OP example, where B doesn't override __add__ or __radd__, but now add a
different __init__ signature, one that requires completely different
arguments. This is entirely legal and done often enough (though perhaps not
in numpy circles?) -- constructors are not subject to the Liskov rule. So
the call to type(self)() may crash or have an undesirable result.

But given that A does call type(self)(), all its subclasses have to
either have a compatible __init__ or override both __add__ and __radd__.

In the end I agree with the OP that we should fix this. I don't see a
reason to require a PEP or require updating whatever PEP described this
behavior originally -- PEPs generally describe what should be done to a
specific version of Python, they don't prevent future alterations, and they
essentially represent the historical record, not current documentation.

I'm a little worried about breaking existing code, but only a little bit,
and this is clearly a gray area, so I think it's okay to change in 3.7
without deprecations. (But I've been overruled on such matters before, so
if you disagree, speak up now and show us your code!)

--Guido

On Mon, Apr 24, 2017 at 4:54 PM, Guido van Rossum 
wrote:

> If this is portant I should probably ponder it.
>
> On Apr 24, 2017 4:47 PM, "Stephan Hoyer"  wrote:
>
>> +Georg Brandl, in case he remembers where "Move the 3k reST doc tree in
>> place." moved things from:
>> https://github.com/python/cpython/commit/116aa62bf54a39697e2
>> 5f21d6cf6799f7faa1349
>>
>> On Mon, Apr 24, 2017 at 4:29 PM, Nick Timkovich 
>> wrote:
>>
>>> GitHub shows that that note hasn't changed in 10 years:
>>> https://github.com/python/cpython/blame/master/Doc/re
>>> ference/datamodel.rst#L2210
>>>
>>> On Mon, Apr 24, 2017 at 3:15 PM, Terry Reedy  wrote:
>>>
 On 4/24/2017 12:14 PM, Stephan Hoyer wrote:

 Based on the change in the documentation between 2.x and 3.x, I wonder
> if this is something that someone intended to clean up as part of Python
> 3000 but never got around to. I would love to hear from anyone familiar
> with the historical context here.
>

 We should ask the intention of the person who made the change, which is
 in the repository.  If you email me the doc (the last part of the url) and
 location within, I will look it up.

 --
 Terry Jan Reedy


 ___
 Python-ideas mailing list
 Python-ideas@python.org
 https://mail.python.org/mailman/listinfo/python-ideas
 Code of Conduct: http://python.org/psf/codeofconduct/

>>>
>>>
>>> ___
>>> Python-ideas mailing list
>>> Python-ideas@python.org
>>> https://mail.python.org/mailman/listinfo/python-ideas
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>>
>>
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>>


-- 
--Guido van Rossum (python.org/~guido)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Tin Tvrtković
You might want to check out attrs (http://attrs.readthedocs.io/en/stable/).
It can generate the __init__ for you, and much much more.


Date: Tue, 25 Apr 2017 14:33:49 +0200
> From: George Fischhof 
> To: Paul Moore 
> Cc: Python-Ideas , "Steven D'Aprano"
> 
> Subject: Re: [Python-ideas] Augmented assignment syntax for objects.
> Message-ID:
> <
> cafwcp0gjg1bxeq2pmv637bxg6+vcxivu1qnekdetuhjmot_...@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> 2017. ?pr. 25. de. 10:04 ezt ?rta ("Paul Moore" ):
>
> On 25 April 2017 at 03:53, Steven D'Aprano  wrote:
> > On Tue, Apr 25, 2017 at 02:08:05AM +0100, Erik wrote:
> >
> >> I often find myself writing __init__ methods of the form:
> >>
> >> def __init__(self, foo, bar, baz, spam, ham):
> >>   self.foo = foo
> >>   self.bar = bar
> >>   self.baz = baz
> >>   self.spam = spam
> >>   self.ham = ham
> >>
> >> This seems a little wordy and uses a lot of vertical space on the
> >> screen.
> >
> > It does, and while both are annoying, in the grand scheme of things
> > they're a very minor annoyance. After all, this is typically only an
> > issue once per class, and not even every class, and vertical space is
> > quite cheap. In general, the barrier for accepting new syntax is quite
> > high, and "minor annoyance" generally doesn't reach it.
>
> I suspect that with a suitably creative use of inspect.signature() you
> could write a decorator for this:
>
> @auto_attrs
> def __init__(self, a, b, c):
> # Remaining init code, called with self.a, self.b and self.c set
>
> I don't have time to experiment right now, but will try to find time
> later. If nothing else, such a decorator would be a good prototype for
> the proposed functionality, and may well be sufficient for the likely
> use cases without needing a syntax change.
>
> Paul
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread George Fischhof
2017. ápr. 25. de. 10:04 ezt írta ("Paul Moore" ):

On 25 April 2017 at 03:53, Steven D'Aprano  wrote:
> On Tue, Apr 25, 2017 at 02:08:05AM +0100, Erik wrote:
>
>> I often find myself writing __init__ methods of the form:
>>
>> def __init__(self, foo, bar, baz, spam, ham):
>>   self.foo = foo
>>   self.bar = bar
>>   self.baz = baz
>>   self.spam = spam
>>   self.ham = ham
>>
>> This seems a little wordy and uses a lot of vertical space on the
>> screen.
>
> It does, and while both are annoying, in the grand scheme of things
> they're a very minor annoyance. After all, this is typically only an
> issue once per class, and not even every class, and vertical space is
> quite cheap. In general, the barrier for accepting new syntax is quite
> high, and "minor annoyance" generally doesn't reach it.

I suspect that with a suitably creative use of inspect.signature() you
could write a decorator for this:

@auto_attrs
def __init__(self, a, b, c):
# Remaining init code, called with self.a, self.b and self.c set

I don't have time to experiment right now, but will try to find time
later. If nothing else, such a decorator would be a good prototype for
the proposed functionality, and may well be sufficient for the likely
use cases without needing a syntax change.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/



Hi, such a decorator would be very grateful ;-) in the standard as for
example I use class parameters this way too in more than 90% of the cases.

BR
George
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Daniel Moisset
I actually saw a decorator like that last week,
https://twitter.com/judy2k/status/854330478068977664

On 25 April 2017 at 08:56, Paul Moore  wrote:

> On 25 April 2017 at 03:53, Steven D'Aprano  wrote:
> > On Tue, Apr 25, 2017 at 02:08:05AM +0100, Erik wrote:
> >
> >> I often find myself writing __init__ methods of the form:
> >>
> >> def __init__(self, foo, bar, baz, spam, ham):
> >>   self.foo = foo
> >>   self.bar = bar
> >>   self.baz = baz
> >>   self.spam = spam
> >>   self.ham = ham
> >>
> >> This seems a little wordy and uses a lot of vertical space on the
> >> screen.
> >
> > It does, and while both are annoying, in the grand scheme of things
> > they're a very minor annoyance. After all, this is typically only an
> > issue once per class, and not even every class, and vertical space is
> > quite cheap. In general, the barrier for accepting new syntax is quite
> > high, and "minor annoyance" generally doesn't reach it.
>
> I suspect that with a suitably creative use of inspect.signature() you
> could write a decorator for this:
>
> @auto_attrs
> def __init__(self, a, b, c):
> # Remaining init code, called with self.a, self.b and self.c set
>
> I don't have time to experiment right now, but will try to find time
> later. If nothing else, such a decorator would be a good prototype for
> the proposed functionality, and may well be sufficient for the likely
> use cases without needing a syntax change.
>
> Paul
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
Daniel F. Moisset - UK Country Manager
www.machinalis.com
Skype: @dmoisset
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Augmented assignment syntax for objects.

2017-04-25 Thread Paul Moore
On 25 April 2017 at 03:53, Steven D'Aprano  wrote:
> On Tue, Apr 25, 2017 at 02:08:05AM +0100, Erik wrote:
>
>> I often find myself writing __init__ methods of the form:
>>
>> def __init__(self, foo, bar, baz, spam, ham):
>>   self.foo = foo
>>   self.bar = bar
>>   self.baz = baz
>>   self.spam = spam
>>   self.ham = ham
>>
>> This seems a little wordy and uses a lot of vertical space on the
>> screen.
>
> It does, and while both are annoying, in the grand scheme of things
> they're a very minor annoyance. After all, this is typically only an
> issue once per class, and not even every class, and vertical space is
> quite cheap. In general, the barrier for accepting new syntax is quite
> high, and "minor annoyance" generally doesn't reach it.

I suspect that with a suitably creative use of inspect.signature() you
could write a decorator for this:

@auto_attrs
def __init__(self, a, b, c):
# Remaining init code, called with self.a, self.b and self.c set

I don't have time to experiment right now, but will try to find time
later. If nothing else, such a decorator would be a good prototype for
the proposed functionality, and may well be sufficient for the likely
use cases without needing a syntax change.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/