Re: [Python-ideas] Accepting multiple mappings as positional arguments to create dicts

2018-04-12 Thread Serhiy Storchaka

12.04.18 22:42, Andrés Delfino пише:

I think the update method can (and personally, should) stay unchanged:

spam.update(dict(x, y))

seems succinct and elegant enough, with the proposed constructor syntax.

Sorry my ignorance, do (Mutable)Mapping ABC say anything about 
constructors?


Mapping and MutableMapping ABCs don't have constructors, but many 
dict-like objects imitate the dict constructor: accept a single mapping 
or a sequence of pairs as a positional argument, and accept other dict 
as kwargs.


___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Fri, Apr 13, 2018 at 2:37 PM, Guido van Rossum  wrote:
> Clearly the PEP should spell out the precedence of :=. I'm sure Chris
> intended to give := the lowest possible precedence: the analogy with = (both
> in Python and in other languages), and the original design of the PEP, where
> the syntax was ( as ), with mandatory parentheses. (Probably his
> implementation helps to guess his intention too, but I can't be bothered yet
> to clone and build it just to answer this question definitively. :-)
>
> I find the analogy argument compelling, and I think we should just make it a
> style rule that parentheses should be used whenever it could be misread by a
> human who's not sure about the precedence.
>
> Too bad for that one example.

Yes, that's the current intention, and (modulo a bug or two) the
current reference implementation. This may change tonight.

(If anyone's curious, and/or wants to join the discussion in
real-time, I'll be streaming live on https://twitch.tv/rosuav as I
tinker with the precedence.)

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Tim Peters
[David Mertz ]
> Yes, I have not read all the iterations of the PEP, and none of them
> extremely closely. I had thought it "obvious" that ':=' should have a very
> high operator precedence.

But you don't really believe that ;-)  That's the rub.  In your specific

None if var:= function() is None else var.method()

example it was obvious := should have very high precedence _there_,
but in an earlier

_, x1, x2 = (D := b**2 - 4*a*c), (-b + sqrt(D))/2, (-b - sqrt(D))/2

it was just as obvious that you wanted := to have a very low
precedence _there_ (else D would be bound to the value of plain old
`b`).

I don't at all mean to be picking on you there - I suffer the same
illusions.  It appears that "very low precedence" is actually wanted
in nearly all examples, _except_ when comparison is involved.

So maybe := "should have" precedence between comparison operators (<=,
is, etc) and bitwise OR (|).

Then both your examples above would do what you expected them to do
(and what I expected them to do at first glance).

OTOH, that wouldn't be at all like C, whose precedence rules Python
largely follows (only the comma operator has lower precedence than
assignment in C), and - worse - wouldn't be at all like Python
assignment statements appear to behave.


> But of course if it doesn't then expressions like
> the one I proposed could mean something quite different.

Whether very high or very low, one of your two examples above is screwed.


> I find the third hand argument rather compelling. All those potentially
> required parentheses turn elegant looking code into an ugly mess.

It is a hangup for me - but I'm not yet sure how severe.
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Fri, Apr 13, 2018 at 2:14 PM, David Mertz  wrote:
> Yes, I have not read all the iterations of the PEP, and none of them
> extremely closely. I had thought it "obvious" that ':=' should have a very
> high operator precedence. But of course if it doesn't then expressions like
> the one I proposed could mean something quite different.

Interesting. How high, exactly?

https://docs.python.org/3/reference/expressions.html#operator-precedence

(note: "higher precedence" doesn't mean higher on that table - the
table's from lowest to highest)

Currently, I've placed ':=' up with if-else expressions. That's
extremely low precedence. I'm contemplating moving it to just higher
than comparison operators (ie just below the bitwise operators),
putting it below all the arithmetic operators. The highest precedence
I would consider putting it is just below the unary operators; that
would mean it binds more tightly than arithmetic operators, but you
can still say "x := y[1]" without having to parenthesize the latter.

foo := a > b   # does this capture 'a', or 'a > b'?
bar := c + d   # 'c' or 'c + d'?

I'm open to argument here, but my thinking is that these should
capture 'a' and 'c + d'.

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Fri, Apr 13, 2018 at 1:55 PM, Tim Peters  wrote:
> [David Mertz ]
>> Yes, I should have added ternary expressions to if statements. I can
>> definitely see the use there.
>>
>> However, your example is not null checking. You'd have to modify it slightly
>> to get that:
>>
>> None if var:= function() is None else var.method()
>>
>> Still not bad looking.
>
> I couldn't find text in the PEP spelling out precedence,

Oops, that's a mistake. I'll add that in a bit. It has extremely low precedence.

> but there are
> two plausible ways that could be grouped:
>
> 1.None if (var:= function()) is None else var.method()
>
> which is what I believe you intended, and
>
> 2.None if var:= (function() is None) else var.method()
>
> which from earlier iterations of this thread I believe is the actual
> meaning - but isn't at all what was intended.

I just went to test it, and the unparenthesized version is actually
bombing with SyntaxError. I'm going to call that a bug, though, and
see about fixing it tonight.

Currently, the precedence is so low that basically anything will get
captured, and if you want to capture anything less than the entire
expression, you parenthesize. I'll experiment with placing it between
'|' and comparison operators, which would mean that an unparenthesized
assignment expression generally won't capture a boolean, but will
instead capture the value itself. That's likely to be more useful, I
think. (Obviously you can always use parens to overrule the precedence
table.)

> While "assignment" is currently a statement type rather than "an
> operator", viewing the current situation as if "=" were an operator it
> has very low precedence, so it would be just as surprising at times to
> boost the precedence of ":=":
>
>  if x := i+1:
>
> That is, in _that_ example,
>
> if x := (i+1):
>
> is "clearly intended", not the more tightly binding
>
> if (x ;= i) + 1:

Agreed as regards addition. Less certain as regards comparisons.

if x := i > 1:

is currently "if x := (i > 1)" and not "if (x := i) > 1". Assuming I
don't run into implementation difficulties, I'll play with this
tonight, then document it one way or the other, and maybe have an open
question about the alternative precedence.

> On the third hand, requiring parentheses all the time would also feel 
> strained:
>
> while m := someregexp.match(somestring):
>
> is already impossible to misread.
>
> Annoying ;-)

Agreed. There's no reason to mandate the parens here. Neither the PEP
nor the reference implementation has any problem with this expression
being unparenthesized.

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Guido van Rossum
Clearly the PEP should spell out the precedence of :=. I'm sure Chris
intended to give := the lowest possible precedence: the analogy with =
(both in Python and in other languages), and the original design of the
PEP, where the syntax was ( as ), with mandatory parentheses.
(Probably his implementation helps to guess his intention too, but I can't
be bothered yet to clone and build it just to answer this question
definitively. :-)

I find the analogy argument compelling, and I think we should just make it
a style rule that parentheses should be used whenever it could be misread
by a human who's not sure about the precedence.

Too bad for that one example.

On Thu, Apr 12, 2018 at 9:14 PM, David Mertz  wrote:

> Yes, I have not read all the iterations of the PEP, and none of them
> extremely closely. I had thought it "obvious" that ':=' should have a very
> high operator precedence. But of course if it doesn't then expressions like
> the one I proposed could mean something quite different.
>
> I find the third hand argument rather compelling. All those potentially
> required parentheses turn elegant looking code into an ugly mess.
>
>
> On Thu, Apr 12, 2018, 11:56 PM Tim Peters  wrote:
>
>> [David Mertz ]
>> > Yes, I should have added ternary expressions to if statements. I can
>> > definitely see the use there.
>> >
>> > However, your example is not null checking. You'd have to modify it
>> slightly
>> > to get that:
>> >
>> > None if var:= function() is None else var.method()
>> >
>> > Still not bad looking.
>>
>> I couldn't find text in the PEP spelling out precedence, but there are
>> two plausible ways that could be grouped:
>>
>> 1.None if (var:= function()) is None else var.method()
>>
>> which is what I believe you intended, and
>>
>> 2.None if var:= (function() is None) else var.method()
>>
>> which from earlier iterations of this thread I believe is the actual
>> meaning - but isn't at all what was intended.
>>
>> The most clearly related example in the PEP appears to be:
>>
>> x = "default" if (eggs := spam().ham) is None else eggs
>>
>> which forced the intended meaning as in #1 above.
>>
>> While "assignment" is currently a statement type rather than "an
>> operator", viewing the current situation as if "=" were an operator it
>> has very low precedence, so it would be just as surprising at times to
>> boost the precedence of ":=":
>>
>>  if x := i+1:
>>
>> That is, in _that_ example,
>>
>> if x := (i+1):
>>
>> is "clearly intended", not the more tightly binding
>>
>> if (x ;= i) + 1:
>>
>> On the third hand, requiring parentheses all the time would also feel
>> strained:
>>
>> while m := someregexp.match(somestring):
>>
>> is already impossible to misread.
>>
>> Annoying ;-)
>>
>
> ___
> 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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Alex Walters
> 
> On the third hand, requiring parentheses all the time would also feel
> strained:
> 
> while m := someregexp.match(somestring):
> 
> is already impossible to misread.
> 
> Annoying ;-)

