[Python-Dev] PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Nick Coghlan
I’ve made a final round of updates to PEP 642 and submitted it to the
Steering Council for consideration alongside PEP 634.

As usual, the rendered version can be found here:
https://www.python.org/dev/peps/pep-0642/

There's a Discourse thread at
https://discuss.python.org/t/pep-642-v3-explicit-pattern-syntax-for-structural-pattern-matching/6459,
and the rest of the email covers the same points as the opening post
in that thread.

There are some pretty significant changes relative to v2, although I
did already discuss most of them in the v2 thread at
https://discuss.python.org/t/pep-642-constraint-pattern-syntax-for-structural-pattern-matching/5614

The PEP itself contains a list of major changes relative to PEP 634,
so I won’t repeat that here:
https://www.python.org/dev/peps/pep-0642/#appendix-c-summary-of-changes-relative-to-pep-634

Instead I’ll summarise the parts that I consider most important:

* ensuring that all “binding to the right” operations use the as
keyword. This drove changes to both mapping patterns and class
patterns.
* explicitly qualifying both name bindings and value constraints with
`as`, `==`, or `is`. This change makes it possible to make pattern
matching available to users without having to resolve the thorny
questions of what bare names and attribute references should do by
default. It also opens up the possibility of potentially adding more
value constraint options later (like `in` , `is not`, and `!=`) if
those operations seem sufficiently compelling to be worth adding.
* explicitly decoupling sequence pattern matching from iterable
unpacking. The change to require qualification of name binding
operations already breaks the alignment between the two, and that
created an opportunity to simplify the grammar by only allowing square
bracket based sequence patterns and eliminating both open sequence
patterns and parenthesis based sequence patterns
* changing class patterns to draw more of their syntactic inspiration
from mapping patterns rather than from class instantiation
* explicitly representing patterns in the AST, rather than treating
patterns as pseudo-expressions all the way through to the code
generation layer. Skipping this step makes the code fragile and hard
to follow, as there isn’t actually any point in the AST that accepts
both expressions and patterns, but with pattern parsing reusing
expression nodes, you can’t tell from just looking at the AST which
nodes expect subexpressions and which expect subpatterns.

I’ll also quote the example match statement from the PEP abstract,
which extracts “host” and “port” details from a 2 item sequence, a
mapping with “host” and “port” keys, any object with “host” and “port”
attributes, or a “host:port” string, treating the “port” as optional
in the latter three cases:

port = DEFAULT_PORT
match expr:
case [as host, as port]:
pass
case {"host" as host, "port" as port}:
pass
case {"host" as host}:
pass
case object{.host as host, .port as port}:
pass
case object{.host as host}:
pass
case str{} as addr:
host, __, optional_port = addr.partition(":")
if optional_port:
port = optional_port
case __ as m:
raise TypeError(f"Unknown address format: {m!r:.200}")
port = int(port)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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/GQHKW5KHXWZ3Y2E2KOJ72GT3IRGGEEUE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Barry Scott


