Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Devin Jeanpierre
On Tue, Nov 6, 2012 at 1:18 AM, Chris Withers  wrote:
> Hi All,
>
> I bumped into this using Michael Foord's Mock library.
> It feels like a bug to me, but thought I'd ask here before logging one in
> the tracker in case people know that we won't be able to fix it:
>
> On 05/11/2012 13:43, Michael Foord wrote:
>>
>>
>>> class Foo(object):

 ...  def __setattr__(s, k, v):
 ...   print k
 ...
>>>
>>> f = Foo()
>>>
>>> f.g = f.x = 3

 g
 x
>>>

It's terrible and counter-intuitive, but it is documented. See:
http://docs.python.org/2/reference/simple_stmts.html#assignment-statements

Notice that it proclaims that target lists are assigned to from left
to right. That's the behavior you've noticed.

On the other hand, one might easily misread this piece of
documentation, which implies right to left assignment:
http://docs.python.org/2/reference/expressions.html#evaluation-order

But the last note doesn't look normative to me.

(I'm not a dev, just trying to be helpful.)

-- Devin
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Terry Reedy

On 11/6/2012 1:18 AM, Chris Withers wrote:

Hi All,

I bumped into this using Michael Foord's Mock library.
It feels like a bug to me, but thought I'd ask here before logging one
in the tracker in case people know that we won't be able to fix it:

On 05/11/2012 13:43, Michael Foord wrote:



class Foo(object):

...  def __setattr__(s, k, v):
...   print k
...

f = Foo()

f.g = f.x = 3

g
x


Hmm, that's definitely counter-intuitive. Worth raising on python-dev?


Well, I guess "it's always been that way", so changing it would be
backwards incompatible. Feel free to raise it though. :-)


You are expecting a chained assignment a = b = c to be parsed as
a = (b = c), as in C and as it should be if assignment is an expression. 
But in Python it is not. The right association would be meaningless 
since (b = c) has no value to be assigned to a.


Python actually parses the chained assignment as (a =) (b =) c.
The relevant grammar production is "assignment_stmt ::=
(target_list "=")+ (expression_list | yield_expression)".
The explanation after the grammar begins with this sentence.

"An assignment statement evaluates the expression list (remember that 
this can be a single expression or a comma-separated list, the latter 
yielding a tuple) and assigns the single resulting object to each of the 
target lists, from left to right."


In other words, in my example, c is assigned to a then b. Please do not 
report documented behavior on the tracker as a bug (and don't encourage 
people to). If you think the above is not clear enough, you *can* 
suggest improvement. Perhaps add an example and explanation such as


a = b, (c,d), *e, f = 1, (2, 3), 4, 5, 6

"The tuple on the right is first assigned to a and then unpacked to b, 
c, d, e, and f, giving them the values 1, 2, 3, [4, 5], and 6."


--
Terry Jan Reedy

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Nick Coghlan
As noted, it's really only counterintuitive if your intuition is primed to
expect C style right to left chained assignments.

Python, on the other hand, is able to preserve primarily left to right
evaluation in this case with only the far right hand expression needing to
be evaluated out of order.

One example that can really make the intended behaviour clear:

*a = *b = iter(range(3))

a ends up as (0,1,2), b ends up as (), because the first assignment
consumes the entire iterable.

My actual advice, though? If the order of assignment really matters, use
multiple assignment statements rather than relying on readers knowing the
assignment order.

Cheers,
Nick.

--
Sent from my phone, thus the relative brevity :)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Rob Cliffe


On 06/11/2012 12:01, Nick Coghlan wrote:


As noted, it's really only counterintuitive if your intuition is 
primed to expect C style right to left chained assignments.


Python, on the other hand, is able to preserve primarily left to right 
evaluation in this case with only the far right hand expression 
needing to be evaluated out of order.




It strikes me that a really intuitive language (at least for Westerners 
who read left-to-right) would write assignments as

expression --> target
and then the order of assignment in
expression -> target1 -> target2
could be the natural left-to-right one.
[Sorry, this is more appropriate to Python-ideas, but I couldn't resist 
adding my 2c.]

Rob Cliffe

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/rob.cliffe%40btinternet.com


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread MRAB