While adding parens to that would be superfluous for the reader of the
module, as a tradeoff for requiring explicitness instead of doing the
implicitly wrong (depending on context) thing is probably worth it.

___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread David Mertz
Yes, I have not read all the iterations of the PEP, and none of them
extremely closely. I had thought it "obvious" that ':=' should have a very
high operator precedence. But of course if it doesn't then expressions like
the one I proposed could mean something quite different.

I find the third hand argument rather compelling. All those potentially
required parentheses turn elegant looking code into an ugly mess.

On Thu, Apr 12, 2018, 11:56 PM Tim Peters  wrote:

> [David Mertz ]
> > Yes, I should have added ternary expressions to if statements. I can
> > definitely see the use there.
> >
> > However, your example is not null checking. You'd have to modify it
> slightly
> > to get that:
> >
> > None if var:= function() is None else var.method()
> >
> > Still not bad looking.
>
> I couldn't find text in the PEP spelling out precedence, but there are
> two plausible ways that could be grouped:
>
> 1.None if (var:= function()) is None else var.method()
>
> which is what I believe you intended, and
>
> 2.None if var:= (function() is None) else var.method()
>
> which from earlier iterations of this thread I believe is the actual
> meaning - but isn't at all what was intended.
>
> The most clearly related example in the PEP appears to be:
>
> x = "default" if (eggs := spam().ham) is None else eggs
>
> which forced the intended meaning as in #1 above.
>
> While "assignment" is currently a statement type rather than "an
> operator", viewing the current situation as if "=" were an operator it
> has very low precedence, so it would be just as surprising at times to
> boost the precedence of ":=":
>
>  if x := i+1:
>
> That is, in _that_ example,
>
> if x := (i+1):
>
> is "clearly intended", not the more tightly binding
>
> if (x ;= i) + 1:
>
> On the third hand, requiring parentheses all the time would also feel
> strained:
>
> while m := someregexp.match(somestring):
>
> is already impossible to misread.
>
> Annoying ;-)
>
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Tim Peters
[David Mertz ]
> Yes, I should have added ternary expressions to if statements. I can
> definitely see the use there.
>
> However, your example is not null checking. You'd have to modify it slightly
> to get that:
>
> None if var:= function() is None else var.method()
>
> Still not bad looking.

I couldn't find text in the PEP spelling out precedence, but there are
two plausible ways that could be grouped:

1.None if (var:= function()) is None else var.method()

which is what I believe you intended, and

2.None if var:= (function() is None) else var.method()

which from earlier iterations of this thread I believe is the actual
meaning - but isn't at all what was intended.

The most clearly related example in the PEP appears to be:

x = "default" if (eggs := spam().ham) is None else eggs

which forced the intended meaning as in #1 above.

While "assignment" is currently a statement type rather than "an
operator", viewing the current situation as if "=" were an operator it
has very low precedence, so it would be just as surprising at times to
boost the precedence of ":=":

 if x := i+1:

That is, in _that_ example,

if x := (i+1):

is "clearly intended", not the more tightly binding

if (x ;= i) + 1:

On the third hand, requiring parentheses all the time would also feel strained:

while m := someregexp.match(somestring):

is already impossible to misread.

Annoying ;-)
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Thautwarm Zhao
>  None if var:= function() is None else var.method()

Make sense.

In some specific scenes(maybe general, I'm not sure),

   var.method() if var:=function() else var

looks cool although it's not really null checking. It works for Python,
just like use `if lst` to check if the list `lst` is empty.


2018-04-13 11:22 GMT+08:00 David Mertz :

> Yes, I should have added ternary expressions to if statements. I can
> definitely see the use there.
>
> However, your example is not null checking. You'd have to modify it
> slightly to get that:
>
> None if var:= function() is None else var.method()
>
> Still not bad looking.
>
> On Thu, Apr 12, 2018, 11:01 PM Thautwarm Zhao 
> wrote:
>
>>
>> > You're looking at a very early commit there. I suggest looking at the
>> > most recent commits on one of two branches:
>>
>> https://github.com/Rosuav/cpython/blob/statement-local-
>> variables/Grammar/Grammar
>> https://github.com/Rosuav/cpython/blob/assignment-
>> expressions/Grammar/Grammar
>>
>> > Those are the two most recent states in my progress towards (a)
>> > statement-local name bindings with "EXPR as NAME", and (b) assignment
>> > expressions with "target := value".
>>
>> Okay, and the syntax "target := value" seems to be much easier to handle
>> with.
>>
>> I do support this feature, but now I'm worried about the meaning of ':=',
>> it seems to be a lazy assignment in some degree. I'm not sure using ':=' is
>> proper here.
>>
>>
>> > Inasmuch as I might like assignment expressions, it would only be in
>> while or if statements, personally.
>>
>> Not exactly, assignment expression also works for "if expression", we can
>> now have null checking.
>>
>> var.method() if var:= function() else None
>>
>> Null checking is importance enough to have a specific syntax in many
>> other languages(C#, kotlin, Ruby and so on), and we can even have more than
>> null checking by adding expression assignment.
>>
>>
>>
>>
>> ___
>> 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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Guido van Rossum
On Thu, Apr 12, 2018 at 8:22 PM, David Mertz  wrote:

> Yes, I should have added ternary expressions to if statements. I can
> definitely see the use there.
>
> However, your example is not null checking. You'd have to modify it
> slightly to get that:
>
> None if var:= function() is None else var.method()
>
> Still not bad looking.
>

Though a long way from function()?.method() per PEP 505. :-)

-- 
--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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread David Mertz
Yes, I should have added ternary expressions to if statements. I can
definitely see the use there.

However, your example is not null checking. You'd have to modify it
slightly to get that:

None if var:= function() is None else var.method()

Still not bad looking.

On Thu, Apr 12, 2018, 11:01 PM Thautwarm Zhao 
wrote:

>
> > You're looking at a very early commit there. I suggest looking at the
> > most recent commits on one of two branches:
>
>
> https://github.com/Rosuav/cpython/blob/statement-local-variables/Grammar/Grammar
>
> https://github.com/Rosuav/cpython/blob/assignment-expressions/Grammar/Grammar
>
> > Those are the two most recent states in my progress towards (a)
> > statement-local name bindings with "EXPR as NAME", and (b) assignment
> > expressions with "target := value".
>
> Okay, and the syntax "target := value" seems to be much easier to handle
> with.
>
> I do support this feature, but now I'm worried about the meaning of ':=',
> it seems to be a lazy assignment in some degree. I'm not sure using ':=' is
> proper here.
>
>
> > Inasmuch as I might like assignment expressions, it would only be in
> while or if statements, personally.
>
> Not exactly, assignment expression also works for "if expression", we can
> now have null checking.
>
> var.method() if var:= function() else None
>
> Null checking is importance enough to have a specific syntax in many other
> languages(C#, kotlin, Ruby and so on), and we can even have more than null
> checking by adding expression assignment.
>
>
>
>
> ___
> 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] Move optional data out of pyc files

2018-04-12 Thread Giampaolo Rodola'
On Fri, 13 Apr 2018 at 03:47, M.-A. Lemburg  wrote:

> I think moving data out of pyc files is going in a wrong direction:
> more stat calls means slower import and slower startup time.
>
> Trying to make pycs smaller also isn't really worth it (they
> compress quite well).
>
> Saving memory could be done by disabling reading objects lazily
> from the file - without removing anything from the pyc file.
> Whether the few 100kB RAM this saves is worth the effort depends
> on the application space.
>
> This leaves the proposal to restructure pyc files into a sectioned
> file and possibly indexed file to make access to (lazily) loaded
> parts faster.


+1. With this in place -O and -OO cmdline options would become even less
useful (which is good).

-- 
Giampaolo - http://grodola.blogspot.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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread David Mertz
Fair enough. I wouldn't actually do what I suggested either. But then, I
also wouldn't ever write:

x1, x2 = (-b + sqrt(D)))/2, (-b - sqrt(D))/2 [with/where/whatever D=...]

If your goal is simply to have symmetry in the plus-or-minus clauses, I was
simply pointing out you can have that with the ':=' syntax.

Inasmuch as I might like assignment expressions, it would only be in while
or if statements, personally.

On Wed, Apr 11, 2018, 5:09 PM Brendan Barnwell 
wrote:

> On 2018-04-11 11:05, David Mertz wrote:
> > How about this, Brendan?
> >
> > _, x1, x2 = (D := b**2 - 4*a*c), (-b + sqrt(D))/2, (-b - sqrt(D))/2
> >
> > I'm not sure I love this, but I don't hate it.
>
> That's clever, but why bother?  I can already do this with
> existing Python:
>
> D = b**2 - 4*a*c
> x1, x2 = (-b + sqrt(D)))/2, (-b - sqrt(D))/2
>
> If the new feature encourages people to do something like your
> example
> (or my earlier examples with the D definition inline in the expression
> for x1), then I'd consider that another mark against it.
>
> --
> Brendan Barnwell
> "Do not follow where the path may lead.  Go, instead, where there is no
> path, and leave a trail."
> --author unknown
>
___
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] Accepting multiple mappings as positional arguments to create dicts