> On 3 Jan 2021, at 15:21, Nick Coghlan  wrote:
> 
> I’ve made a final round of updates to PEP 642 and submitted it to the
> Steering Council for consideration alongside PEP 634.
> 
> As usual, the rendered version can be found here:
> https://www.python.org/dev/peps/pep-0642/
> 
> There's a Discourse thread at
> https://discuss.python.org/t/pep-642-v3-explicit-pattern-syntax-for-structural-pattern-matching/6459,
> and the rest of the email covers the same points as the opening post
> in that thread.
> 
> There are some pretty significant changes relative to v2, although I
> did already discuss most of them in the v2 thread at
> https://discuss.python.org/t/pep-642-constraint-pattern-syntax-for-structural-pattern-matching/5614
> 
> The PEP itself contains a list of major changes relative to PEP 634,
> so I won’t repeat that here:
> https://www.python.org/dev/peps/pep-0642/#appendix-c-summary-of-changes-relative-to-pep-634
> 
> Instead I’ll summarise the parts that I consider most important:
> 
> * ensuring that all “binding to the right” operations use the as
> keyword. This drove changes to both mapping patterns and class
> patterns.
> * explicitly qualifying both name bindings and value constraints with
> `as`, `==`, or `is`. This change makes it possible to make pattern
> matching available to users without having to resolve the thorny
> questions of what bare names and attribute references should do by
> default. It also opens up the possibility of potentially adding more
> value constraint options later (like `in` , `is not`, and `!=`) if
> those operations seem sufficiently compelling to be worth adding.
> * explicitly decoupling sequence pattern matching from iterable
> unpacking. The change to require qualification of name binding
> operations already breaks the alignment between the two, and that
> created an opportunity to simplify the grammar by only allowing square
> bracket based sequence patterns and eliminating both open sequence
> patterns and parenthesis based sequence patterns
> * changing class patterns to draw more of their syntactic inspiration
> from mapping patterns rather than from class instantiation
> * explicitly representing patterns in the AST, rather than treating
> patterns as pseudo-expressions all the way through to the code
> generation layer. Skipping this step makes the code fragile and hard
> to follow, as there isn’t actually any point in the AST that accepts
> both expressions and patterns, but with pattern parsing reusing
> expression nodes, you can’t tell from just looking at the AST which
> nodes expect subexpressions and which expect subpatterns.
> 
> I’ll also quote the example match statement from the PEP abstract,
> which extracts “host” and “port” details from a 2 item sequence, a
> mapping with “host” and “port” keys, any object with “host” and “port”
> attributes, or a “host:port” string, treating the “port” as optional
> in the latter three cases:
> 
>port = DEFAULT_PORT
>match expr:
>case [as host, as port]:
>pass
>case {"host" as host, "port" as port}:
>pass
>case {"host" as host}:
>pass
>case object{.host as host, .port as port}:
>pass
>case object{.host as host}:
>pass
>case str{} as addr:
>host, __, optional_port = addr.partition(":")
>if optional_port:
>port = optional_port
>case __ as m:
>raise TypeError(f"Unknown address format: {m!r:.200}")
>port = int(port)

I read the above and believe I know what it meant without needing to read the 
PEP in detail.
I like that a lot.

I quickly read 642 v3 and missed an explanation about why the syntax to match a 
string object is
str{} and not str. Are you saying that I MUST use {} so that when case is 
parsed its clear that its a class
with no constraints?

in the "Changes to class patterns" I read the BinaryOp example and
I thought from the above that it would also use {} and not ().
---
match expr:
case BinaryOp(== '+', as left, as right):
---
I was expecting to see:
---
match expr:
case BinaryOp{== '+', as left, as right}:
---


Barry


> 
> Cheers,
> Nick.
> 
> -- 
> Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
> ___
> 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/GQHKW5KHXWZ3Y2E2KOJ72GT3IRGGEEUE/
> 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@pyt

