[Python-Dev] Re: Merging PRs without CLA signed

2020-02-27 Thread Brett Cannon
My personal stance is if Microsoft Word could have come up with the change then 
a signed CLA is _probably_ not needed (IOW typos and grammatical errors).

But honestly, I fall into the same camp as Mariatta and Pablo out of laziness 
and fear of being wrong. :) Laziness because there are plenty of other people 
willing to sign the CLA and participate fully that I would rather help out with 
my limited open source time. Out of fear because I don't want to get this wrong 
and be the reason the PSF gets sued some day.

Personally, I hope we move to CLA Assistant (or improve the-knights-who-say-ni 
to be as usable) and then make CLA signing a required status check on PRs to 
negate having to think about this.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/QQYQSI3X26IK23MJPEQJKYNLTVZSVHP3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Brandt Bucher
Thanks for your response Serhiy.

> Yes, but this is a different thing. You must to implement new __or__ in a 
> subclass to make the behavior of d1 | d2 be different from {**d1, **d2}.

Really? I'm sorry, but this doesn't feel like a real argument to me.

There was no clear compatible path before. Now there is. It works by default, 
returning a dict for dict subclasses. If you want to change the return type (or 
do something else), you do have to do a little work. Same for every other 
overridden thing in any other subclass.

Besides, our argument was just the opposite: "you can't implement anything in a 
subclass to make the type of {**d1, **d2} be different".

Now that we've provided a way, it's a problem because you have to define custom 
behavior (if you want it)?

> you want an operation for merging OrderedDict, defaultdict, etc and add 
> dict.__or__ just for symmetry, even if it is not actually necessary for dicts.

Except that now every dict subclass gets this for free. And now everything 
quacks alike.

Are you really suggesting that it would make more sense to implement this for 
all subclasses, but not dict itself? I don't think you are, but it sure sounds 
like it.

> Let's take a closer look at these examples.

I appreciate that you've taken the time to go through each one, but please note 
that the PEP finishes with:

> The above examples show that sometimes the | operator leads to a clear 
> increase in readability... However other examples using the | operator lead 
> to long, complex single expressions... As with any other language feature, 
> the programmer should use their own judgement about whether | improves their 
> code.

We're not suggesting that all of the examples would be better, or even 
equivalent with the new code. During the discussions last year, people kept 
asking for before-and-after examples. We decided to extract real examples 
rather than fabricate toys, so for the purposes of this PEP you can assume that 
they stand on their own, void of context.

For example, I considered removing the `globs` example because, like you, I 
thought it was uglier. However, I figured that it would be wrong to omit it, 
since the goal of the section was to show as many candidates for the operator 
that we could trivially find, not "all of the ones that Brandt likes better 
with |". :)

I'm not sure that continuing this thread of discussion is very productive. As I 
have mentioned before, the huge PEP is roughly:

- 50% responses to arguments.
- 35% examples.
- 10% specification.
- 5% links to prior discussions.

We've addressed anything that we felt needed addressing, and they have been 
enough to persuade the necessary decision makers. Many of the points you make 
have been responded to in some way or another in this monster of a document. :)
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/RHFTVX7IV7VG3GLEVE4ZWOIHTCB2JQBK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Unpacking native bools in the struct module: Is Python relying on undefined behavior?

2020-02-27 Thread Serge Guelton
> Quick and obvious fix:
> 
>  static PyObject *
>  nu_bool(const char *p, const formatdef *f)
>  {
>  char x;
>  memcpy((char *), p, sizeof x);
>  return PyBool_FromLong(x != 0);
>  }

Which is optimized to

 static PyObject *
 nu_bool(const char *p, const formatdef *f)
 {
 return PyBool_FromLong(*p != 0);
 }

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


[Python-Dev] Re: Unpacking native bools in the struct module: Is Python relying on undefined behavior?