2018-04-12 Thread Andrés Delfino
There's a long thread about the subject:
https://mail.python.org/pipermail/python-ideas/2015-February/031748.html

I suggest to avoid the matter altogether :)

On Thu, Apr 12, 2018 at 4:15 PM, Mike Miller 
wrote:

> While we're on the subject, I've tried to add dicts a few times over the
> years to get a new one but it doesn't work:
>
> d3 = d1 + d2  # TypeError
>
> Thinking a bit, set union is probably a better analogue, but it doesn't
> work either:
>
> d3 = d1 | d2  # TypeError
>
> Where the last value of any duplicate keys should win.
>
> -Mike
>
>
>
> On 2018-04-12 06:46, Andrés Delfino wrote:
>
>> Extending the original idea, IMHO it would make sense for the dict
>> constructor to create a new dictionary not only from several mappings, but
>> mixing mappings and iterables too.
>>
>> Consider this example:
>>
>> x = [(1, 'one')]
>> y = {2: 'two'}
>>
>> Now: {**dict(x), **y}
>> Proposed: dict(x, y)
>>
> ___
> 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] Proposal: A Reduce-Map Comprehension and a "last" builtin

2018-04-12 Thread Peter O'Connor
On Wed, Apr 11, 2018 at 10:50 AM, Paul Moore  wrote:

> In particular, I'm happiest with the named moving_average() function,
> which may reflect to some extent my lack of familiarity with the
> subject area. I don't *care* how it's implemented internally - an
> explicit loop is fine with me, but if a domain expert wants to be
> clever and use something more complex, I don't need to know. An often
> missed disadvantage of one-liners is that they get put inline, meaning
> that people looking for a higher level overview of what the code does
> get confronted with all the gory details.


I'm all in favour of hiding things away into functions - I just think those
functions should be as basic as possible, without implicit assumptions
about how they will be used.  Let me give an example:



Lets look at your preferred method (A):

def moving_average(signal_iterable, decay, initial=0):
last_average = initial
for x in signal_iterable:
last_average = (1-decay)*last_average + decay*x
yield last_average

moving_average_gen = moving_average(signal, decay=decay,
initial=initial)

And compare it with (B), which would require the proposed syntax:

def moving_average_step(last_average, x, decay):
return (1-decay)*last_average + decay*x

moving_average_gen = (average:= moving_average_step(average, x,
decay=decay) for x in signal from x=initial)

-

Now, suppose we want to change things so that the "decay" changes with
every step.

The moving_average function (A) now has to be changed, because what we once
thought would be a fixed parameter is now a variable that changes between
calls.  Our options are:
- Make "decay" another iterable (in which case other functions calling
"moving_average" need to be changed).
- Leave an option for "decay" to be a float which gets transformed to an
iterable with "decay_iter = (decay for _ in itertools.count(0)) if
isinstance(decay, (int, float)) else decay".  (awkward because 95% of
usages don't need this.  If you do this for more parameters you suddenly
have this weird implementation with iterators everywhere even though in
most cases they're not needed).
- Factor out the "pure"  "moving_average_step" from "moving_average", and
create a new "moving_average_with_dynamic_decay" wrapper (but now we have
to maintain two wrappers - with the duplicated arguments - which starts to
require a lot of maintenance when you're passing down several parameters
(or you can use the dreaded **kwargs).

With approach (B) on the other hand, "moving_average_step" and all the
functions calling it, can stay the same: we just change the way we call it
in this instance to:

moving_average_gen = (average:= moving_average_step(average, x,
decay=decay) for x, decay in zip(signal, decay_schedule) from x=initial)



Now lets imagine this were a more complex function with 10 parameters.  I
see these kind of examples a lot in machine-learning and robotics programs,
where you'll have parameters like "learning rate", "regularization",
"minibatch_size", "maximum_speed", "height_of_camera" which might initially
be considered initialization parameters, but then later it turns out they
need to be changed dynamically.

This is why I think the "(y:=f(y, x) for x in xs from y=initial)" syntax
can lead to cleaner, more maintainable code.



On Wed, Apr 11, 2018 at 10:50 AM, Paul Moore  wrote:

> On 11 April 2018 at 15:37, Peter O'Connor 
> wrote:
>
> > If people are happy with these solutions and still see no need for the
> > initialization syntax, we can stop this, but as I see it there is a
> "hole"
> > in the language that needs to be filled.
>
> Personally, I'm happy with those solutions and see no need for the
> initialisation syntax.
>
> In particular, I'm happiest with the named moving_average() function,
> which may reflect to some extent my lack of familiarity with the
> subject area. I don't *care* how it's implemented internally - an
> explicit loop is fine with me, but if a domain expert wants to be
> clever and use something more complex, I don't need to know. An often
> missed disadvantage of one-liners is that they get put inline, meaning
> that people looking for a higher level overview of what the code does
> get confronted with all the gory details.
>
> 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] Accepting multiple mappings as positional arguments to create dicts

2018-04-12 Thread Mike Miller
While we're on the subject, I've tried to add dicts a few times over the years 
to get a new one but it doesn't work:


d3 = d1 + d2  # TypeError

Thinking a bit, set union is probably a better analogue, but it doesn't work 
either:

d3 = d1 | d2  # TypeError

Where the last value of any duplicate keys should win.

-Mike



On 2018-04-12 06:46, Andrés Delfino wrote:
Extending the original idea, IMHO it would make sense for the dict constructor 
to create a new dictionary not only from several mappings, but mixing mappings 
and iterables too.


Consider this example:

x = [(1, 'one')]
y = {2: 'two'}

Now: {**dict(x), **y}
Proposed: dict(x, y)

___
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] Move optional data out of pyc files

2018-04-12 Thread Daniel Moisset
I've been playing a bit with this trying to collect some data and measure
how useful this would be. You can take a look at the script I'm using at:
https://github.com/dmoisset/pycstats

What I'm measuring is:
1. Number of objects in the pyc, and how many of those are:
   * docstrings (I'm using a heuristic here which I'm not 100% sure it is
correct)
   * lnotabs
   * Duplicate objects; these have not been discussed in this thread before
but are another source of optimization I noticed while writing this.
Essentially I'm refering to immutable constants that are instanced more
than once and could be shared. You can also measure the effect of this
optimization across modules and within a single module[1]
2. Bytes used in memory by the categories above (sum of sys.getsizeof() for
each category).

I'm not measuring anything related to annotations because, as I mentioned
before, they are generated piecemeal by executable bytecode so they are
hard to separate

Running this on my python 3.6 pyc cache I get:

$ find /usr/lib/python3.6 -name '*.pyc' |xargs python3.6 pycstats.py
8645 docstrings, 1705441B
19060 lineno tables, 941702B
59382/202898 duplicate objects for 3101287/18582807 memory size

So this means around ~10% of the memory used after loading is used for
docstrings, ~5% for lnotabs, and ~15% for objects that could be shared. The
sharing assumes we can share betwwen modules, but even doing it within
modules, you can get to ~7%.

In short, this could mean a 25%-35% reduction in memory use for code
objects if the stdlib is a good benchmark.

Best,
D.

[1] Regarding duplicates, I've found some unexpected things within loaded
code objects, for example instances of the small integer "1" with different
id() than the singleton that cpython normally uses for "1", although most
duplicates are some small strings, tuples with argument names, or .
Something that could be interesting to write is a "pyc optimizer" that
removes duplicates, this should be a gain at a minimal preprocessing cost.


On 12 April 2018 at 15:16, Daniel Moisset  wrote:

> One implementation difficulty specifically related to annotations, is that
> they are quite hard to find/extract from the code objects. Both docstrings
> and lnotab are within specific fields of the code object for their
> function/class/module; annotations are spread as individual constants
> (assuming PEP 563), which are loaded in bytecode through separate
> LOAD_CONST statements before creating the function object, and that can
> happen in the middle of bytecode for the higher level object (the module or
> class containing a function definition). So the change for achieving that
> will be more significant than just "add a couple of descriptors to function
> objects and change the module marshalling code".
>
> Probably making annotations fit a single structure that can live in
> co_consts could make this change easier, and also make startup of annotated
> modules faster (because you just load a single constant instead of one per
> argument), this might be a valuable change by itself.
>
>
>
> On 12 April 2018 at 11:48, INADA Naoki  wrote:
>
>> > Finally, loading docstrings and other optional components can be made
>> lazy.
>> > This was not in my original idea, and this will significantly
>> complicate the
>> > implementation, but in principle it is possible. This will require
>> larger
>> > changes in the marshal format and bytecode.
>>
>> I'm +1 on this idea.
>>
>> * New pyc format has code section (same to current) and text section.
>> text section stores UTF-8 strings and not loaded at import time.
>> * Function annotation (only when PEP 563 is used) and docstring are
>> stored as integer, point to offset in the text section.
>> * When type.__doc__, PyFunction.__doc__, PyFunction.__annotation__ are
>> integer, text is loaded from the text section lazily.
>>
>> PEP 563 will reduce some startup time, but __annotation__ is still
>> dict.  Memory overhead is negligible.
>>
>> In [1]: def foo(a: int, b: int) -> int:
>>...: return a + b
>>...:
>>...:
>>
>> In [2]: import sys
>> In [3]: sys.getsizeof(foo)
>> Out[3]: 136
>>
>> In [4]: sys.getsizeof(foo.__annotations__)
>> Out[4]: 240
>>
>> When PEP 563 is used, there are no side effect while building the
>> annotation.
>> So the annotation can be serialized in text, like
>> {"a":"int","b":"int","return":"int"}.
>>
>> This change will require new pyc format, and descriptor for
>> PyFunction.__doc__, PyFunction.__annotation__
>> and type.__doc__.
>>
>> Regards,
>>
>> --
>> INADA Naoki  
>> ___
>> 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 - Machinalis Limited
> www.machinalis.co.uk 
> Skype: 

Re: [Python-ideas] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Fri, Apr 13, 2018 at 4:01 AM, Thautwarm Zhao  wrote:
>> > Makes sense. However, couldn't you prevent that by giving with
>> priority over the binding ? As in "(with simple_cm) as value", where
>> > we consider the "as" as binding operator instead of part of the with
>> > statement ? Sure, you could commit suicide by parenthesis, but by
>> > default it'd do exactly what the "with simple_cm as value" currently
>> > does. This does require use of as instead of :=, though. (which was
>> > the point I was trying to make, apologies for the confusion)
>>
>> Does "(with simple_cm) as value" means "with (simple_cm as value)"?
>> If so, it's impossible to let the priority of "with ... as ..." over `as`
>> binding.
>>
>> This is the grammar  of current syntax related to with statement:
>>
>> with_stmt: 'with' with_item (',' with_item)* ':' suite
>> with_item: test ['as' expr]
>>
>> If `as` binding could be used in a general expression, just as
>> `test` is the top of expression, an expression using `as` binding must be
>> in the structure > `test`.
>> In other words, if you write
>>
>> with expr as name:
>> # do stuff
>>
>> Without doubt it's equivalent to `with (expr as name)`.
>>
>> Or you want to completely change the grammar design of CPython :)
>>
>> thautwarm
>
> Additionally, here is an evidence.
>
> I've just had a look at Chris Angelico's implementation about expression
> assignment, it's  cool, however the problem is still raised.
>
> https://github.com/Rosuav/cpython/blob/0f237048b7665720b5165a40de0ed601c1e82c39/Grammar/Grammar
>
> `as` binding is added at line 111, obviously you cannot separate it from the
> `test` structure(because `test` is the top expr).
>
> testlist_comp: (test|star_expr) ( comp_for | 'as' NAME | (','
> (test|star_expr))* [','] )
>
> It seems that if we're to support expression assignment, `as` binding should
> be declined.
> To be honest I feel upset because I think `expr as name` is really cool and
> pythonic.
>

You're looking at a very early commit there. I suggest looking at the
most recent commits on one of two branches:

https://github.com/Rosuav/cpython/blob/statement-local-variables/Grammar/Grammar
https://github.com/Rosuav/cpython/blob/assignment-expressions/Grammar/Grammar

Those are the two most recent states in my progress towards (a)
statement-local name bindings with "EXPR as NAME", and (b) assignment
expressions with "target := value".

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] Python-ideas Digest, Vol 137, Issue 67

2018-04-12 Thread Thautwarm Zhao
 > Makes sense. However, couldn't you prevent that by giving with
> priority over the binding ? As in "(with simple_cm) as value", where
> we consider the "as" as binding operator instead of part of the with
> statement ? Sure, you could commit suicide by parenthesis, but by
> default it'd do exactly what the "with simple_cm as value" currently
> does. This does require use of as instead of :=, though. (which was
> the point I was trying to make, apologies for the confusion)

Does "(with simple_cm) as value" means "with (simple_cm as value)"?
If so, it's impossible to let the priority of "with ... as ..." over `as`
binding.

This is the grammar  of current syntax related to with statement:

with_stmt: 'with' with_item (',' with_item)* ':' suite
with_item: test ['as' expr]

If `as` binding could be used in a general expression, just as
`test` is the top of expression, an expression using `as` binding must be
in the structure `test`.
In other words, if you write

 with expr as name:
 # do stuff

Without doubt it's equivalent to `with (expr as name)`.

Or you want to completely change the grammar design of CPython :)

thautwarm



2018-04-12 21:41 GMT+08:00 :

> Send Python-ideas mailing list submissions to
> python-ideas@python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://mail.python.org/mailman/listinfo/python-ideas
> or, via email, send a message with subject or body 'help' to
> python-ideas-requ...@python.org
>
> You can reach the person managing the list at
> python-ideas-ow...@python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Python-ideas digest..."
>
> Today's Topics:
>
>1. Re: PEP 572: Assignment Expressions (post #4) (Chris Angelico)
>2. Re: PEP 572: Assignment Expressions (post #4) (Chris Angelico)
>3. Re: PEP 572: Assignment Expressions (post #4) (Nick Coghlan)
>4. Re: PEP 572: Assignment Expressions (post #4) (Jacco van Dorp)
>5. Re: PEP 572: Assignment Expressions (post #4) (Chris Angelico)
>
>
> -- 已转发邮件 --
> From: Chris Angelico 
> To: python-ideas 
> Cc:
> Bcc:
> Date: Thu, 12 Apr 2018 23:08:06 +1000
> Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4)
> On Thu, Apr 12, 2018 at 9:09 PM, Paul Moore  wrote:
> > On 11 April 2018 at 22:28, Chris Angelico  wrote:
> >> On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan 
> wrote:
> >>> This argument will be strengthened by making the examples used in the
> >>> PEP itself more attractive, as well as proposing suitable additions to
> >>> PEP 8, such as:
> >>>
> >>> 1. If either assignment statements or assignment expressions can be
> >>> used, prefer statements
> >>> 2. If using assignment expressions would lead to ambiguity about
> >>> execution order, restructure to use statements instead
> >>
> >> Fair enough. Also adding that chained assignment expressions should
> >> generally be avoided.
> >
> > Another one I think should be included (I'm a bit sad that it's not so
> > obvious that no-one would ever even think of it, but the current
> > discussion pretty much killed that hope for me).
> >
> > * Assignment expressions should never be used standalone - assignment
> > statements should *always* be used in that case.
>
> That's covered by the first point. If it's a standalone statement,
> then the statement form could be used, ergo you should prefer the
> statement form.
>
> ChrisA
>
>
>
> -- 已转发邮件 --
> From: Chris Angelico 
> To: python-ideas 
> Cc:
> Bcc:
> Date: Thu, 12 Apr 2018 23:14:34 +1000
> Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4)
> On Thu, Apr 12, 2018 at 7:21 PM, Kirill Balunov 
> wrote:
> >
> > I gain readability! I don't see any reason to use it in other contexts...
> > Because it makes the code unreadable and difficult to perceive while
> giving
> > not so much benefit.  I may be wrong, but so far I have not seen a single
> > example that at least slightly changed my mind.
>
> This is, in effect, your entire argument for permitting assignments
> only in certain contexts. "I can't think of any useful reason for
> doing this, so we shouldn't do it". But that means making the language
> grammar more complicated (both in the technical sense of the parser's
> definitions, and in the colloquial sense of how you'd explain Python
> to a new programmer), because there are these magic constructs that
> can be used anywhere in an expression, but ONLY if that expression is
> inside an if or while statement. You lose the ability to refactor your
> code simply to satisfy an arbitrary restriction to appease someone's
> feeling of "it can't be useful anywhere else".
>
> There are basically two clean ways to do this:
>
> 1) Create actual 

Re: [Python-ideas] Default values in multi-target assignment

2018-04-12 Thread Serhiy Storchaka

12.04.18 18:12, Guido van Rossum пише:
I hear where you're coming from but I really don't think we should do 
this. If you don't have the right expectation already it's hard to guess 
what it means. I would much rather spend effort on a proper matching 
statement.


There are few applications of this syntax, and it is not totally new, it 
is originated from the syntax of function parameters. But I agree with 
you. I prefer to keep the syntax of Python simpler.


___
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] Default values in multi-target assignment

2018-04-12 Thread Guido van Rossum
I hear where you're coming from but I really don't think we should do this.
If you don't have the right expectation already it's hard to guess what it
means. I would much rather spend effort on a proper matching statement.

On Thu, Apr 12, 2018 at 2:54 AM, Serhiy Storchaka 
wrote:

> Yet one crazy idea. What if allow default values for targets in
> multi-target assignment?
>
> >>> (a, b=0) = (1, 2)
> >>> a, b
> (1, 2)
> >>> (a, b=0) = (1,)
> >>> a, b
> (1, 0)
> >>> (a, b=0) = ()
> Traceback (most recent call last):
>   File "", line 1, in 
> ValueError: not enough values to unpack (expected at least 1, got 0)
> >>> (a, b=0) = (1, 2, 3)
> Traceback (most recent call last):
>   File "", line 1, in 
> ValueError: too many values to unpack (expected at most 2)
>
> Currently you need either explicitly check the length of the right-hand
> part (if it is a sequence and not an arbitrary iterator),
>
> if len(c) == 1:
> a, = c
> b = 0
> elif len(c) == 2:
> a, b = c
> else:
> raise TypeError
>
> or use an intermediate function:
>
> def f(a, b=0):
> return a, b
> a, b = f(*c)
>
> The latter can be written as an ugly one-liner:
>
> a, b = (lambda a, b=0: (a, b))(*c)
>
> ___
> 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] Accepting multiple mappings as positional arguments to create dicts