[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Antoine Pitrou
On Sun, 3 Jan 2021 16:19:01 +
Barry Scott  wrote:
> > 
> > I’ll also quote the example match statement from the PEP abstract,
> > which extracts “host” and “port” details from a 2 item sequence, a
> > mapping with “host” and “port” keys, any object with “host” and “port”
> > attributes, or a “host:port” string, treating the “port” as optional
> > in the latter three cases:
> > 
> >port = DEFAULT_PORT
> >match expr:
> >case [as host, as port]:
> >pass
> >case {"host" as host, "port" as port}:
> >pass
> >case {"host" as host}:
> >pass
> >case object{.host as host, .port as port}:
> >pass
> >case object{.host as host}:
> >pass
> >case str{} as addr:
> >host, __, optional_port = addr.partition(":")
> >if optional_port:
> >port = optional_port
> >case __ as m:
> >raise TypeError(f"Unknown address format: {m!r:.200}")
> >port = int(port)  
> 
> I read the above and believe I know what it meant without needing to read the 
> PEP in detail.
> I like that a lot.

+1.  Unlike the other PEP, there is no confusion with regular Python
syntax such as function calls.

Regards

Antoine.

___
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/23DGXSXJ32DMJMZIETSEWGYDX2RNIR3W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Paul Moore
On Sun, 3 Jan 2021 at 16:26, Barry Scott  wrote:
> I read the above and believe I know what it meant without needing to read the 
> PEP in detail.
> I like that a lot.

Personally, I read it and was horribly confused. I worked out most of
it, but I would *not* count it as intuitive or natural.

Specific examples:

case {"host" as host, "port" as port}:
pass
case {"host" as host}:
pass

I assume that's dictionary unpacking? It doesn't really look like
anything else in Python, though, and it took me a while to work out.

case object{.host as host, .port as port}:
pass

I can only guess at this. I assume "subclass of object with host and
port attributes/properties"? But why use {...} for object access? And
does that extend to Foo{...} meaning "subclass of Foo? There's no
reason to assume yes or no to that.

Overall, the whole thing feels like an attempt to invent some sort of
syntax in reaction to the PEP 634 form - not having a logic in its own
right, but simply with a driving principle of "don't be like PEP 534".
It abandons any idea of "make matching look like the thing that's
being matched" and replaces it with a completely new set of syntax,
which lacks the intuitive nature that I expect from Python (and yes, I
know that can be read as "I'm not familiar with it, so I don't like
it" - that may indeed be all that it is, but I feel that it's a bit
more fundamental than just that).

I have not read the full PEP, so take this as very much a "first
impression" reaction, but I'd avoid using this syntax, both in my own
projects and in any project I contribute to. Honestly, I feel like I'd
rather see pattern matching rejected altogether than see this version
accepted.

Paul
___
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/GFNGO5UZB67HKWN3WSKGMFYEPE3RAFMK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Ethan Furman

On 1/3/21 8:50 AM, Paul Moore wrote:


Personally, I read it and was horribly confused.



 case object{.host as host, .port as port}:
 pass


Leading periods is a big no-go for me, for all the reasons listed in the 
original thread.


I have not read the full PEP, so take this as very much a "first
impression" reaction, but I'd avoid using this syntax, both in my own
projects and in any project I contribute to. Honestly, I feel like I'd
rather see pattern matching rejected altogether than see this version
accepted.


Agreed.

--
~Ethan~
___
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/SO4K2WNUZDKIPYJOPVTBNXOWEBIOQWYP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Paul Sokolovsky
Hello,

On Sun, 3 Jan 2021 16:50:33 +
Paul Moore  wrote:

> On Sun, 3 Jan 2021 at 16:26, Barry Scott 
> wrote:
> > I read the above and believe I know what it meant without needing
> > to read the PEP in detail. I like that a lot.  
> 
> Personally, I read it and was horribly confused. I worked out most of
> it, but I would *not* count it as intuitive or natural.
> 
> Specific examples:
> 
> case {"host" as host, "port" as port}:
> pass
> case {"host" as host}:
> pass
> 
> I assume that's dictionary unpacking? It doesn't really look like
> anything else in Python, though, and it took me a while to work out.
> 
> case object{.host as host, .port as port}:
> pass
> 
> I can only guess at this. I assume "subclass of object with host and
> port attributes/properties"? But why use {...} for object access? And
> does that extend to Foo{...} meaning "subclass of Foo? There's no
> reason to assume yes or no to that.
> 
> Overall, the whole thing feels like an attempt to invent some sort of
> syntax in reaction to the PEP 634 form - not having a logic in its own
> right, but simply with a driving principle of "don't be like PEP 534".
> It abandons any idea of "make matching look like the thing that's
> being matched" and replaces it with a completely new set of syntax,
> which lacks the intuitive nature that I expect from Python 

+1 for that evaluation. And I'd like to remind with what the original
discussion started, with very simple and focused questions:

a) What if we *do* use sigils for value patterns?
or,
b) What if we *do* use sigils for capture patterns?

Instead of focusing on one of the above questions, making fine,
focused, pin-head sized adjustments to the original pattern matching
PEPs, with PEP642 we've got a noticeable scope creep, with evermore
extravagant syntax replacements of the large part of the original
proposal.

This once again shows that it's very easy to get carried away and how
important for others to help to remind where to stop.
 
[]

> I have not read the full PEP, so take this as very much a "first
> impression" reaction, but I'd avoid using this syntax, both in my own
> projects and in any project I contribute to. Honestly, I feel like I'd
> rather see pattern matching rejected altogether than see this version
> accepted.

Just the same, there's no need to go too far here either. The question
of PEP642 rejection should be treated as orthogonal to acceptance /
rejection of PEP634. Because, well, PEP634 misses to do some things
better, but indeed at least some of them can be added later. But PEP642
twists matters so much, that it likely will be irreparable afterwards.

> 
> Paul