2020-02-27 Thread Serge Guelton
On Thu, Feb 27, 2020 at 10:51:39AM -0500, Charalampos Stratakis wrote:
> Hello folks,
> 
> I recently observed a failure on the s390x fedora rawhide buildbot, on the 
> clang builds, when clang got updated to version 10:
> https://bugs.python.org/issue39689
> 
> The call:
> struct.unpack('>?', b'\xf0')
> means to unpack a "native bool", i.e. native size and alignment. Internally, 
> this does:
> 
> static PyObject *
> nu_bool(const char *p, const formatdef *f)
> {
> _Bool x;
> memcpy((char *), p, sizeof x);
> return PyBool_FromLong(x != 0);
> }
> 
> i.e., copies "sizeof x" (1 byte) of memory to a temporary buffer x, and then 
> treats that as _Bool.
> 
> While I don't have access to the C standard, I believe it says that 
> assignment of a true value to _Bool can coerce to a unique "true" value. It 
> seems that if a char doesn't have the exact bit pattern for true or false, 
> casting to _Bool is undefined behavior. Is that correct?
> 
> Clang 10 on s390x seems to take advantage of this: it probably only looks at 
> the last bit(s) so a _Bool with a bit pattern of 0xf0 turns out false.
> But the tests assume that 0xf0 should unpack to True.

I don't think it's specific to Clang 9, or the s390x arch. Have a look to

https://godbolt.org/z/3n-LqN

clang indeed just checks for the lowest bit. Is it correct? I think so. _Bool
can only holds two value, 0 and 1, [0] which is different from an int whose 
value is
true or false whether its different or equal to 0. GCC and Clang agree on that:

https://godbolt.org/z/koc4Pb

So yeah, according to that rule, the value set in `p` wasn't from a _Bool if it
has the 0xf0 value. So you're re-interepreting memory between two different 
types type-punning, and that's UB.

Quick and obvious fix:

 static PyObject *
 nu_bool(const char *p, const formatdef *f)
 {
 char x;
 memcpy((char *), p, sizeof x);
 return PyBool_FromLong(x != 0);
 }





[0]
the standard says

6.3.1.2  Boolean type

When any scalar value is converted to_Bool,the result is 0
if the value compares equalto 0; otherwise, the result is 1.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/S24XTMGGHJCN2FRZJWVHM5ZRMN3QORPK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Unpacking native bools in the struct module: Is Python relying on undefined behavior?

2020-02-27 Thread Petr Viktorin

On 2020-02-27 17:14, Serge Guelton wrote:

On Thu, Feb 27, 2020 at 10:51:39AM -0500, Charalampos Stratakis wrote:

Hello folks,

I recently observed a failure on the s390x fedora rawhide buildbot, on the 
clang builds, when clang got updated to version 10:
 https://bugs.python.org/issue39689

The call:
 struct.unpack('>?', b'\xf0')
means to unpack a "native bool", i.e. native size and alignment. Internally, 
this does:

 static PyObject *
 nu_bool(const char *p, const formatdef *f)
 {
 _Bool x;
 memcpy((char *), p, sizeof x);
 return PyBool_FromLong(x != 0);
 }

i.e., copies "sizeof x" (1 byte) of memory to a temporary buffer x, and then 
treats that as _Bool.

While I don't have access to the C standard, I believe it says that assignment of a true 
value to _Bool can coerce to a unique "true" value. It seems that if a char 
doesn't have the exact bit pattern for true or false, casting to _Bool is undefined 
behavior. Is that correct?

Clang 10 on s390x seems to take advantage of this: it probably only looks at 
the last bit(s) so a _Bool with a bit pattern of 0xf0 turns out false.
But the tests assume that 0xf0 should unpack to True.


I don't think it's specific to Clang 9, or the s390x arch. Have a look to

 https://godbolt.org/z/3n-LqN

clang indeed just checks for the lowest bit. Is it correct? I think so. _Bool
can only holds two value, 0 and 1, [0] which is different from an int whose 
value is
true or false whether its different or equal to 0. GCC and Clang agree on that:

 https://godbolt.org/z/koc4Pb