On 2012-11-06 15:02, Rob Cliffe wrote:


On 06/11/2012 12:01, Nick Coghlan wrote:


As noted, it's really only counterintuitive if your intuition is
primed to expect C style right to left chained assignments.

Python, on the other hand, is able to preserve primarily left to right
evaluation in this case with only the far right hand expression
needing to be evaluated out of order.


It strikes me that a really intuitive language (at least for Westerners
who read left-to-right) would write assignments as
 expression --> target
and then the order of assignment in
 expression -> target1 -> target2
could be the natural left-to-right one.


That would make augmented assignment more difficult. For example, how
would you write the equivalent of "x -= y"?


[Sorry, this is more appropriate to Python-ideas, but I couldn't resist
adding my 2c.]
Rob Cliffe



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Guido van Rossum
+1 to what Nick said. And I thought about this carefully when
designing the language. It's not a bug. The note about assignment RHS
being evaluated before LHS is normative -- you just have to interpret
RHS as "after the *last* '=' symbol". Assignment itself is *not* an
expression.

On Tue, Nov 6, 2012 at 4:01 AM, Nick Coghlan  wrote:
> As noted, it's really only counterintuitive if your intuition is primed to
> expect C style right to left chained assignments.
>
> Python, on the other hand, is able to preserve primarily left to right
> evaluation in this case with only the far right hand expression needing to
> be evaluated out of order.
>
> One example that can really make the intended behaviour clear:
>
> *a = *b = iter(range(3))
>
> a ends up as (0,1,2), b ends up as (), because the first assignment consumes
> the entire iterable.
>
> My actual advice, though? If the order of assignment really matters, use
> multiple assignment statements rather than relying on readers knowing the
> assignment order.
>
> Cheers,
> Nick.
>
> --
> Sent from my phone, thus the relative brevity :)
>
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/guido%40python.org
>



-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Serhiy Storchaka

On 06.11.12 14:01, Nick Coghlan wrote:

Python, on the other hand, is able to preserve primarily left to right
evaluation in this case with only the far right hand expression needing
to be evaluated out of order.


I'm surprised, but it is really so.

  >>> {}[print('foo')] = print('bar')
  bar
  foo

I was expecting "foo" before "bar".

Another counterintuitive (and possible wrong) example:

  >>> {print('foo'): print('bar')}
  bar
  foo
  {None: None}


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread R. David Murray

On Tue, 06 Nov 2012 18:14:38 +0200, Serhiy Storchaka  
wrote:
> Another counterintuitive (and possible wrong) example:
> 
>>>> {print('foo'): print('bar')}
>bar
>foo
>{None: None}

http://bugs.python.org/issue11205

--David
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Ned Batchelder

On 11/6/2012 11:26 AM, R. David Murray wrote:

On Tue, 06 Nov 2012 18:14:38 +0200, Serhiy Storchaka  
wrote:

Another counterintuitive (and possible wrong) example:

>>> {print('foo'): print('bar')}
bar
foo
{None: None}

http://bugs.python.org/issue11205


This seems to me better left undefined, since there's hardly ever a need 
to know the precise evaluation sequence between keys and values, and 
retaining some amount of "unspecified" to allow for implementation 
flexibility is a good thing.


--Ned.



--David
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/ned%40nedbatchelder.com



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Devin Jeanpierre
On Nov 6, 2012 1:05 PM, "Ned Batchelder"  wrote:
>
> On 11/6/2012 11:26 AM, R. David Murray wrote:
>>
>> On Tue, 06 Nov 2012 18:14:38 +0200, Serhiy Storchaka 
wrote:
>>>
>>> Another counterintuitive (and possible wrong) example:
>>>
>>> >>> {print('foo'): print('bar')}
>>> bar
>>> foo
>>> {None: None}
>>
>> http://bugs.python.org/issue11205
>
>
> This seems to me better left undefined, since there's hardly ever a need
to know the precise evaluation sequence between keys and values, and
retaining some amount of "unspecified" to allow for implementation
flexibility is a good thing.

"Left undefined"? The behavior was defined, but CPython didn't follow the
defined behaviour.

--Devin (phone)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Ned Batchelder