-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/GBKFB54YFUY3Y6PC5BXYNMTD6NDEAZPG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Nick Coghlan
On Mon, 4 Jan 2021, 2:19 am Barry Scott,  wrote:

>
> I quickly read 642 v3 and missed an explanation about why the syntax to
> match a string object is
> str{} and not str. Are you saying that I MUST use {} so that when case is
> parsed its clear that its a class
> with no constraints?
>


Yes. "str{}" would give a pure subclass check, "str()" would also be
allowed for classes that define "__match_args__".



> in the "Changes to class patterns" I read the BinaryOp example and
> I thought from the above that it would also use {} and not ().
>
> ---
>
> match expr:
>
> case BinaryOp(== '+', as left, as right):
>
> ---
>
> I was expecting to see:
>
> ---
>
> match expr:
>
> case BinaryOp{== '+', as left, as right}:
>
> ---
>
>
The example in the abstract doesn't show a class defined pattern that
relies on __match_args__, only an instance attributes pattern.

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/D4ZSJUW4WFFWPWQWP23AAUSZ6AQXQT3M/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Nick Coghlan
On Mon, 4 Jan 2021, 2:50 am Paul Moore,  wrote:

> On Sun, 3 Jan 2021 at 16:26, Barry Scott  wrote:
> > I read the above and believe I know what it meant without needing to
> read the PEP in detail.
> > I like that a lot.
>
> Personally, I read it and was horribly confused. I worked out most of
> it, but I would *not* count it as intuitive or natural.
>
> Specific examples:
>
> case {"host" as host, "port" as port}:
> pass
> case {"host" as host}:
> pass
>
> I assume that's dictionary unpacking? It doesn't really look like
> anything else in Python, though, and it took me a while to work out.
>


These *can* have the colon included, and it would be quite viable to have
that as the only spelling in the initial design iteration:

case {"host": as host, "port": as port}:
pass
case {"host": as host}:
pass


The submitted grammar just allows the colon to be left out for brevity (as
even with it missing you were still able to correctly identify this as a
mapping match).


> case object{.host as host, .port as port}:
> pass
>
> I can only guess at this. I assume "subclass of object with host and
> port attributes/properties"?


Correct :)

But why use {...} for object access? And
> does that extend to Foo{...} meaning "subclass of Foo? There's no
> reason to assume yes or no to that.
>

The instance attribute syntax arose from trying to deal with two problems
from class patterns in PEP 634:

* "ATTR=TARGET" using "=" to bind to the right instead of to the left
* no subsequent path to ever offering a syntax for *retrieving* multiple
attributes in ordinary expressions outside pattern matching

The minimal fix for the first point would have been just "case
object(host=as host, port=as port}:", but that couldn't ever be used to
retrieve multiple attributes, as "object(host, port)" is already a function
call.

By contrast, "object{.host, .port}" is currently illegal syntax that could
plausibly become a syntactic shorthand for "(object.host, object.port)" in
both ordinary expressions and in assignment targets, even if it was
initially only supported in pattern matching.


> Overall, the whole thing feels like an attempt to invent some sort of
> syntax in reaction to the PEP 634 form - not having a logic in its own
> right, but simply with a driving principle of "don't be like PEP 534".
>

The design logic went as follows:

1. Start with PEP 634
2a. Ensure all "binding to the right" operations use 'as'
2b. Ensure all bare names outside subexpressions are qualified with a sigil
or keyword
3. Ensure all deconstruction operations offer a potential future path to
producing tuples in ordinary expressions using pattern matching inspired
syntax

It abandons any idea of "make matching look like the thing that's
> being matched"


PEP 634 doesn't offer that for class patterns either.

I like being able to leave out the colon for mapping name bindings, but
wouldn't object to requiring that it be left in.

and replaces it with a completely new set of syntax,
> which lacks the intuitive nature that I expect from Python (and yes, I
> know that can be read as "I'm not familiar with it, so I don't like
> it" - that may indeed be all that it is, but I feel that it's a bit
> more fundamental than just that).
>
> I have not read the full PEP, so take this as very much a "first
> impression" reaction,


I'd definitely like to hear your second impression after reviewing the PEP
text, but getting first impressions like yours was a big part of my
motivation for including the match statement example.