2018-04-12 Thread Guido van Rossum
On Thu, Apr 12, 2018 at 7:34 AM, Ed Kellett 
wrote:

> On 2018-04-12 14:46, Andrés Delfino wrote:
> > Extending the original idea, IMHO it would make sense for the dict
> > constructor to create a new dictionary not only from several mappings,
> but
> > mixing mappings and iterables too.
> >
> > Consider this example:
> >
> > x = [(1, 'one')]
> > y = {2: 'two'}
> >
> > Now: {**dict(x), **y}
> > Proposed: dict(x, y)
> >
> > I think this extension makes the call ostensibly easier to read and grep.
>
> It allows for creating a flattened dict from an iterable of dicts, too,
> which I've occasionally wanted:
>
> >>> configs = {'a': 'yes'}, {'b': 'no'}, {'c': 3}
> >>> dict(*configs)
> {'a': 'yes', 'b': 'no', 'c': 3}
>
> versus:
>
> >>> dict(chain.from_iterable(c.items() for c in configs))
> {'a': 'yes', 'b': 'no', 'c': 3}


Yes, this all sounds totally reasonable.

-- 
--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] Add the method decorator

2018-04-12 Thread Ed Kellett
On 2018-04-12 14:57, Serhiy Storchaka wrote:
> If noddy_name is a Python function, noddy.name() will call
> noddy_name(noddy), but if it is a C function, noddy.name() will call
> noddy_name().
> 
> The same is true for classes and custom callables.

FWIW, you could (almost) do this in py2:

>>> class Str(str): pass
...
>>> Str.print = types.MethodType(print, None, Str)
>>> Str("hello").print()
hello

> If a function is a descriptor, it can be converted into non-descriptor
> function by wrapping it with the staticmethod decorator. I suggest to
> add the method decorator, which converts an rbitrary callable into a
> descriptor.
> 
>     class Noddy:
>     name = method(noddy_name)
> 
> This will help to implement only performance critical method of a class
> in C.

Does the method decorator need to be written in C for the performance
benefit? If you can stand __get__ being Python, it's pretty easy to
write and doesn't need to change the language.

This does remind me of my favourite silly functional Python trick: as
long as foo is implemented in Python, foo.__get__(x)(y,z) is equivalent
to foo(x,y,z), which is useful if you find Python's standard partial
application syntax too ugly.

> Currently you need to implement a base class in C, and inherit
> Python class from C class. But this doesn't work when the class should
> be inherited from other C class, or when an existing class should be
> patched like in total_ordering.
> 
> This will help also to use custom callables as methods.

I wonder if it wouldn't make more sense to make the behaviour consistent
between Python and C functions... that

someclass.blah = a_python_function

already does a frequently-wrong thing suggests (to me) that maybe the
proper solution would be to bring back unbound method objects.

Ed



signature.asc
Description: OpenPGP digital signature
___
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] Accepting multiple mappings as positional arguments to create dicts

2018-04-12 Thread Ed Kellett
On 2018-04-12 14:46, Andrés Delfino wrote:
> Extending the original idea, IMHO it would make sense for the dict
> constructor to create a new dictionary not only from several mappings, but
> mixing mappings and iterables too.
> 
> Consider this example:
> 
> x = [(1, 'one')]
> y = {2: 'two'}
> 
> Now: {**dict(x), **y}
> Proposed: dict(x, y)
> 
> I think this extension makes the call ostensibly easier to read and grep.

It allows for creating a flattened dict from an iterable of dicts, too,
which I've occasionally wanted:

>>> configs = {'a': 'yes'}, {'b': 'no'}, {'c': 3}
>>> dict(*configs)
{'a': 'yes', 'b': 'no', 'c': 3}

versus:

>>> dict(chain.from_iterable(c.items() for c in configs))
{'a': 'yes', 'b': 'no', 'c': 3}

Ed



signature.asc
Description: OpenPGP digital signature
___
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] Move optional data out of pyc files

2018-04-12 Thread Daniel Moisset
One implementation difficulty specifically related to annotations, is that
they are quite hard to find/extract from the code objects. Both docstrings
and lnotab are within specific fields of the code object for their
function/class/module; annotations are spread as individual constants
(assuming PEP 563), which are loaded in bytecode through separate
LOAD_CONST statements before creating the function object, and that can
happen in the middle of bytecode for the higher level object (the module or
class containing a function definition). So the change for achieving that
will be more significant than just "add a couple of descriptors to function
objects and change the module marshalling code".

Probably making annotations fit a single structure that can live in
co_consts could make this change easier, and also make startup of annotated
modules faster (because you just load a single constant instead of one per
argument), this might be a valuable change by itself.



On 12 April 2018 at 11:48, INADA Naoki  wrote:

> > Finally, loading docstrings and other optional components can be made
> lazy.
> > This was not in my original idea, and this will significantly complicate
> the
> > implementation, but in principle it is possible. This will require larger
> > changes in the marshal format and bytecode.
>
> I'm +1 on this idea.
>
> * New pyc format has code section (same to current) and text section.
> text section stores UTF-8 strings and not loaded at import time.
> * Function annotation (only when PEP 563 is used) and docstring are
> stored as integer, point to offset in the text section.
> * When type.__doc__, PyFunction.__doc__, PyFunction.__annotation__ are
> integer, text is loaded from the text section lazily.
>
> PEP 563 will reduce some startup time, but __annotation__ is still
> dict.  Memory overhead is negligible.
>
> In [1]: def foo(a: int, b: int) -> int:
>...: return a + b
>...:
>...:
>
> In [2]: import sys
> In [3]: sys.getsizeof(foo)
> Out[3]: 136
>
> In [4]: sys.getsizeof(foo.__annotations__)
> Out[4]: 240
>
> When PEP 563 is used, there are no side effect while building the
> annotation.
> So the annotation can be serialized in text, like
> {"a":"int","b":"int","return":"int"}.
>
> This change will require new pyc format, and descriptor for
> PyFunction.__doc__, PyFunction.__annotation__
> and type.__doc__.
>
> Regards,
>
> --
> INADA Naoki  
> ___
> 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 - Machinalis Limited
www.machinalis.co.uk 
Skype: @dmoisset T: + 44 7398 827139

1 Fore St, London, EC2Y 9DT

Machinalis Limited is a company registered in England and Wales. Registered
number: 10574987.
___
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] Add the method decorator

2018-04-12 Thread Serhiy Storchaka
There is a difference between functions implemented in Python and C. 
Functions implemented in Python are descriptors. They can be used for 
defining methods in Python classes. Functions implemented in C are not 
descriptors. When set a class attribute to a functions implemented in C, 
it will not become a bound method.


from _noddy import noddy_name
class Noddy:
name = noddy_name
noddy = Noddy()

If noddy_name is a Python function, noddy.name() will call 
noddy_name(noddy), but if it is a C function, noddy.name() will call 
noddy_name().


The same is true for classes and custom callables.

If a function is a descriptor, it can be converted into non-descriptor 
function by wrapping it with the staticmethod decorator. I suggest to 
add the method decorator, which converts an rbitrary callable into a 
descriptor.


class Noddy:
name = method(noddy_name)

This will help to implement only performance critical method of a class 
in C. Currently you need to implement a base class in C, and inherit 
Python class from C class. But this doesn't work when the class should 
be inherited from other C class, or when an existing class should be 
patched like in total_ordering.


This will help also to use custom callables as methods.

___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Thu, Apr 12, 2018 at 11:19 PM, Nick Coghlan  wrote:
> On 12 April 2018 at 07:28, Chris Angelico  wrote:
>> On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan  wrote:
 Frequently Raised Objections
 