On 11/6/2012 1:19 PM, Devin Jeanpierre wrote:



On Nov 6, 2012 1:05 PM, "Ned Batchelder" > wrote:

>
> On 11/6/2012 11:26 AM, R. David Murray wrote:
>>
>> On Tue, 06 Nov 2012 18:14:38 +0200, Serhiy Storchaka 
mailto:storch...@gmail.com>> wrote:

>>>
>>> Another counterintuitive (and possible wrong) example:
>>>
>>> >>> {print('foo'): print('bar')}
>>> bar
>>> foo
>>> {None: None}
>>
>> http://bugs.python.org/issue11205
>
>
> This seems to me better left undefined, since there's hardly ever a 
need to know the precise evaluation sequence between keys and values, 
and retaining some amount of "unspecified" to allow for implementation 
flexibility is a good thing.


"Left undefined"? The behavior was defined, but CPython didn't follow 
the defined behaviour.




I would change the reference manual to leave it undefined.  Clearly not 
many people have been bothered by the fact that CPython implemented it 
"wrong".  If someone really needs to control whether the keys or values 
are evaluated first, they shouldn't use a dict literal.


--Ned.


--Devin (phone)



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Greg Ewing

MRAB wrote:

That would make augmented assignment more difficult. For example, how
would you write the equivalent of "x -= y"?


SUBTRACT x FROM y.

CLOSE POST WITH SMILEY.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Guido van Rossum
On Tue, Nov 6, 2012 at 9:58 AM, Ned Batchelder  wrote:
> On 11/6/2012 11:26 AM, R. David Murray wrote:
>>
>> On Tue, 06 Nov 2012 18:14:38 +0200, Serhiy Storchaka 
>> wrote:
>>>
>>> Another counterintuitive (and possible wrong) example:
>>>
>>> >>> {print('foo'): print('bar')}
>>> bar
>>> foo
>>> {None: None}
>>
>> http://bugs.python.org/issue11205
>
>
> This seems to me better left undefined, since there's hardly ever a need to
> know the precise evaluation sequence between keys and values, and retaining
> some amount of "unspecified" to allow for implementation flexibility is a
> good thing.

Maybe. Do note that Python tries to be *different* than your average
C++ standard and actually prescribes evaluation orders in most cases.
The idea being that the kind of optimizations that C++ compilers get
to do by moving evaluation order around aren't worth it in Python
anyway, and it's better for the user if there are no arbitrary
differences in this area between Python implementations. Note that I
didn't say "no surprises" -- the post that started this thread shows
that surprises are still possible.

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-06 Thread Serhiy Storchaka

On 06.11.12 21:00, Ned Batchelder wrote:

If someone really needs to control whether the keys or values
are evaluated first, they shouldn't use a dict literal.


Not only a dict literal.

>>> {print('foo'): print('bar') for x in [1]}
bar
foo
{None: None}


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Ned Batchelder


On 11/6/2012 5:12 PM, Guido van Rossum wrote:

On Tue, Nov 6, 2012 at 9:58 AM, Ned Batchelder  wrote:

On 11/6/2012 11:26 AM, R. David Murray wrote:

On Tue, 06 Nov 2012 18:14:38 +0200, Serhiy Storchaka 
wrote:

Another counterintuitive (and possible wrong) example:

 >>> {print('foo'): print('bar')}
 bar
 foo
 {None: None}

http://bugs.python.org/issue11205


This seems to me better left undefined, since there's hardly ever a need to
know the precise evaluation sequence between keys and values, and retaining
some amount of "unspecified" to allow for implementation flexibility is a
good thing.

Maybe. Do note that Python tries to be *different* than your average
C++ standard and actually prescribes evaluation orders in most cases.
The idea being that the kind of optimizations that C++ compilers get
to do by moving evaluation order around aren't worth it in Python
anyway, and it's better for the user if there are no arbitrary
differences in this area between Python implementations. Note that I
didn't say "no surprises" -- the post that started this thread shows
that surprises are still possible.