but I'd avoid using this syntax, both in my own
> projects and in any project I contribute to. Honestly, I feel like I'd
> rather see pattern matching rejected altogether than see this version
> accepted.
>


I've reached that point with PEP 634 - I think the problems with binding to
the right in mapping and especially class patterns are serious enough that
I'd prefer to see no pattern matching to *that* syntax for pattern matching.

I also have concerns about AST ambiguity in the current PEP 634
implementation, but those could be fixed by defining separate AST nodes for
patterns without having to change the surface syntax proposal (the AST I've
defined for 642 should be usable for 634 as well).

Cheers,
Nick.


> Paul
>
___
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/VV3XFMBY4ZKGAOA4QJY3PGKQK4GUQRKS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642 v3: Explicit patterns for structured pattern matching

2021-01-03 Thread Nick Coghlan
On Mon, 4 Jan 2021, 4:34 am Ethan Furman,  wrote:

> On 1/3/21 8:50 AM, Paul Moore wrote:
>
> > Personally, I read it and was horribly confused.
>
> >>  case object{.host as host, .port as port}:
> >>  pass
>
> Leading periods is a big no-go for me, for all the reasons listed in the
> original thread.
>

It gave me pause as well, but the differences I see relative to the
proposed usage in the early iterations of PEP 622 are:

1. This dot isn't semantically significant to the parser, it's just a "this
is an attribute name" hint for the human reader. If you forget it, you get
a syntax error rather than the code meaning something else.
2. It only appears inside instance attribute mappings, not as part of
arbitrary patterns, so the leading dot isn't the only "this is an attribute
reference" hint.
3. It means the same thing as dots do in the rest of Python (indicating
that the following identifier is an attribute name).

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/KPDHJIU3MNU6ID6SVKGDGYW7AY435QYY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Descriptors in dataclasses fields

2021-01-03 Thread Josue Balandrano Coronel
I've been exploring dataclasses for a few months now and they've proven to be 
very useful.

The only downside is that there's not a simple way to use descriptors.

Descriptors only work on class attributes (as per the docs: 
https://docs.python.org/3/howto/descriptor.html#closing-thoughts). This means 
that to use a descriptor in a data class we have to use typing.ClassVar like 
this

@dataclass
class Item:
name: str
price: typing.ClassVar[Decimal] = PriceValidator()

Which is totally fine because of how descriptors work the previous syntax is a 
feature in dataclasses, IMHO.

But, there's not a straight forward way to pass a value to the descriptor on 
init. Because ClassVars are not used by @dataclass to do its thing (as per the 
docs: https://docs.python.org/3/library/dataclasses.html#class-variables)

This means that in the example above `price` is not going to be a parameter of 
the class Item's __init__ method. So the only way to do this is to either 
create an InitVar field or a regular field and then pass the value to the 
descriptor in __post_init__

@dataclass
class Item:
name: str
price_val: InitVar[Decimal]
price: typing.ClassVar[Decimal] = PriceValidator()

def __post_init__(self, price_val: Decimal) -> None:
self.price = price_val

When using a regular field we can double the field's purpose by making it the 
field the descriptor is going to use:

@dataclass
class Item:
name: str
_price: Decimal
price: typing.ClassVar[Decimal] = PriceValidator()

def __post_init__(self) -> None:
self.price = self._price

And then in the descriptor implement __set_name__ like so:

def __set_name(self, owner, name):
self.name = f"_{name}"


Personally, I don't like either option because it adds noice to the data class 
definition. Using an InitVar is the better option because that variable is 
clearly defined as init only and it's not present in an instance. Using a 
regular field adds unnecessary noice to the data class.

Also, I think it clashes with the intent of descriptors since they're supposed 
to manage their data in any way they want.

My questions are:

- Are my assumptions correct?
- Is this the intended behavior? Or what's the preferred way of using a 
descriptor in a dataclass field?
- If this is not intended, could it be possible to add a `descriptor` parameter 
to the `field` method and treat the field accordingly?

I couldn't find any information on the docs or the PEP. I could"ve missed 
something, sorry if this is the case :)

Thanks!

--
Josue
https://www.rmcomplexity.com
___
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/UOMBDIVNRG3DS6UHWSOF4JTLIPXEENCT/
Code of Conduct: http://python.org/psf/codeofconduct/