So yeah, according to that rule, the value set in `p` wasn't from a _Bool if it
has the 0xf0 value. So you're re-interepreting memory between two different 
types type-punning, and that's UB.

Quick and obvious fix:

  static PyObject *
  nu_bool(const char *p, const formatdef *f)
  {
  char x;
  memcpy((char *), p, sizeof x);
  return PyBool_FromLong(x != 0);
  }


(This assumes size of _Bool is the same as size of char, which I guess 
is also UB? But I guess we can add a build-time assertion for that, and 
say we don't support platforms where that's not the case.)



So thanks! I'm left with a question for CPython's struct experts, which 
is better kept to the bug tracker: 
https://bugs.python.org/issue39689#msg362815

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


[Python-Dev] Unpacking native bools in the struct module: Is Python relying on undefined behavior?

2020-02-27 Thread Charalampos Stratakis
Hello folks,

I recently observed a failure on the s390x fedora rawhide buildbot, on the 
clang builds, when clang got updated to version 10:
https://bugs.python.org/issue39689

The call:
struct.unpack('>?', b'\xf0')
means to unpack a "native bool", i.e. native size and alignment. Internally, 
this does:

static PyObject *
nu_bool(const char *p, const formatdef *f)
{
_Bool x;
memcpy((char *), p, sizeof x);
return PyBool_FromLong(x != 0);
}

i.e., copies "sizeof x" (1 byte) of memory to a temporary buffer x, and then 
treats that as _Bool.

While I don't have access to the C standard, I believe it says that assignment 
of a true value to _Bool can coerce to a unique "true" value. It seems that if 
a char doesn't have the exact bit pattern for true or false, casting to _Bool 
is undefined behavior. Is that correct?

Clang 10 on s390x seems to take advantage of this: it probably only looks at 
the last bit(s) so a _Bool with a bit pattern of 0xf0 turns out false.
But the tests assume that 0xf0 should unpack to True.

-- 
Regards,

Charalampos Stratakis
Software Engineer
Python Maintenance Team, Red Hat
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/O742VLCYX2AE3RWQK5RBQ3BGUOHESLF5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Claudio Jolowicz
Let me split my case into two points:

1) The intuition that the right-hand side of `a | b` is a fallback value
2) The claim that `a |= b` is a common idiom to assign defaults

About 2)

It appears that the idiom in 2) is less common than I assumed. My
expectations
were shaped by working with a C++ codebase where the `|=` operator was
sometimes
overloaded in such a way (since there is no `||=` operator in this
language).
Unfortunately, I have not found similar uses of `|=` elsewhere (e.g. in
Boost).

To illustrate this with a specific case nonetheless, that C++ codebase had a
generic data type modelled after Haskell's Maybe. In Haskell, `Maybe a` is a
type which can be empty (`Nothing`) or hold a value (`Just a`). In the C++
implementation, the operation `a |= b` would assign `just(b)` iff `a` was
not
empty.

About 1)

I still believe that there is an intuition that the right operand of `|` is
a
fallback value, and this intuition may lead people to wrong use of dict
unions.

To make this intuition more explicit: Consider other operations that behave
like
OR in a Boolean algebra, such as logical OR, and set union. Conceptually,
these
operations perform one or multiple checks on the left operand, and only
consider
the right operand if the check "failed".

- With logical OR, short-circuit semantics are widespread (cf. C, UNIX
shell, or
  Python itself). The right operand is only evaluated if the left operand
  evaluates to false in a Boolean context.

- With set union, implementations typically start by copying the left
operand,
  and add entries from the right operand if they are not already present in
the
  copy. This is also what CPython does in `set_union` (via `set_add_entry`).


As another case in point, overriding items from the right operand is already
provided by `dict.update`. A `|=` operator which provides for the
complementary
operation of filling in missing items would have made for a more orthogonal
set
of operations. When formulated in terms of `|`, the two operations only
differ
in the order of operands.