I think it's unfortunate that the current patch in the referenced bug ( 
http://bugs.python.org/issue11205 ) fixes the "problem" by adding one 
more bytecode to the compiled Python.  The other alternative seems to be 
changing the meaning of two opcodes. Neither of these are great 
alternatives.  I know we don't promise to maintain backward 
compatibility in the meanings of opcodes, but I'll bet actual code will 
be broken by changing the meaning of STORE_MAP and MAP_ADD.  Slowing 
down dict displays (just slightly) to get this right seems unfortunate also.


If the bug report is accurate, CPython and the reference manual have 
disagreed since Python 2.5, and many of us are now surprised to hear it, 
which means there can't have been much broken code.


I understand the point about C compilers having more opportunities to 
take advantage of "undefined" in the spec, but Python implementations 
are getting cleverer about how to implement Python semantics as well, 
perhaps we should have some faith in their future cleverness and give 
them even a little bit of leeway.  I don't imagine this little bit will 
actually be useful to them, but making this undefined will already help 
CPython by avoiding either an extra bytecode or a change in the opcodes.


There are plenty of places where different Python implementations 
differ, and even careful observers had different ideas about how keys 
and values were ordered in dict displays ("I thought it was like a 
function call,"  vs, "I thought it was like an assignment"). We've gone 
out of our way to maintain backward compatibility with the implemented 
behavior before (ordering of dict keys, for example).  The simplest 
change to make here is to update the reference and keep the implementation.


--Ned.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Nick Coghlan
On Wed, Nov 7, 2012 at 10:13 PM, Ned Batchelder  wrote:
> There are plenty of places where different Python implementations differ,
> and even careful observers had different ideas about how keys and values
> were ordered in dict displays ("I thought it was like a function call,"  vs,
> "I thought it was like an assignment"). We've gone out of our way to
> maintain backward compatibility with the implemented behavior before
> (ordering of dict keys, for example).  The simplest change to make here is
> to update the reference and keep the implementation.

"The implementation is right, the docs are wrong" sounds good to me,
as it's easy to justify the out of order evaluation in terms of the
equivalent item assignment statements:

x = {a:b, c:d}

vs

x = {}
x[a] = b
x[c] = d

That relationship is quite logical given that (ignoring namespace
details) dict construction from a display [1] pretty much does the
equivalent of:

result = {}
for key_expr, val_expr in display_entries:
result[eval(key_expr)] = eval(val_expr)

This comment [2] from the dict comprehension implementation makes it
explicit that the behaviour of the equivalent Python item assignment
code was taken to be normative.

[1] http://hg.python.org/cpython/file/default/Python/compile.c#l3319
[2] http://hg.python.org/cpython/file/default/Python/compile.c#l3020

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Chris Angelico
On Thu, Nov 8, 2012 at 1:11 AM, Nick Coghlan  wrote:
> "The implementation is right, the docs are wrong" sounds good to me,
> as it's easy to justify the out of order evaluation in terms of the
> equivalent item assignment statements:

What do other Pythons than CPython do currently? Or is it "The
reference implementation is right, the docs are wrong"?

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Łukasz Rekucki
On 7 November 2012 15:16, Chris Angelico  wrote:
> On Thu, Nov 8, 2012 at 1:11 AM, Nick Coghlan  wrote:
>> "The implementation is right, the docs are wrong" sounds good to me,
>> as it's easy to justify the out of order evaluation in terms of the
>> equivalent item assignment statements:
>
> What do other Pythons than CPython do currently? Or is it "The
> reference implementation is right, the docs are wrong"?

PyPy and IronPython are the same as CPython. Only Jython (both 2.5 and
2.7a) follows the docs.

Regards,
Łukasz Rekucki
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Guido van Rossum
On Wed, Nov 7, 2012 at 4:13 AM, Ned Batchelder  wrote:
> I think it's unfortunate that the current patch in the referenced bug (
> http://bugs.python.org/issue11205 ) fixes the "problem" by adding one more
> bytecode to the compiled Python.  The other alternative seems to be changing
> the meaning of two opcodes. Neither of these are great alternatives.  I know
> we don't promise to maintain backward compatibility in the meanings of
> opcodes, but I'll bet actual code will be broken by changing the meaning of
> STORE_MAP and MAP_ADD.  Slowing down dict displays (just slightly) to get
> this right seems unfortunate also.

I agree this would be unfortunate and I recommend that you add this to
the bug. I agree that we should be *very* conservative in changing the
meaning of existing opcodes (adding new one is a different story).

But it was fixed before (http://bugs.python.org/issue448679 has a
simple fix that doesn't change opcode meanings and was applied in
2001) -- what happened?

> If the bug report is accurate, CPython and the reference manual have
> disagreed since Python 2.5, and many of us are now surprised to hear it,
> which means there can't have been much broken code.

Give that it was discussed before and fixed before, I think the intent
is clear: we should fix the code, not the docs.

> I understand the point about C compilers having more opportunities to take
> advantage of "undefined" in the spec, but Python implementations are getting
> cleverer about how to implement Python semantics as well, perhaps we should
> have some faith in their future cleverness and give them even a little bit
> of leeway.

Hm. I really don't think that is a good development for Python to
compromise in the area of expression evaluation order where side
effects are involved. A good compiler should be able to detect the
absence of potential side effects. E.g. it might reorder when only
constants and simple variable references are present, or (in the case
of a JIT, which has run-time type information) when it knows enough
about the types of the operands involved to determine that operations
like getattr or getitem are guaranteed side-effect-free.

> I don't imagine this little bit will actually be useful to them,
> but making this undefined will already help CPython by avoiding either an
> extra bytecode or a change in the opcodes.

I haven't looked at the proposed fixes, but I think correctness is
more important than saving an extra bytecode (OTOH keeping the set of
opcodes the same trumps both). I can't imagine that this extra opcode
will be significant in many cases.

> There are plenty of places where different Python implementations differ,
> and even careful observers had different ideas about how keys and values
> were ordered in dict displays ("I thought it was like a function call,"  vs,
> "I thought it was like an assignment"). We've gone out of our way to
> maintain backward compatibility with the implemented behavior before
> (ordering of dict keys, for example).

Not sure what you're referencing here -- didn't we just start
randomizing hashing?

> The simplest change to make here is
> to update the reference and keep the implementation.

In this particular case I disagree.

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Chris Angelico
On Thu, Nov 8, 2012 at 1:54 AM, Guido van Rossum  wrote:
> On Wed, Nov 7, 2012 at 4:13 AM, Ned Batchelder  wrote:
>> We've gone out of our way to
>> maintain backward compatibility with the implemented behavior before
>> (ordering of dict keys, for example).
>
> Not sure what you're referencing here -- didn't we just start
> randomizing hashing?

Hash randomization could have been quietly introduced as a security
fix and backported to old versions. But since applications might have
depended on dict iteration order, it wasn't - old versions of Python
won't randomize hashes unless you set an environment variable. That's
taking care of old code, even when that old code is depending on
non-spec behaviour.

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Nick Coghlan
On Thu, Nov 8, 2012 at 12:54 AM, Guido van Rossum  wrote:
> On Wed, Nov 7, 2012 at 4:13 AM, Ned Batchelder  wrote:
>> If the bug report is accurate, CPython and the reference manual have
>> disagreed since Python 2.5, and many of us are now surprised to hear it,
>> which means there can't have been much broken code.
>
> Give that it was discussed before and fixed before, I think the intent
> is clear: we should fix the code, not the docs.

Almost certainly, it was broken in the migration to the AST compiler
and there was no regression test to pick up the change.

> I haven't looked at the proposed fixes, but I think correctness is
> more important than saving an extra bytecode (OTOH keeping the set of
> opcodes the same trumps both). I can't imagine that this extra opcode
> will be significant in many cases.

Since you've indicated the implementation is in the wrong here and you
also want to preserve opcode semantics, I think Skip's patch is
correct, but also needs to be applied to dict comprehensions (now we
have them). The extra bytecode is only ROT_TWO, which is one of the
cheapest we have kicking around :)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Guido van Rossum
Ok, somebody go for it! (Also please refer to my pronouncement in the bug
-- I've gotta run.)


On Wed, Nov 7, 2012 at 7:12 AM, Nick Coghlan  wrote:

> On Thu, Nov 8, 2012 at 12:54 AM, Guido van Rossum 
> wrote:
> > On Wed, Nov 7, 2012 at 4:13 AM, Ned Batchelder 
> wrote:
> >> If the bug report is accurate, CPython and the reference manual have
> >> disagreed since Python 2.5, and many of us are now surprised to hear it,
> >> which means there can't have been much broken code.
> >
> > Give that it was discussed before and fixed before, I think the intent
> > is clear: we should fix the code, not the docs.
>
> Almost certainly, it was broken in the migration to the AST compiler
> and there was no regression test to pick up the change.
>
> > I haven't looked at the proposed fixes, but I think correctness is
> > more important than saving an extra bytecode (OTOH keeping the set of
> > opcodes the same trumps both). I can't imagine that this extra opcode
> > will be significant in many cases.
>
> Since you've indicated the implementation is in the wrong here and you
> also want to preserve opcode semantics, I think Skip's patch is
> correct, but also needs to be applied to dict comprehensions (now we
> have them). The extra bytecode is only ROT_TWO, which is one of the
> cheapest we have kicking around :)
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
>