>>>
>>> There needs to be a subsection here regarding the need to call `del`
>>> at class and module scope, just as there is for loop iteration
>>> variables at those scopes.
>>
>> Hmm, I'm not sure I follow. Are you saying that this is an objection
>> to assignment expressions, or an objection to them not being
>> statement-local? If the latter, it's really more about "rejected
>> alternative proposals".
>
> It's both - accidentally polluting class and module namespaces is an
> argument against expression level assignments in general, and sublocal
> namespaces aimed to eliminate that downside.
>
> Since feedback on the earlier versions of the PEP has moved sublocal
> namespaces into the "rejected due to excessive conceptual complexity"
> box, that means accidental namespace pollution comes back as a
> downside that the PEP should mention.
>
> I don't think it needs to say much, just point out that they share the
> downside of regular for loops: if you use one at class or module
> scope, and don't want to export the name, you need to delete it
> explicitly.
>

Ah, makes sense. Thanks. Have added that to the latest version.

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] Accepting multiple mappings as positional arguments to create dicts

2018-04-12 Thread Andrés Delfino
Extending the original idea, IMHO it would make sense for the dict
constructor to create a new dictionary not only from several mappings, but
mixing mappings and iterables too.

Consider this example:

x = [(1, 'one')]
y = {2: 'two'}

Now: {**dict(x), **y}
Proposed: dict(x, y)

I think this extension makes the call ostensibly easier to read and grep. I
believe we are safe regarding compatibility issues, right?

What do you guys think?

On Wed, Apr 11, 2018 at 4:44 AM, Mike Miller 
wrote:

> Ok, we can haggle the finer details and I admit once you learn the syntax
> it isn't substantially harder.  Simply, I've found the dict() a bit easier
> to mentally parse at a glance.  Also, to add I've always expected multiple
> args to work with it, and am always surprised when it doesn't.
>
> Would never have thought of this unpacking syntax if I didn't know that's
> the way its done now, but often have to think about it for a second or two.
>
>
> On 2018-04-10 22:22, Chris Angelico wrote:
>
>> On Wed, Apr 11, 2018 at 2:44 PM, Steven D'Aprano 
>> wrote:
>>
>>> On Wed, Apr 11, 2018 at 02:22:08PM +1000, Chris Angelico wrote:
>>>
>>
> ___
> 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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Thu, Apr 12, 2018 at 11:31 PM, Jacco van Dorp  wrote:
> 2018-04-12 15:02 GMT+02:00 Nick Coghlan :
>> On 12 April 2018 at 22:22, Jacco van Dorp  wrote:
>>> I've looked through PEP 343, contextlib docs (
>>> https://docs.python.org/3/library/contextlib.html ), and I couldn't
>>> find a single case where "with (y := f(x))" would be invalid.
>>
>> Consider this custom context manager:
>>
>> @contextmanager
>> def simple_cm():
>> yield 42
>>
>> Given that example, the following code:
>>
>> with cm := simple_cm() as value:
>> print(cm.func.__name__, value)
>>
>> would print "'simple_cm 42", since the assignment expression would
>> reference the context manager itself, while the with statement binds
>> the yielded value.
>>
>> Another relevant example would be `contextlib.closing`: that returns
>> the passed in argument from __enter__, *not* self.
>>
>> And that's why earlier versions of PEP 572 (which used the "EXPR as
>> NAME" spelling) just flat out prohibited top level name binding
>> expressions in with statements: "with (expr as name):" and "with expr
>> as name:" were far too different semantically for the only syntactic
>> difference to be a surrounding set of parentheses.
>>
>> Cheers,
>> Nick.
>
> Makes sense. However, couldn't you prevent that by giving with
> priority over the binding ? As in "(with simple_cm) as value", where
> we consider the "as" as binding operator instead of part of the with
> statement ? Sure, you could commit suicide by parenthesis, but by
> default it'd do exactly what the "with simple_cm as value" currently
> does. This does require use of as instead of :=, though. (which was
> the point I was trying to make, apologies for the confusion)

If you want this to be a generic name-binding operation, then no; most
objects cannot be used as context managers. You'll get an exception if
you try to use "with 1 as x:", for instance.

As Nick mentioned, there are context managers that return something
other than 'self', and for those, "with expr as name:" has an
important meaning that cannot easily be captured with an assignment
operator.

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Jacco van Dorp
2018-04-12 15:02 GMT+02:00 Nick Coghlan :
> On 12 April 2018 at 22:22, Jacco van Dorp  wrote:
>> I've looked through PEP 343, contextlib docs (
>> https://docs.python.org/3/library/contextlib.html ), and I couldn't
>> find a single case where "with (y := f(x))" would be invalid.
>
> Consider this custom context manager:
>
> @contextmanager
> def simple_cm():
> yield 42
>
> Given that example, the following code:
>
> with cm := simple_cm() as value:
> print(cm.func.__name__, value)
>
> would print "'simple_cm 42", since the assignment expression would
> reference the context manager itself, while the with statement binds
> the yielded value.
>
> Another relevant example would be `contextlib.closing`: that returns
> the passed in argument from __enter__, *not* self.
>
> And that's why earlier versions of PEP 572 (which used the "EXPR as
> NAME" spelling) just flat out prohibited top level name binding
> expressions in with statements: "with (expr as name):" and "with expr
> as name:" were far too different semantically for the only syntactic
> difference to be a surrounding set of parentheses.
>
> Cheers,
> Nick.

Makes sense. However, couldn't you prevent that by giving with
priority over the binding ? As in "(with simple_cm) as value", where
we consider the "as" as binding operator instead of part of the with
statement ? Sure, you could commit suicide by parenthesis, but by
default it'd do exactly what the "with simple_cm as value" currently
does. This does require use of as instead of :=, though. (which was
the point I was trying to make, apologies for the confusion)
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Nick Coghlan
On 12 April 2018 at 07:28, Chris Angelico  wrote:
> On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan  wrote:
>>> Frequently Raised Objections
>>> 
>>
>> There needs to be a subsection here regarding the need to call `del`
>> at class and module scope, just as there is for loop iteration
>> variables at those scopes.
>
> Hmm, I'm not sure I follow. Are you saying that this is an objection
> to assignment expressions, or an objection to them not being
> statement-local? If the latter, it's really more about "rejected
> alternative proposals".

It's both - accidentally polluting class and module namespaces is an
argument against expression level assignments in general, and sublocal
namespaces aimed to eliminate that downside.

Since feedback on the earlier versions of the PEP has moved sublocal
namespaces into the "rejected due to excessive conceptual complexity"
box, that means accidental namespace pollution comes back as a
downside that the PEP should mention.

I don't think it needs to say much, just point out that they share the
downside of regular for loops: if you use one at class or module
scope, and don't want to export the name, you need to delete it
explicitly.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Thu, Apr 12, 2018 at 7:21 PM, Kirill Balunov  wrote:
>
> I gain readability! I don't see any reason to use it in other contexts...
> Because it makes the code unreadable and difficult to perceive while giving
> not so much benefit.  I may be wrong, but so far I have not seen a single
> example that at least slightly changed my mind.

This is, in effect, your entire argument for permitting assignments
only in certain contexts. "I can't think of any useful reason for
doing this, so we shouldn't do it". But that means making the language
grammar more complicated (both in the technical sense of the parser's
definitions, and in the colloquial sense of how you'd explain Python
to a new programmer), because there are these magic constructs that
can be used anywhere in an expression, but ONLY if that expression is
inside an if or while statement. You lose the ability to refactor your
code simply to satisfy an arbitrary restriction to appease someone's
feeling of "it can't be useful anywhere else".

There are basically two clean ways to do this:

1) Create actual syntax as part of the while statement, in the same
way that the 'with EXPR as NAME:' statement does. This means you
cannot put any additional operators after the 'as NAME' part. It's as
much a part of the statement's syntax as the word 'in' is in a for
loop.

2) Make this a feature of expressions in general. Then they can be
used anywhere that an expression can be.

I've gone for option 2. If you want to push for option 1, go ahead,
but it's a nerfed solution just because you personally cannot think of
any good use for this.

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Thu, Apr 12, 2018 at 9:09 PM, Paul Moore  wrote:
> On 11 April 2018 at 22:28, Chris Angelico  wrote:
>> On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan  wrote:
>>> This argument will be strengthened by making the examples used in the
>>> PEP itself more attractive, as well as proposing suitable additions to
>>> PEP 8, such as:
>>>
>>> 1. If either assignment statements or assignment expressions can be
>>> used, prefer statements
>>> 2. If using assignment expressions would lead to ambiguity about
>>> execution order, restructure to use statements instead
>>
>> Fair enough. Also adding that chained assignment expressions should
>> generally be avoided.
>
> Another one I think should be included (I'm a bit sad that it's not so
> obvious that no-one would ever even think of it, but the current
> discussion pretty much killed that hope for me).
>
> * Assignment expressions should never be used standalone - assignment
> statements should *always* be used in that case.

That's covered by the first point. If it's a standalone statement,
then the statement form could be used, ergo you should prefer the
statement form.

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Nick Coghlan
On 12 April 2018 at 22:22, Jacco van Dorp  wrote:
> I've looked through PEP 343, contextlib docs (
> https://docs.python.org/3/library/contextlib.html ), and I couldn't
> find a single case where "with (y := f(x))" would be invalid.