> Here's our current proposal for docs. Is there anything you'd like to add?
> https://github.com/python/cpython/pull/18659/files

I find this quite clear. It already points out the behaviour in question.


To conclude, different semantics for dict union would have been preferable
in my
view, but I guess that ship has sailed. Other than changing dict union
semantics
I don't think there is anything actionable left here. Maybe my input still
has
some value in clarifying expectations some users may have for this new
feature.

Thank you for your openness about this late input to the discussion.

On Thu, 27 Feb 2020 at 10:35, Kyle Stanley  wrote:

> > So I've also never come across "|=" being used for this purpose.
>
> IIRC, the JavaScript implementation of "|=" can potentially be used in the
> way Claudio described it, instead it's based on the truthiness of the
> left-hand operand rather than it being "unset". But it works in that
> context because "null" and "undefined" are considered falsey [1]. For
> example:
>
> > var value = null;
> > var other = 2;
> > value |= other;
> > console.log(value);
> 2
>
> So it effectively works like "value | other", but also sets "value" to
> "other" iff "value" is falsey. When the left-hand operand is truthy, it
> effectively does nothing.
>
> > var value = 3;
> > var other = 2;
> > value |= other;
> > console.log(value);
> 3
>
> Also worth noting, since "value |= other" translates to "value = value |
> other", it works as a bitwise OR operator; not as a catch-all for assigning
> a default value:
>
> > var value = null;
> > var other = "test";
> > value |= other;
> > console.log(value);
> 0
>
> Instead, you'd have to use the standard OR operator, like this "value =
> value || other" (since "||=" is invalid syntax):
>
> > var value = null;
> > var other = "test";
> > value = value || other;
> > console.log(value);
> test
>
> FWIW, I have very rarely seen "|=" used as an operator in JS, but I've
> seen "value = value || other" used a decent amount.
>
> ---
>
> [1] - https://developer.mozilla.org/en-US/docs/Glossary/Falsy
>
>
>
> On Wed, Feb 26, 2020 at 6:26 PM Nick Coghlan  wrote:
>
>>
>>
>> On Thu., 27 Feb. 2020, 2:03 am Guido van Rossum, 
>> wrote:
>>
>>> On Wed, Feb 26, 2020 at 7:43 AM Claudio Jolowicz 
>>> wrote:
>>>
 In my experience, the expression `value |= other` is a common idiom
 across
 programming languages to provide a default for `value` if it is
 "unset".

>>>
>>> Interesting. Can you point to specific examples of this? In what other
>>> languages have you seen this? (Not that it would make us change PEP 584,
>>> but if this appears common we could probably warn about it prominently in
>>> docs and tutorials.)
>>>
>>
>> I was thinking that bash scripting might be an example, but I double
>> checked, and that's spelled 'VAR="${$VAR:-default value}" '
>>
>> make has 'VAR ?= "default value"'
>>
>> C# uses "??=" for null 