-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Serhiy Storchaka

On 07.11.12 17:12, Nick Coghlan wrote:

Since you've indicated the implementation is in the wrong here and you
also want to preserve opcode semantics, I think Skip's patch is
correct, but also needs to be applied to dict comprehensions (now we
have them). The extra bytecode is only ROT_TWO, which is one of the
cheapest we have kicking around :)


Not only to dict comprehensions, but also to item assignments.  It will 
be weird if a dict comprehension and a plain loop will be inconsistent.



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Terry Reedy

On 11/7/2012 9:54 AM, Guido van Rossum wrote:


Hm. I really don't think that is a good development for Python to
compromise in the area of expression evaluation order where side
effects are involved.


I agreee. I think Python's simple left to right evaluation order is one 
of its virtues.



A good compiler should be able to detect the
absence of potential side effects. E.g. it might reorder when only
constants and simple variable references are present, or (in the case
of a JIT, which has run-time type information) when it knows enough
about the types of the operands involved to determine that operations
like getattr or getitem are guaranteed side-effect-free.


I call this the 'as-if' rule: the compiler can take shortcuts if the 
result is 'as-if' no shortcut.


--
Terry Jan Reedy

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Terry Reedy

On 11/7/2012 10:17 AM, Guido van Rossum wrote:

Ok, somebody go for it! (Also please refer to my pronouncement in the
bug -- I've gotta run.)


Done. http://bugs.python.org/issue11205?@ok_message=msg 175120

--
Terry Jan Reedy

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Ned Batchelder


On 11/7/2012 12:08 PM, Serhiy Storchaka wrote:

On 07.11.12 17:12, Nick Coghlan wrote:

Since you've indicated the implementation is in the wrong here and you
also want to preserve opcode semantics, I think Skip's patch is
correct, but also needs to be applied to dict comprehensions (now we
have them). The extra bytecode is only ROT_TWO, which is one of the
cheapest we have kicking around :)