Consider this custom context manager:

@contextmanager
def simple_cm():
yield 42

Given that example, the following code:

with cm := simple_cm() as value:
print(cm.func.__name__, value)

would print "'simple_cm 42", since the assignment expression would
reference the context manager itself, while the with statement binds
the yielded value.

Another relevant example would be `contextlib.closing`: that returns
the passed in argument from __enter__, *not* self.

And that's why earlier versions of PEP 572 (which used the "EXPR as
NAME" spelling) just flat out prohibited top level name binding
expressions in with statements: "with (expr as name):" and "with expr
as name:" were far too different semantically for the only syntactic
difference to be a surrounding set of parentheses.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] Default values in multi-target assignment

2018-04-12 Thread Clint Hepner

> On 2018 Apr 12 , at 5:54 a, Serhiy Storchaka  wrote:
> 
> Yet one crazy idea. What if allow default values for targets in multi-target 
> assignment?
> 
>>>> (a, b=0) = (1, 2)
>>>> a, b
>(1, 2)
>>>> (a, b=0) = (1,)
>>>> a, b
>(1, 0)
>>>> (a, b=0) = ()
>Traceback (most recent call last):
>  File "", line 1, in 
>ValueError: not enough values to unpack (expected at least 1, got 0)
>>>> (a, b=0) = (1, 2, 3)
>Traceback (most recent call last):
>  File "", line 1, in 
>ValueError: too many values to unpack (expected at most 2)
> 
> Currently you need either explicitly check the length of the right-hand part 
> (if it is a sequence and not an arbitrary iterator),
> 
>if len(c) == 1:
>a, = c
>b = 0
>elif len(c) == 2:
>a, b = c
>else:
>raise TypeError
> 
> or use an intermediate function:
> 
>def f(a, b=0):
>return a, b
>a, b = f(*c)
> 
> The latter can be written as an ugly one-liner:
> 
>a, b = (lambda a, b=0: (a, b))(*c)

I think the best comparison would be

(a, b=0, *_) = t

vs

a, b, *_ = (*t, 0)
(a, b, *_) = (*t, 0)

In both, I've added *_ to capture any trailing elements. It's
more necessary with the current syntax, since adding defaults
will make the tuple too long when they aren't needed.

Given that, I'm +1 on the proposal, since

 1. Defaults are more closely associated with their intended name
 2. A new tuple doesn't need to be constructed on the RH

The one minor downside, IMO, is that if you choose to omit the *_ guard,
you *must* use parentheses on the LHS, as

a, b = 0 = t  # parsed as a, b = (0 = t)

raises a SyntaxError on the assignment to 0.

-- 
Clint

___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Jacco van Dorp
2018-04-12 13:28 GMT+02:00 Kirill Balunov :
>
>
> 2018-04-12 12:48 GMT+03:00 Jacco van Dorp :
>>
>> Wouldn't these local name bindings make the current "as" clause of
>> "with f(x) as y" completely obsolete ?
>>
>> It's probably good to know my background, and my background is that I
>> know completely nothing of the implementation, im only junior software
>> engineer, and python was my first programming experience, and still
>> the one I have by far the most experience with.
>>
>> To me, the entire proposal sounds mostly like an expansion of the as
>> syntax as we know it from "with". There will be no difference between:
>>
>> with open(filename) as f:
>> // code
>>
>> and
>>
>> with f  := open(filename):
>> // code
>>
>> or at least as far as I can see. (that is, if := will be allowed in
>> the with statement, and it sounds like it will ?)
>>
>
> Thank you Jacob! I do not know if I understood correctly how you understand
> what is happening here. But you are just demonstrating my fears about this
> proposal...
>
> with f  := open(filename):
>
> This will be only valid if the returned object of (f := open(filename))
> defines __enter__ and __exit__ methods ( Nevertheless, in this situation it
> is so). But in other cases it will raise an error. Generally  `with name  :=
> expr` is not equivalent to `with expr as name:`. In another places, for
> example, `except` clause `f := something` is valid only if the returned type
> is an object, which inherit from BaseException. So in this two situations,
> in my opinion, it will not be used too much.
>
> Yours example under current proposal should look like  `with open(
> full_file_path := os.path.join(path, filename) ) as f:`.
>
> With kind regards,
> -gdg

No, it will not raise an error to replace all these "as" usages with
name binding, if we choose operator priority right.

Even if we consider "with (y := f(x))", the f(x) the with gets is the
same as the one bound to the name - that's the point of the binding
expression. The only difference seems to be whether the name binding
is done before or after the __enter__ method - depending on operator
priority (see below).

I've looked through PEP 343, contextlib docs (
https://docs.python.org/3/library/contextlib.html ), and I couldn't
find a single case where "with (y := f(x))" would be invalid.

The only difference I can think of is objects where __enter__ doesn't
return self. Inexperienced programmers might forget it, so we're
giving them the "as y" part working instead of binding y to None.
There might be libraries out there that return a non-self value from
__enter__, which would alter behaviour. I honestly can't imagine why
you might do that tho.

And this could be entirely solved by giving "with" a higher priority
than "as". Then if "as" was used instead of ":=", you could just drop
"as" as part of the with statement, and it'd work the exact same way
everyone's used to.

And it's basically the same with "except x as y"; If except gets a
higher priority than as, it'd do the same thing(i.e., the exception
object gets bound to y, not the tuple of types). At least, that's what
it'd look like from outside. If people'd complain "but the local
binding does different behind except", you explain the same story as
when they would ask about the difference between + and * priority in
basic math - and they'd be free to use parenthesis as well if they
really want to for some reason i'm unable to comprehend.

except (errors := (TypeError, ValueError)) as e:  # Or of course:
except ( (TypeError, ValueError) as errors ) as e:
logger.info(f"Error {e} is included in types: {errors}")


Where it all comes together is that if as is chosen instead of :=, it
might just be far easier to comprehend for people how it works. "same
as in with" might be wrong technically, but it's simple and correct
conceptually.

Note: I'm talking about operator priority here as if with and except
return anything - which I know they don't. That probably complicates
it a lot more than it sounds like what I've tried to explain my
thoughts here, but I hope I made sense. (it's obvious to me, but well,
im dutch..(jk))

Jacco
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Kirill Balunov
2018-04-12 12:48 GMT+03:00 Jacco van Dorp :

> Wouldn't these local name bindings make the current "as" clause of
> "with f(x) as y" completely obsolete ?
>
> It's probably good to know my background, and my background is that I
> know completely nothing of the implementation, im only junior software
> engineer, and python was my first programming experience, and still
> the one I have by far the most experience with.
>
> To me, the entire proposal sounds mostly like an expansion of the as
> syntax as we know it from "with". There will be no difference between:
>
> with open(filename) as f:
> // code
>
> and
>
> with f  := open(filename):
> // code
>
> or at least as far as I can see. (that is, if := will be allowed in
> the with statement, and it sounds like it will ?)
>
>
Thank you Jacob! I do not know if I understood correctly how you understand
what is happening here. But you are just demonstrating my fears about this
proposal...

with f  := open(filename):

This will be only valid if the returned object of (f := open(filename)) defines
__enter__ and __exit__ methods ( Nevertheless, in this situation it is so).
But in other cases it will raise an error. Generally  `with name  := expr` is
not equivalent to `with expr as name:`. In another places, for example,
`except` clause `f := something` is valid only if the returned type is an
object, which inherit from BaseException. So in this two situations, in my
opinion, it will not be used too much.

Yours example under current proposal should look like  `with open(
full_file_path := os.path.join(path, filename) ) as f:`.

With kind regards,
-gdg
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Paul Moore
On 11 April 2018 at 22:28, Chris Angelico  wrote:
> On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan  wrote:
>> This argument will be strengthened by making the examples used in the
>> PEP itself more attractive, as well as proposing suitable additions to
>> PEP 8, such as:
>>
>> 1. If either assignment statements or assignment expressions can be
>> used, prefer statements
>> 2. If using assignment expressions would lead to ambiguity about
>> execution order, restructure to use statements instead
>
> Fair enough. Also adding that chained assignment expressions should
> generally be avoided.

Another one I think should be included (I'm a bit sad that it's not so
obvious that no-one would ever even think of it, but the current
discussion pretty much killed that hope for me).

* Assignment expressions should never be used standalone - assignment
statements should *always* be used in that case.

That's also one that I'd like to see implemented as a warning in the
common linters and style checkers.

I'm still not convinced that this whole proposal is a good thing (the
PEP 8 suggestions feel like fighting a rearguard action against
something that's inevitable but ill-advised), but if it does get
accepted it's in a lot better place now than it was when the
discussions started - so thanks for all the work you've done on
incorporating feedback.

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] Move optional data out of pyc files

2018-04-12 Thread INADA Naoki
> Finally, loading docstrings and other optional components can be made lazy.
> This was not in my original idea, and this will significantly complicate the
> implementation, but in principle it is possible. This will require larger
> changes in the marshal format and bytecode.