[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Chris Angelico
On Thu, Feb 27, 2020 at 8:15 PM Serhiy Storchaka  wrote:
>
> 27.02.20 10:46, Chris Angelico пише:
> > On Thu, Feb 27, 2020 at 7:41 PM Serhiy Storchaka  
> > wrote:
> >> sympy/utilities/runtests.py
> >>
> >> Sorry, but the current code
> >>
> >> globs = globs.copy()
> >> if extraglobs is not None:
> >>   globs.update(extraglobs)
> >>
> >> looks much clearer to me than the proposed
> >>
> >> globs = globs | (extraglobs if extraglobs is not None else {})
> >
> > Is there a reason for not writing it as:
> >
> > globs = globs | (extraglobs or {})
> >
> > ? That reads fairly well to me.
>
> Sure. Although it would work different if extraglobs is a false value
> different from None, empty mapping and iterable.

Yes, technically it's different. But other than this silently ignoring
errors like passing 0 rather than None, it's unlikely to have any
material difference.

> But if we ignore such
> subtle details, it could be written also as
>
> globs = {**globs, **(extraglobs or {})}

Yeah, but now I think the pipe syntax has a definite advantage.

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


[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Kyle Stanley
> So I've also never come across "|=" being used for this purpose.

IIRC, the JavaScript implementation of "|=" can potentially be used in the
way Claudio described it, instead it's based on the truthiness of the
left-hand operand rather than it being "unset". But it works in that
context because "null" and "undefined" are considered falsey [1]. For
example:

> var value = null;
> var other = 2;
> value |= other;
> console.log(value);
2

So it effectively works like "value | other", but also sets "value" to
"other" iff "value" is falsey. When the left-hand operand is truthy, it
effectively does nothing.

> var value = 3;
> var other = 2;
> value |= other;
> console.log(value);
3

Also worth noting, since "value |= other" translates to "value = value |
other", it works as a bitwise OR operator; not as a catch-all for assigning
a default value:

> var value = null;
> var other = "test";
> value |= other;
> console.log(value);
0

Instead, you'd have to use the standard OR operator, like this "value =
value || other" (since "||=" is invalid syntax):

> var value = null;
> var other = "test";
> value = value || other;
> console.log(value);
test

FWIW, I have very rarely seen "|=" used as an operator in JS, but I've seen
"value = value || other" used a decent amount.

---

[1] - https://developer.mozilla.org/en-US/docs/Glossary/Falsy



On Wed, Feb 26, 2020 at 6:26 PM Nick Coghlan  wrote:

>
>
> On Thu., 27 Feb. 2020, 2:03 am Guido van Rossum,  wrote:
>
>> On Wed, Feb 26, 2020 at 7:43 AM Claudio Jolowicz 
>> wrote:
>>
>>> In my experience, the expression `value |= other` is a common idiom
>>> across
>>> programming languages to provide a default for `value` if it is "unset".
>>>
>>
>> Interesting. Can you point to specific examples of this? In what other
>> languages have you seen this? (Not that it would make us change PEP 584,
>> but if this appears common we could probably warn about it prominently in
>> docs and tutorials.)
>>
>
> I was thinking that bash scripting might be an example, but I double
> checked, and that's spelled 'VAR="${$VAR:-default value}" '
>
> make has 'VAR ?= "default value"'
>
> C# uses "??=" for null coalescence on assignment.
>
> So I've also never come across "|=" being used for this purpose.
>
> Cheers,
> Nick.
>
>> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/HMKYUZP5T6HTURG46GU3L72KANB65MLQ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/FOL22B6MXU65P2T3M6CCMYVZSSSWR2PO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Serhiy Storchaka

27.02.20 10:46, Chris Angelico пише:

On Thu, Feb 27, 2020 at 7:41 PM Serhiy Storchaka  wrote:

sympy/utilities/runtests.py

Sorry, but the current code

globs = globs.copy()
if extraglobs is not None:
  globs.update(extraglobs)

looks much clearer to me than the proposed

globs = globs | (extraglobs if extraglobs is not None else {})


Is there a reason for not writing it as:

globs = globs | (extraglobs or {})

? That reads fairly well to me.


Sure. Although it would work different if extraglobs is a false value 
different from None, empty mapping and iterable. But if we ignore such 
subtle details, it could be written also as


globs = {**globs, **(extraglobs or {})}
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/UYJ5VMSQPSS5WINGUWTTGI24IXJ6ABRC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Chris Angelico
On Thu, Feb 27, 2020 at 7:41 PM Serhiy Storchaka  wrote:
> sympy/utilities/runtests.py
>
> Sorry, but the current code
>
> globs = globs.copy()
> if extraglobs is not None:
>  globs.update(extraglobs)
>
> looks much clearer to me than the proposed
>
> globs = globs | (extraglobs if extraglobs is not None else {})

Is there a reason for not writing it as:

globs = globs | (extraglobs or {})

? That reads fairly well to me.

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


[Python-Dev] Re: Accepting PEP 584: Add Union Operators To dict

2020-02-27 Thread Serhiy Storchaka

18.02.20 19:35, Brandt Bucher пише:

...it was decided that `d1 | d2` also should ignore the types of the operands and always 
return a dict. And it accepts only dicts, not general mappings, in difference to `{**d1, 
**d2}`. So the only disadvantage of `{**d1, **d2}` is that it is not well known and 
"looks ugly".


Not quite. While this point *has* been weakened a bit with the recent semantic 
change, you don't mention that `dict` subclasses can (and likely would) 
override the `__or__` trio with wrapped `super()` calls. So while `{**d1, 
**d2}` will *never* be anything but a `dict`, I can trust that well-written 
`dict` subclasses my code encounters will still be able to preserve themselves 
with `d1 | d2`, if desired.


Yes, but this is a different thing. You *must* to implement new `__or__` 
in a subclass to make the behavior of `d1 | d2` be different from 
`{**d1, **d2}`. Actually, there was already an example -- Counter.


It is not an argument for implementing `__or__` in dict. It is an 
argument for implementing `__or__` in other classes. So to add a value 
to it you have to look at from from the opposite side: you want an 
operation for merging OrderedDict, defaultdict, etc and add 
`dict.__or__` just for symmetry, even if it is not actually necessary 
for dicts.



The pure-Python implementation of the non-inplace operator can be simpler if 
use dict unpacking.


The purpose of the pure-Python implementation in the PEP is to be a clear, 
understandable example that serves as a codification of the semantics, not to 
be the shortest one-liner. The suggested changes make the code less readable, 
making it harder to see exactly what will happen if I do `self | other`. I'm 
against changing it, for that reason.


Agree, the current code makes easier to implement such operations in 
other mapping classes.



Regarding the commonality of this operation, we've provided eighteen detailed 
examples of third-party library code that are candidates for these new 
operators. To the best of my knowledge, a large survey like this is 
unprecedented in a PEP. Whether or not it is more common than a different 
operation on other types isn't relevant here. We have gone above and beyond in 
demonstrating the use cases in detail.


Let's take a closer look at these examples. Unfortunately the PEP does 
not provide links to the original code, so the context is not always known.


IPython/zmq/ipkernel.py
IPython/zmq/kernelapp.py
matplotlib/delaunay/triangulate.py
numpy/ma/core.py
praw/internal.py
pygments/lexer.py
sphinx/highlighting.py
sphinx/quickstart.py
sympy/abc.py
sympy/parsing/maxima.py
sympy/printing/ccode.py and sympy/printing/fcode.py

In almost all examples it is guaranteed that the result is a dict. You 
create a dict by calling dict() or using dict display and then update 
it. So the form `{**d1, **d2}` can be used in all these cases.


In some examples, like in praw/internal.py, it may be especially good:

data = {'name': six.text_type(user), 'type': relationship, **kwargs}

In some cases, like in sympy/abc.py the proposed transformation is just 
not correct if arguments have overridden `__or__`. Currently it is 
guaranteed that the result is a dict, but with proposed code it is no 
longer true.


matplotlib/legend.py
sphinx/domains/__init__.py
sphinx/ext/doctest.py
sphinx/ext/inheritance_diagram.py

In these cases you merge a user provided dict with some default value 
which is a dict by default, but may be overridden in subclasses. 
Although it is unlikely.


matplotlib/backends/backend_svg.py

The current code uses `{**attrib, **extra}`. 
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_svg.py#L155


requests/sessions.py

The proposed transformation makes the code less efficient -- it makes 
redundant copying.


sympy/utilities/runtests.py

Sorry, but the current code

globs = globs.copy()
if extraglobs is not None:
globs.update(extraglobs)

looks much clearer to me than the proposed

globs = globs | (extraglobs if extraglobs is not None else {})
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/V6HCC6F2EQZTZ5JKPPMWFJNYO6HNGTJY/
Code of Conduct: http://python.org/psf/codeofconduct/