Not only to dict comprehensions, but also to item assignments.  It 
will be weird if a dict comprehension and a plain loop will be 
inconsistent.



Just to be clear: the reference guide says that the behavior *SHOULD BE* 
(but is not yet) this:


   Python 3.3.0
>>> {print("a"):print("b")}
   a
   b
   {None: None}
>>> d = {}
>>> d[print("a")] = print("b")
   b
   a
>>>

Is this or is this not "weird" to you?

--Ned.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/ned%40nedbatchelder.com




___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Guido van Rossum
The dict display is considered an *expression* and thus must follow
the L2R rule. The assignment is explicitly covered by the R2L rule for
assignments (only). Weird or not, those are the rules, and I don't
want to change them.

On Wed, Nov 7, 2012 at 1:39 PM, Ned Batchelder  wrote:
>
> On 11/7/2012 12:08 PM, Serhiy Storchaka wrote:
>
> On 07.11.12 17:12, Nick Coghlan wrote:
>
> Since you've indicated the implementation is in the wrong here and you
> also want to preserve opcode semantics, I think Skip's patch is
> correct, but also needs to be applied to dict comprehensions (now we
> have them). The extra bytecode is only ROT_TWO, which is one of the
> cheapest we have kicking around :)
>
>
> Not only to dict comprehensions, but also to item assignments.  It will be
> weird if a dict comprehension and a plain loop will be inconsistent.
>
>
> Just to be clear: the reference guide says that the behavior *SHOULD BE*
> (but is not yet) this:
>
> Python 3.3.0
 {print("a"):print("b")}