I'm +1 on this idea.

* New pyc format has code section (same to current) and text section.
text section stores UTF-8 strings and not loaded at import time.
* Function annotation (only when PEP 563 is used) and docstring are
stored as integer, point to offset in the text section.
* When type.__doc__, PyFunction.__doc__, PyFunction.__annotation__ are
integer, text is loaded from the text section lazily.

PEP 563 will reduce some startup time, but __annotation__ is still
dict.  Memory overhead is negligible.

In [1]: def foo(a: int, b: int) -> int:
   ...: return a + b
   ...:
   ...:

In [2]: import sys
In [3]: sys.getsizeof(foo)
Out[3]: 136

In [4]: sys.getsizeof(foo.__annotations__)
Out[4]: 240

When PEP 563 is used, there are no side effect while building the annotation.
So the annotation can be serialized in text, like
{"a":"int","b":"int","return":"int"}.

This change will require new pyc format, and descriptor for
PyFunction.__doc__, PyFunction.__annotation__
and type.__doc__.

Regards,

-- 
INADA Naoki  
___
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] Move optional data out of pyc files

2018-04-12 Thread Serhiy Storchaka

10.04.18 20:38, Chris Angelico пише:

On Wed, Apr 11, 2018 at 2:14 AM, Serhiy Storchaka  wrote:
A deployed Python distribution generally has .pyc files for all of the
standard library. I don't think people want to lose the ability to
call help(), and unless I'm misunderstanding, that requires
docstrings. So this will mean twice as many files and twice as many
file-open calls to import from the standard library. What will be the
impact on startup time?


Yes, this will mean more syscalls when import with docstrings. But the 
startup time doesn't matter for interactive shell in which you call 
help(). It was expected that programs which need to gain the benefit 
from separating optional components will run without loading them (like 
with option -OO).


The overhead can be reduced by packing multiple files in a single archive.

Finally, loading docstrings and other optional components can be made 
lazy. This was not in my original idea, and this will significantly 
complicate the implementation, but in principle it is possible. This 
will require larger changes in the marshal format and bytecode. This can 
open a door for further enhancements: loading the code and building 
classes and other complex data (especially heavy namedtuples, enums and 
dataclasses) on demand. Often you need to use just a single attribute or 
function from a large module. But this is different change, out of scope 
of this topic.


___
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] Default values in multi-target assignment

2018-04-12 Thread Serhiy Storchaka
Yet one crazy idea. What if allow default values for targets in 
multi-target assignment?


>>> (a, b=0) = (1, 2)
>>> a, b
(1, 2)
>>> (a, b=0) = (1,)
>>> a, b
(1, 0)
>>> (a, b=0) = ()
Traceback (most recent call last):
  File "", line 1, in 
ValueError: not enough values to unpack (expected at least 1, got 0)
>>> (a, b=0) = (1, 2, 3)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: too many values to unpack (expected at most 2)

Currently you need either explicitly check the length of the right-hand 
part (if it is a sequence and not an arbitrary iterator),


if len(c) == 1:
a, = c
b = 0
elif len(c) == 2:
a, b = c
else:
raise TypeError

or use an intermediate function:

def f(a, b=0):
return a, b
a, b = f(*c)

The latter can be written as an ugly one-liner:

a, b = (lambda a, b=0: (a, b))(*c)

___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Evpok Padding
On 11 April 2018 at 23:09, Brendan Barnwell  wrote:

> On 2018-04-11 11:05, David Mertz wrote:
>
>> How about this, Brendan?
>>
>> _, x1, x2 = (D := b**2 - 4*a*c), (-b + sqrt(D))/2, (-b - sqrt(D))/2
>>
>> I'm not sure I love this, but I don't hate it.
>>
>
> That's clever, but why bother?  I can already do this with
> existing Python:


Well, you were the one who suggested using an assignment expression for
that case.
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Chris Angelico
On Thu, Apr 12, 2018 at 4:45 PM, Michel Desmoulin
 wrote:
>
>
> Le 11/04/2018 à 23:34, George Leslie-Waksman a écrit :
>> I really like this proposal in the context of `while` loops but I'm
>> lukewarm in other contexts.
>>
>> I specifically like what this would do for repeated calls.
>>
>> ...
>>
>> md5 = hashlib.md5()
>> with open(filename, 'rb') as file_reader:
>> while chunk := file_reader.read(1024):
>> md5.update(chunk)
>>
>> seems really nice. I'm not sure the other complexity is justified by
>> this nicety and I'm really wary of anything that makes comprehensions
>> more complicated; I already see enough comprehension abuse to the point
>> of illegibility.
>>
>> --George
>>
>>
>
> I like the new syntax, but you can already do what you want with iter():
>
>
> md5 = hashlib.md5()
> with open('/etc/fstab', 'rb') as file_reader:
> for chunk in iter(lambda: file_reader.read(1024), b''):
> md5.update(chunk)
>
> Anyway, both use case fall short IRL, because you would wrap read in
> huge try/except to deal with the mess that is letting a user access the
> filesystem.

That works ONLY if you're trying to check for a sentinel condition via
equality. So that'll work for the file read situation, but it won't
work if you're watching for any negative number (from APIs that use
negative values to signal failure), nor something where you want the
condition to be "is not None", etc, etc, etc. Also, it doesn't read
nearly as well.

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] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Stephen J. Turnbull
Nick Coghlan writes:

 > > # Similar to the boolean 'or' but checking for None specifically
 > > x = "default" if (eggs := spam().ham) is None else eggs
 > >
 > > # Even complex expressions can be built up piece by piece
 > > y = ((eggs := spam()), (cheese := eggs.method()), cheese[eggs])

My immediate take was "this syntax is too ugly to live", but so are
Gila monsters, and I don't understand the virtues that lead Nick and
Guido to take this thread seriously.  So I will just leave that
statement here.  (no vote yet)

More constructively, I found it amusing that the results were stuffed
into generic one-character variables, while the temporaries got actual
words, presumably standing in for mnemonic identifiers.  Besides
moving the examples, that should be fixed if these examples are to be
used at all.  I'm also with Paul (IIRC) who suggested formatting the
second example on multiple lines.

I suggest s/x/filling/ (sandwich) and s/y/omelet/.

Steve
___
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] Proposal: flatten multi-nested list/tuple/set and other certain class/type.

2018-04-12 Thread delta114514
I thought that itertools.chain.from_iterable isn't useful.
cuz this only allow "single-nested iterable -- this will raise error when 
arg has non-nested element--" like below::
>>> from itertools import chain
>>> chain.from_iterable([1])

>>> list(_)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' object is not iterable

and this can't unpack over double nest.
>>> chain.from_iterable([[[1, 2]], [[4, 5]]])

>>> list(_)
[[1, 2], [4, 5]]
 
So, I wanted to make "True chain.from_iterable". and this is it.

def flatten(iterables, unpack=(list, tuple, set), peep=(list, tuple, set)):
for element in iterables:
try:
if isinstance(element, unpack):
if isinstance(element, peep):
yield from flatten(element, unpack=unpack, peep=peep)
else:
yield from flatten(element, unpack=(), peep=())
elif isinstance(element, peep):
yield type(element)(flatten(element, unpack=unpack, peep=peep))
else:
raise TypeError
except TypeError:
yield element


Reason why I didin't use type() is wanted to unpack type-object like "range"
and I wanted to unpack user-defined-class/func. this is why I didin't use 
collections.Iterable to check instance.

I know this will be destructed by itertools.count :(

Please give me advice.

And I wanna know why function like this is not in standard library.

thx.
___
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] flatten multi-nested list/set/tuple and certain types.

2018-04-12 Thread delta114514
I thought that itertools.chain.from_iterable isn't useful.
cuz this only allow "single-nested iterable -- this will raise error when 
arg has non-nested element--" like below::
>>> from itertools import chain
>>> chain.from_iterable([1])

>>> list(_)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' object is not iterable

and this can't unpack over double nest.
>>> chain.from_iterable([[[1, 2]], [[4, 5]]])

>>> list(_)
[[1, 2], [4, 5]]
 
So, I wanted to make "True chain.from_iterable". and this is it.

def flatten(iterables, unpack=(list, tuple, set), peep=(list, tuple, set)):
for element in iterables:
try:
if isinstance(element, unpack):
if isinstance(element, peep):
yield from flatten(element, unpack=unpack, peep=peep)
else:
yield from flatten(element, unpack=(), peep=())
elif isinstance(element, peep):
yield type(element)(flatten(element, unpack=unpack, peep=peep))
else:
raise TypeError
except TypeError:
yield element


Reason why I didin't use type() is wanted to unpack type-object like "range"
and I wanted to unpack user-defined-class/func. this is why I didin't use 
collections.Iterable to check instance.

I know this will be destructed by itertools.count :(

Please give me advice.

And I wanna know why function like this is not in standard library.

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