> a
> b
> {None: None}
 d = {}
 d[print("a")] = print("b")
> b
> a

>
> Is this or is this not "weird" to you?
>
> --Ned.
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/ned%40nedbatchelder.com
>
>
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/guido%40python.org
>



-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Terry Reedy

On 11/7/2012 4:39 PM, Ned Batchelder wrote:


Just to be clear: the reference guide says that the behavior *SHOULD BE*
(but is not yet) this:

Python 3.3.0
 >>> {print("a"):print("b")}
a
b
{None: None}
 >>> d = {}
 >>> d[print("a")] = print("b")
b
a
 >>>

Is this or is this not "weird" to you?


Not weird. Expressions and assignment targets are each consistently 
evaluated left to right (except as *necessarily* alter by precedence), 
with expressions evaluated before targets.


What is weird -- to me ;-) -- is using side-effects in either example above.

--
Terry Jan Reedy

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Steven D'Aprano

On 08/11/12 08:39, Ned Batchelder wrote:


Just to be clear: the reference guide says that the behavior *SHOULD BE* (but 
is not yet) this:

Python 3.3.0

>> {print("a"):print("b")}

a
b
{None: None}



That was the behaviour of Python 2.4:

py> def pr(x):
... print x
...
py> {pr(1): pr(2), pr(3): pr(4)}
1
2
3
4
{None: None}


2.5 changed to the behaviour seen now, that is, it prints 2 1 4 3
in that order.



>> d = {}
>> d[print("a")] = print("b")

b
a

Is this or is this not "weird" to you?


Not weird to me. The first case has no assignment, so it operates
left to right without exception. The second case has an assignment,
so it operates left to right with a single exception, the right
hand side of the assignment is evaluated before the left hand side(s).

This gives a single, intuitive[1] order of evaluation (left to right),
with the fewest number of exceptions necessary[2]. Using Python 2.4
again:


py> d = {}
py> d[pr(1)] = d[pr(2)] = d[pr(3)] = pr(4) is pr(5)
4
5
1
2
3





[1] Well, intuitive to those whose native language reads left to right.

[2] I assume it is necessary.



--
Steven
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-07 Thread Ned Batchelder

On 11/7/2012 5:11 PM, Terry Reedy wrote:

On 11/7/2012 4:39 PM, Ned Batchelder wrote:


Just to be clear: the reference guide says that the behavior *SHOULD BE*
(but is not yet) this:

Python 3.3.0
 >>> {print("a"):print("b")}
a
b
{None: None}
 >>> d = {}
 >>> d[print("a")] = print("b")
b
a
 >>>

Is this or is this not "weird" to you?


Not weird. Expressions and assignment targets are each consistently 
evaluated left to right (except as *necessarily* alter by precedence), 
with expressions evaluated before targets.


Sorry, I should have been clearer: I was asking about weird not to say, 
"This is weird and should be changed!", but to get clarification from 
Serhiy about his statement, " It will be weird if a dict comprehension 
and a plain loop will be inconsistent."  I honestly didn't know which 
behavior he considered inconsistent and therefore weird.


--Ned.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] chained assignment weirdity

2012-11-08 Thread Serhiy Storchaka
On 08.11.12 03:11, Ned Batchelder wrote:
> Sorry, I should have been clearer: I was asking about weird not to say, 
> "This is weird and should be changed!", but to get clarification from 
> Serhiy about his statement, " It will be weird if a dict comprehension 
> and a plain loop will be inconsistent."  I honestly didn't know which 
> behavior he considered inconsistent and therefore weird.

I was referring to two of the most popular idioms to dynamically create a dict.

  d = {}
  for x in a:
  d[k(x)] = v(x)

  d = {k(x): v(x) for x in a}

For now these methods are consistent.

I agree that the use of the side effects here is not a sensible idea, but when 
such effects occur by accident, it will cause a surprise.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com