[Python-Dev] Re: About the new CFrame structure

2021-12-20 Thread Brandt Bucher
Just to clear up a quick point I made:

> - PyFrameObject.f_back just gives you a dummy wrapper around the previous 
> frame object.
>   - It's not really useful for unwinding anything.

That should read "previous InterpreterFrame", rather than "previous frame 
object".

Also, everything I wrote above is in the context of 3.11. InterpreterFrames 
don't exist in 3.10 and below, so in those versions PyFrameObject.f_back is 
indeed what you probably want.
___
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/TKPWWP33QJJEVEIP63C4SIEMVBY44LCW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: About the new CFrame structure

2021-12-20 Thread Brandt Bucher
Hi Gabriele!

> I hope you would indulge me in asking for some details about the new CFrame 
> structure, even in the form of existing literature (e.g. PEP) where the idea 
> behind it is explained.

There isn't too much documentation on this, unfortunately (since these are all 
very unstable, low-level interpreter details), but a good place to start would 
be https://bugs.python.org/issue46090.

Based on my own understanding (from reading the source code):
- There are three relevant structures: CFrame, InterpreterFrame, and 
PyFrameObject.
  - PyFrameObjects are just PyObject wrappers around an InterpreterFrame, where 
all of the *actual* frame state for the Python stack is maintained.
   - They are created lazily (for example, when sys._getframe() is called).
 - See https://github.com/python/cpython/pull/27077.
  - InterpreterFrames live in a "datastack" for fast allocation and 
deallocation.
- This "datastack" lives on the PyThreadState.
- Because of how it is designed, InterpreterFrames must be 
allocated/deallocated "in order".
- If an InterpreterFrame is cleared, but still has a live PyFrameObject 
that points to it, it will copy itself *into* the PyFrameObject first (to 
guarantee that the PyFrameObject keeps working).
- See https://github.com/python/cpython/pull/26076.
  - A single CFrame is statically allocated inside of each 
_PyEval_EvalFrameDefault call, so it corresponds to the C stack, not the Python 
stack.
- It links to a chain of one or more InterpreterFrames.
- Multiple InterpreterFrames can correspond to a single CFrame!
  -  This is a performance optimization in 3.11: rather than enter a new 
call to _PyEval_EvalFrameDefault, calls to pure-Python code just create a new 
InterpreterFrame, set it as the current one, and continue execution.
  - You can see how many InterpreterFrames correspond to the current CFrame 
by reading the "depth" member of the current InterpreterFrame.
- A value of 0 indicates that this is the only InterpreterFrame for 
this CFrame.
- A value of 42 means that this optimization has been performed 42 
times (and there are currently 43 InterpreterFrames executing in this CFrame).

> Also, I'd like to a quick question, if I may. There now appear to be two ways 
> of unwinding the frame stack: either iterate over CFrame.previous, or the 
> more traditional PyFrameObject.f_back. I suspect there are reasons why these 
> are perhaps not actually equivalent, and indeed this is mainly what I'd like 
> to read in the literature I've requested above.

The above outline probably makes the differences clear:
- PyFrameObject.f_back just gives you a dummy wrapper around the previous frame 
object.
  - It's not really useful for unwinding anything.
- InterpreterFrame.previous gives you the previous interpreter frame (duh!).
  - This is probably what you want.
- CFrame.previous gives you the previous call to _PyEval_EvalFrameDefault.
  - It's not really useful for unwinding anything.
  - This is only really useful to maintain the current tracing state when 
returning. 

Hopefully this helps! Somebody (Pablo or Mark?) will probably jump in here if I 
got anything wrong.

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


[Python-Dev] Re: Why doesn't peephole optimise away operations with fast locals?

2021-10-10 Thread Brandt Bucher
Guido van Rossum wrote:
> What's exasperating to me about this whole discussion is that nobody has
> shown any reason why this kind of code would be occurring in user code.
> STORE_FAST x LOAD_FAST x seems that it must come from a user writing
> x = x

I think that would be LOAD_FAST(x) STORE_FAST(x). STORE_FAST(x) LOAD_FAST(x) 
could be caused by something like this:
 
def f():
x = …
y = x

Presumably this could be replaced with DUP_TOP() STORE_FAST(x)? But I don’t 
know if that’s any faster. It does require more stack space…

> Are we just a solution (a clever peephole
> trick) looking for a problem?

It seems so.

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


[Python-Dev] Re: Why doesn't peephole optimise away operations with fast locals?

2021-10-10 Thread Brandt Bucher
I can think of two reasons.

The first reason is that this operation *does* have a side-effect: if a fast 
local is unbound, the load will raise a NameError!

def f():
 x  # This should always raise.
 x = None  # This makes x a fast local.

The second reason is one that Guido already alluded to: the peephole optimizer 
shouldn’t be tasked with “fixing” poorly-written or uncommon code… just 
improving common code.

If anything, we would probably just warn here. But even that seems like too 
much.

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


[Python-Dev] Re: PEP 654 except* formatting

2021-10-06 Thread Brandt Bucher
Łukasz Langa wrote:
> Joking aside, since we allow any expression after 'except' 'group' then this 
> is indeed ambiguous. In theory!

The ambiguity with function calls, though, is probably a dealbreaker:

except group (E1, E2) as e: …
except group(E1, E2) as e: …

See my other message for an alternative (putting “group” after the expression).

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


[Python-Dev] Re: PEP 654 except* formatting

2021-10-06 Thread Brandt Bucher
Łukasz Langa wrote:
> Joking aside, since we allow any expression after 'except' 'group' then this 
> is indeed ambiguous. In theory!

Another option (to remove the ambiguity) could be to move the “group” after the 
expression. Bonus points for reading more clearly:

except MemoryError group as e: …
except (KeyError, IndexError) group as e: …
except some + expression group as e: …

And edge-cases like this still work normally:

except some + group as e: …
___
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/TW5I4Z3XKCSZC6IRXHNFVPZVLHEKI7O3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 654 except* formatting

2021-10-03 Thread Brandt Bucher
Łukasz Langa wrote:
> My idea is this:
> try:
> ...
> except group E as e:
> ...
> except group E1, T2 as e:
> ...
> Should be doable given the magical match-case contextual keywords precedent. 
> This looks nice and is explicit, since you will always get an ExceptionGroup 
> instance under `e`.

Heh, we crossed posts with the soft keywords. I like your idea (“except group”) 
better than mine (“except each”).
___
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/4FPTSD6VAIJD2WSP63KQUOQLDAOI3EWR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 654 except* formatting

2021-10-03 Thread Brandt Bucher
Irit Katriel wrote:
> It is also not too late to opt for a completely different syntax if a better 
> one is suggested.

Honestly, I’ve never been a fan of the PEP’s proposed star syntax.

If we’re okay adding a soft keyword, though, something like “except each” could 
help communicate the meaning of the blocks a bit more explicitly. I’m pretty 
sure that grammar would be unambiguous in all cases.
___
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/44TWMI3PV3TKRL6ZJ4YU3GMQ6W43EHU5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Should the definition of an "(async) iterator" include __iter__?

2021-09-14 Thread Brandt Bucher
Guido van Rossum wrote:
> TBH I don't think there is an *actual* problem here. I think it's just
> about choosing the right wording for the glossary (which IMO does not have
> status as a source of truth anyway).

Good point. I'm probably approaching this from the wrong angle (by trying to 
"fix" the language, rather than the docs).
___
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/ZUESGSZ2BIBZZI42ZUMCQVWUX3STIO6V/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Should the definition of an "(async) iterator" include __iter__?

2021-09-14 Thread Brandt Bucher
Guido van Rossum wrote:
> On Tue, Sep 14, 2021 at 3:49 PM Brandt Bucher brandtbuc...@gmail.com
> wrote:
> > I think it's also worth noting that a missing "`__iter__` that returns
> > self" is trivial to recover from... just use a new reference to the
> > iterator instead. The overhead of a method call for this convention almost
> > seems silly.
> The use case is this:

Yeah, I understand that. But what I'm hinting that is that the `GET_ITER` 
opcode and `iter` builtin *could* gracefully handle this situation when called 
on something that doesn't define `__iter__` but does define `__next__`. 
Pseudocode:

def iter(o):
if hasattr(o, "__iter__"):
return o.__iter__()
elif hasattr(o, "__next__"):
# Oh well, o.__iter__() would have just returned o anyways...
return o
raise TypeError

This would be implemented at the lowest possible level, in `PyObject_GetIter`.

> > What worries me most about changing the current "requirement" is that it
> > may create either confusion or backward compatibility issues for
> > `collections.abc.Iterator` (which is a subtype of `Iterable`, and thus
> > requires `__iter__`).
> If you explicitly inherit from Iterator, you inherit a default
> implementation of __iter__ (that returns self, of course). If you merely
> register, it's up to you to comply. And sometimes people register things
> that don't follow the letter of the protocol, just to get things going.
> (This is common for complex protocols like Mapping, where some function you
> have no control over insists on a Mapping but only calls one or two common
> methods.

Yeah, I was thinking about cases like `isinstance(o, Iterator)`, where `o` 
defines `__iter__` but not `__next__`. Even though this code might start 
returning the "right" answer, it's still a backward-compatibility break. Not 
sure what the true severity would be, though...
___
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/SDZDMAF4MJDZHKIIWO2UUNRG6ZV2EU55/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Should the definition of an "(async) iterator" include __iter__?

2021-09-14 Thread Brandt Bucher
I think it's also worth noting that a missing "`__iter__` that returns self" is 
trivial to recover from... just use a new reference to the iterator instead. 
The overhead of a method call for this convention almost seems silly.

What worries me most about changing the current "requirement" is that it may 
create either confusion or backward compatibility issues for 
`collections.abc.Iterator` (which is a subtype of `Iterable`, and thus requires 
`__iter__`).
___
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/RSV6MOIBVNEFKL4NDHTKDVSGVABVY65Q/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 467 feedback from the Steering Council

2021-09-09 Thread Brandt Bucher
Brandt Bucher wrote:
> You can even get creative and use the dedicated “pistol” operator…

Ah, wait, ignore this example. I got the chr and ord behavior flipped in my 
head.

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


[Python-Dev] Re: PEP 467 feedback from the Steering Council

2021-09-09 Thread Brandt Bucher
Steven D'Aprano wrote:
> TIL :-)
> How have I never noticed to_bytes until now? o_O

I’m going to go out on a limb here: because it’s rarely ever needed?

I mean, the proposed bchr() functionality is crazy simple to implement yourself 
if you actually *do* need it. You can even get creative and use the dedicated 
“pistol” operator:

>>> b = b"*"
>>> i ,= b
>>> i
42

;)

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


[Python-Dev] Re: PEP 467 feedback from the Steering Council

2021-09-08 Thread Brandt Bucher
Steven D'Aprano wrote:
> To me, it sounds like should be the opposite of int.from_bytes.
> >>> int.from_bytes(b'Hello world', 'little')
> 121404708502361365413651784
> >>> bytes.from_int(121404708502361365413651784, 'little')
> # should return b'Hello world'
> If that's not the API being suggested, that's going to be confusing.

I'm a bit lost here... why are we convinced at all that we need a new way to do 
this? Hasn't this functionality already existed for years?

>>> x = int.from_bytes(b"*", "little")
>>> x
42
>>> x.to_bytes(1, "little")
b'*'

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


[Python-Dev] Re: Problems with dict subclassing performance

2021-08-18 Thread Brandt Bucher
Marco Sulla wrote:
> I remember the BDFL said in a post […]

Really trying not to get involved, but for anybody still reading: Marco is 
seriously misquoting somebody here. The actual quote is “too many cooks”.

https://mail.python.org/archives/list/python-dev@python.org/message/7QNWFKBLJPS5KY3UVFT426TDIHAF6WCX/
___
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/WLTXOABUP3X3HVTGBHYC7ZZHKOMTPWR5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Critique of PEP 657 -- Include Fine Grained Error Locations in Tracebacks

2021-05-17 Thread Brandt Bucher
Ethan Furman wrote:
> On 5/17/2021 6:13 AM, Mark Shannon wrote:
> > Where i1, i2 are integers and s1 is a string.
> > > i1 + i2 + s1
> > 
> Wouldn't the carets just be under the i2 + s1 portion?

I don't think so, since this is executed as `((i1 + i2) + s1)`.

Mark's carets look correct to me, since the second (outer) addition's LHS is 
the result of adding `i1` and `i2`:

```
Python 3.11.0a0 (heads/main:a42d98ed91, May 16 2021, 14:02:36) [GCC 7.5.0] on 
linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> op = ast.parse("i1 + i2 + s1", mode="eval").body
>>> op

>>> op.col_offset
0
>>> op.end_col_offset
12
```

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


[Python-Dev] Re: str() vs format(): trivia question

2021-04-20 Thread Brandt Bucher
It has always bugged me that for Enums mixed in with int or str (a common 
pattern in my code), `f"{MyEnum.X}"` is not the same as `str(MyEnum.X)`.

I'd be happy to see it changed!
___
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/FAQ7QYJMUBMNM4PZSMKFV3NHF26WKVT3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-04-06 Thread Brandt Bucher
Hi Mark.

Thanks for your reply, I really appreciate it.

Mark Shannon said:
> My intention, and I apologize for not making this clearer, was not to 
> denigrate your work, but to question the implications of the term "reference".
> 
> Calling something a "reference" implementation suggests that it is something 
> that people can refer to, that is near perfectly correct and fills in the 
> gaps in the specification.
> 
> That is a high standard, and one that is very difficult to attain. It is why 
> I use the term "implementation", and not "reference implementation" in my 
> PEPs.

Interesting. The reason I typically include a "Reference Implementation" 
section in my PEPs is because they almost always start out as a copy-paste of 
the template in PEP 12 (which also appears in PEP 1):

https://www.python.org/dev/peps/pep-0001/#what-belongs-in-a-successful-pep
https://www.python.org/dev/peps/pep-0012/#suggested-sections

Funny enough, PEP 635 has a "Reference Implementation" section, which itself 
refers to the implementation as simply a "feature-complete CPython 
implementation":

https://www.python.org/dev/peps/pep-0635/#reference-implementation

(PEP 634 and PEP 636 don't mention the existence of an implementation at all, 
as far as I can tell.)

It's not a huge deal, but we might consider updating those templates if the 
term "Reference Implementation" implies a higher standard than "we've put in 
the work to make this happen, and you can try it out here" (which is what I've 
usually used the section to communicate).

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


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-04-03 Thread Brandt Bucher
Mark Shannon said:
> I was relying on the "reference" implementation, which is also in the PEP.

Can you please stop putting scare quotes around "reference implementation"? 
You've done it twice now, and it's been a weekend-ruiner for me each time.

I've put months of work into writing and improving CPython's current pattern 
matching implementation, mostly on nights and weekends. I don't know whether 
it's intentional or not, but when you say things like that it instantly 
devalues all of my hard work in front of everyone on the list.

For such a huge feature, I'm honestly quite amazed that this is the only issue 
we've found since it was merged over a month ago (and both authors have agreed 
that it needs to be fixed in the PEP, not the implementation). The PR 
introducing this behavior was reviewed by at least a half-dozen people, 
including you.

The last time you said something like this, I just muted the thread. Let's 
please keep this respectful; we're all obviously committing a lot of our own 
time and energy to this, and we need to work well together for it to be 
successful in the long term.

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


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-04-02 Thread Brandt Bucher
Mark Shannon wrote:
> On 02/04/2021 7:19 am, Brandt Bucher wrote:
> > I agree that self-matching classes should absolutely allow keyword matches. 
> > I had no idea the PEP forbade it.
> PEP 634 allows it.

PEP 634 says:

> For a number of built-in types (specified below), a single positional 
> subpattern is accepted which will match the entire subject; for these types 
> no keyword patterns are accepted.

(https://www.python.org/dev/peps/pep-0634/#class-patterns)

> Most checks are cheap though.
> Checking for duplicates in `__match_args__` can be done at class creation 
> time, and checking for duplicates in the pattern can be done at compile time.

I assume the compile-time check only works for named keyword attributes. The 
current implementation already does this.

-1 on checking `__match_args__` anywhere other than the match block itself.

Guido van Rossum wrote:
> On Fri, Apr 2, 2021 at 3:38 AM Mark Shannon m...@hotpy.org wrote:
> > Are there are any use-cases? 
> > The test-case `int(real=0+0j, imag=0-0j)` is contrived, but I'm struggling 
> > to come up with less contrived examples for any of float, list, dict, 
> > tuple, str.
> There could be a subclass that adds an attribute. That's still contrived  
> though.

I could see the case for something like `case defaultdict({"Spam": s}, 
default_factory=f)`. I certainly don't think it should be forbidden.
___
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/L2RB6WYAOSLZECG4N2JTYMAAQX3U64GA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-04-02 Thread Brandt Bucher
Guido van Rossum wrote:
> Well, now I have egg on my face, because the current implementation does 
> reject multiple occurrences of the same identifier in __match_args__. We 
> generate an error like "TypeError: C() got multiple sub-patterns for 
> attribute 'a'". However, I cannot find this uniqueness requirement in PEP 
> 634, so I think it was a mistake to implement it.
> 
> Researching this led me to find another issue where PEP 634 and the 
> implementation differ, but this time it's the other way around: PEP 634 says 
> about types which accept a single positional subpattern (int(x), str(x) etc.) 
> "for these types no keyword patterns are accepted." Mark's example `case 
> int(real=0, imag=0):` makes me think this requirement is wrong and I would 
> like to amend PEP 634 to strike this requirement. Fortunately, this is not 
> what is implemented. E.g. `case int(1, real=1):` is accepted and works, as 
> does `case int(real=0):`.
> 
> Calling out Brandt to get his opinion. And thanks to Mark for finding these!

The current implementation will reject any attribute being looked up more than 
once, by position *or* keyword. It's actually a bit tricky to do, which is why 
the `MATCH_CLASS` op is such a beast... it needs to look up positional and 
keyword attributes all in one go, keeping track of everything it's seen and 
checking for duplicates.

I believe this behavior is a holdover from PEP 622:

> The interpreter will check that two match items are not targeting the same 
> attribute, for example `Point2d(1, 2, y=3)` is an error.

(https://www.python.org/dev/peps/pep-0622/#overlapping-sub-patterns)

PEP 634 explicitly disallows duplicate keywords, but as far as I can tell it 
says nothing about duplicate `__match_args__` or keywords that also appear in 
`__match_args__`. It looks like an accidental omission during the 622 -> 634 
rewrite.

(I guess I figured that if somebody matches `Spam(foo, y=bar)`, where 
`Spam.__match_args__` is `("y",)`, that's probably a bug in the user's code. 
Ditto for `Spam(y=foo, y=bar)` and `Spam(foo, bar)` where `Spam.__match_args__` 
is `("y", "y")` But it's not a hill I'm willing to die on.)

I agree that self-matching classes should absolutely allow keyword matches. I 
had no idea the PEP forbade it.
___
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/EKXKRZBJAUWVJVMF3MCNJA6I7HLLL26B/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Brandt Bucher
Guido van Rossum wrote:
> On Wed, Mar 31, 2021 at 2:14 PM Brandt Bucher brandtbuc...@gmail.com
> wrote:
> > (One change from my last email: it doesn't allow `__match_map__` /
> > `__match_seq__` to be set to `False`... only `True`. This prevents some
> > otherwise tricky multiple-inheritance edge-cases present in both of our
> > flagging systems that I discovered during testing. I don't think there are
> > actual use-cases for unsetting the flags in subclasses, but we can revisit
> > that later if needed.)
> That's surprising to me. Just like we can have a class that inherits from
> int but isn't hashable, and make that explicit by setting `__hash__ =
> None`, why couldn't I have a class that inherits from something else that
> happens to inherit from Sequence, and say "but I don't want it to match
> like a sequence" by adding `__match_sequence__ = False`? AFAIK all Mark's
> versions would support this by setting `__match_kind__ = 0`.

The issue isn't when *I* set `__match_seq__ = False` or `__match_container__ = 
0`. It's when *one of my parents* does it that things become difficult.

> Maybe you can show an example edge case where this would be undesirable?

Good idea. I've probably been staring at this stuff for too long to figure it 
out myself. :)

As far as I can tell, these surprising cases arise because a bit flag can only 
be either 0 or 1. For us, "not specified" is equivalent to 0, which can lead to 
ambiguity.

Consider this case:

```
class Seq:
__match_seq__ = True
# or __match_container__ = MATCH_SEQUENCE

class Parent:
pass

class Child(Parent, Seq):
pass
```

Okay, cool. `Child` will match as a sequence, which seems correct. But what 
about this similar case?

```
class Seq:
__match_seq__ = True
# or __match_container__ = MATCH_SEQUENCE

class Parent:
__match_seq__ = False
# or __match_container__ = 0

class Child(Parent, Seq):
pass
```

Here, `Child` will *not* match as a sequence, even though it probably should. 
The only workarounds I've found (like allowing `None` to mean "this is unset, 
don't inherit me if another parent sets this flag", ditching tp_flags entirely, 
or not inheriting these attributes) feel a bit extreme just to allow some users 
to do the moral equivalent of un-subclassing `collections.abc.Sequence`.

So, my current solution (seen on the branch linked in my earlier email) is:

- Set the flag if the corresponding magic attribute is set to True in the class 
definition
- Raise at class definition time if it's set to anything other than True
- Otherwise, set the flag if any of the parents set have the flag set

As far as I can tell, this leads to the expected (and current, as of 3.10.0a6) 
behavior in all cases. Plus, it doesn't break my mental model of how 
inheritance works.
___
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/R3BGDN6NINJMLUWBVMVYIGORSLPJOMJP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-31 Thread Brandt Bucher
>> - Add new `__match_seq__` and `__match_map__` special attributes, 
>> corresponding to new public `Py_TPFLAGS_MATCH_SEQ` and 
>> `Py_TPFLAGS_MATCH_MAP` flags for use in `tp_flags`. When Python classes are 
>> defined with one or both of these attributes set to a boolean value, 
>> `type.__new__` will update the flags on the type to reflect the change 
>> (using a similar mechanism as `__slots__` definitions). They will be 
>> inherited otherwise. For convenience, `collections.abc.Sequence` will define 
>> `__match_seq__ = True`, and `collections.abc.Mapping` will define 
>> `__match_map__ = True`.
>> 
>> Using this in Python would look like:
>> 
>> ```
>> class MySeq:
>>  __match_seq__ = True
>>  ...
>> 
>> class MyMap:
>>  __match_map__ = True
>>  ...
>> ```
> 
> I don't like the way this need special inheritance rules, where inheriting 
> one attribute mutates the value of another. It seems convoluted.

Let me clarify: these two attributes do not interact with one another; each 
attribute only interacts with its own flag on the type. It is perfectly 
possible to do:

```
class WhatIsIt:
__match_map__ = True
__match_seq__ = True
```

This will set both flags, and this `WhatIsIt` will match as a mapping *and* a 
sequence. This is allowed and works in PEP 634, but like Guido I'm not entirely 
opposed to making the matching behavior of such a class undefined against 
sequence or mapping patterns. 

> Consider:
> 
> class WhatIsIt(MySeq, MyMap):
 pass
> 
> With __match_container__ it works as expected with no special inheritance 
> rules.

What *is* the expected behavior of this? Based on the current behavior of PEP 
634, I would expect the `__match_container__` of each base to be or'ed, and 
something like this to match as both a mapping and a sequence (which PEP 653 
says leads to undefined behavior). The actual behavior seems more like it will 
just be a sequence and not a mapping, since `__match_container__` would be 
inherited from `MySeq` and `MyMap` would be ignored.

In the interest of precision, here is an implementation of *exactly* what I am 
thinking:

`typeobject.c`: 
https://github.com/python/cpython/compare/master...brandtbucher:patma-flags#diff-1decebeef15f4e0b0ce106c665751ec55068d4d1d1825847925ad4f528b5b872

`ceval.c`: 
https://github.com/python/cpython/compare/master...brandtbucher:patma-flags#diff-c22186367cbe20233e843261998dc027ae5f1f8c0d2e778abfa454ae74cc59de

(One change from my last email: it doesn't allow `__match_map__` / 
`__match_seq__` to be set to `False`... only `True`. This prevents some 
otherwise tricky multiple-inheritance edge-cases present in both of our 
flagging systems that I discovered during testing. I don't think there are 
actual use-cases for unsetting the flags in subclasses, but we can revisit that 
later if needed.)
___
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/S4KLVTEA4HYDCAER25DZMOUB6LN6K63P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-30 Thread Brandt Bucher
Hi Mark.

I've spoken with Guido, and we are willing to propose the following amendments 
to PEP 634:

- Require `__match_args__` to be a tuple.
- Add new `__match_seq__` and `__match_map__` special attributes, corresponding 
to new public `Py_TPFLAGS_MATCH_SEQ` and `Py_TPFLAGS_MATCH_MAP` flags for use 
in `tp_flags`. When Python classes are defined with one or both of these 
attributes set to a boolean value, `type.__new__` will update the flags on the 
type to reflect the change (using a similar mechanism as `__slots__` 
definitions). They will be inherited otherwise. For convenience, 
`collections.abc.Sequence` will define `__match_seq__ = True`, and 
`collections.abc.Mapping` will define `__match_map__ = True`.

Using this in Python would look like:

```
class MySeq:
__match_seq__ = True
...

class MyMap:
__match_map__ = True
...
```

Using this in C would look like:

```
PyTypeObject PyMySeq_Type = {
...
.tp_flags = Py_TPFLAGS_MATCH_SEQ | ...,
...
}

PyTypeObject PyMyMap_Type = {
...
.tp_flags = Py_TPFLAGS_MATCH_MAP | ...,
...
}
```

We believe that these changes will result in the best possible outcome:
- The new mechanism should faster than either PEP.
- The new mechanism should provide a better user experience than either PEP 
when defining types in either Python *or C*.

If these amendments were made, would you be comfortable withdrawing PEP 653? We 
think that if we're in agreement here, a compromise incorporating these 
promising changes into the current design would be preferable to submitting yet 
another large pattern matching PEP for a very busy SC to review and pronounce 
before the feature freeze. I am also willing, able, and eager to implement 
these changes promptly (perhaps even before the next alpha) if so.

Thanks for pushing us to make this better.

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


[Python-Dev] Re: Request for comments on final version of PEP 653 (Precise Semantics for Pattern Matching)

2021-03-30 Thread Brandt Bucher
Overall, I am still uncomfortable with PEP 653, and would probably not support 
its acceptance.

Although it has thankfully become a much less radical proposal than it was a 
few weeks ago (thanks, Mark, for your attention to our feedback), I feel that 
the rules it binds implementations to are *very* premature, and that the new 
mechanisms it introduces to do so only modestly improve potential performance 
at great expense to the ease of learning, using, and maintaining code using 
structural pattern matching.

A few notes follow:

> For example, using `sympy`, we might want to write:
>
> ```
> # a*a == a**2
> case Mul(args=[a, b]) if a == b:
> return Pow(a, 2)
> ```
>
> Which requires the sympy class `Symbol` to "self" match. For `sympy` to 
> support this pattern with PEP 634 is possible, but a bit tricky. With this 
> PEP it can be implemented very easily.

Maybe I'm missing something, but I don't understand at all how the provided 
code snippet relies on the self-matching behavior.

Have the maintainers of SymPy (or any large library supposedly benefitting 
here) come out in support of the PEP? Are they at least aware of it? Have they 
indicated that the proposed idiom for implementing self-matching behavior using 
a property is truly too "tricky" for them?

Have you identified any stdlib classes that would benefit greatly from this?

For me, `__match_class__` feels like a feature without demonstrated need. Even 
if there is a great demand for this, I certainly think that there are far 
better options than the proposed flagging system:

- A `@match_self` class decorator (someone's bound to put one on PyPI, at any 
rate).
- Allowing `__match_args__ = None` to signal this case (an option we previously 
considered, and my personal preference).

...both of which can be added later, if needed.

Further, PEP 634 makes it very easy for libraries to support Python versions 
with *and* without pattern matching (something I consider to be an important 
requirement). The following class works with both 3.9 and 3.10:

```
class C(collections.abc.Sequence):
...
```

While something like this is required for PEP 653:

```
class C:
if sys.version_info >= (3, 10):
from somewhere import MATCH_SEQUENCE
__match_container__ = MATCH_SEQUENCE
...
```

> PEP 634 relies on the `collections.abc` module when determining which 
> patterns a value can match, implicitly importing it if necessary. This PEP 
> will eliminate surprising import errors and misleading audit events from 
> those imports.

I think that a broken `_collections_abc` module *should* be surprising. Is 
there any reasonable scenario where it's expected to not exist, or be not be 
fit for this purpose?

And I'm not sure how an audit event for an import that is happening could be 
considered "misleading"... I certainly wouldn't want it suppressed.

> Looking up a special attribute is much faster than performing a subclass test 
> on an abstract base class.

How much faster? A quick benchmark on my machine suggests less than half a 
microsecond. PEP 634 (like PEP 653) already allows us to cache this information 
for the subject of a match statement, so I doubt that this is actually a real 
issue in practice. An indeed, with the current implementation, this test isn't 
even performed on the most common types, such as lists, tuples, and 
dictionaries.

At the very least, PEP 653's confusing new flag system seems to be a *very* 
premature optimization, seriously hurting usability for a modest performance 
increase. (Using them wrongly also seems to introduce a fair amount of 
undefined behavior, which seems to go against the PEP's own motivation.)

> If the value of `__match_args__` is not as specified, then the implementation 
> may raise any exception, or match the wrong pattern.

I think there's a name for this sort of behavior... ;)

A couple of other, more technical notes:

- PEP 653 requires mappings to have a `keys()` method that returns an object 
supporting set inequality operations. It is not really that common to find this 
sort of support in user code (in my experience, it is more likely that 
user-defined `keys()` methods will return iterables). It's not even clear to me 
if this is an interface requirement for mappings in general. For example, 
`weakref.WeakKeyDictionary` and `weakref.WeakValueDictionary` presently do not 
work with PEP 653's requirements for mapping patterns, since their `keys()` 
methods return iterators.

- Treating `__getitem__` as pure is problematic for some common classes (such 
as `defaultdict`). That's why we use two-argument `get()` instead.

As well-fleshed out as the pseudocode for the matching operations in this PEP 
may be, examples like this suggest that perhaps we should wait until 3.11 or 
later to figure out what actually works in practice and what doesn't. PEP 634 
took a full year of work, and the ideas it proposed changed substantially 
during that time (in no small part because we 

[Python-Dev] Re: PEP 653: Precise Semantics for Pattern Matching

2021-02-19 Thread Brandt Bucher
Oscar Benjamin wrote:
> Under PEP 634 in general, for any class C, a pattern C(x) matches an object 
> C(x, y) and there's no way for C to override that. To me that is sufficiently 
> unintuitive in the abstract that no example is really needed to see where 
> there is room for improvement.

We originally kicked around (and at one point even implemented) a 
`__match_args_required__` attribute, which is an integer specifying a minimum 
required number of positional sub-patterns. For reasons I can't recall, though, 
it was eventually dropped. It would take care of this, and I imagine it could 
be quite painless to add it back if there was enough support.

Here's a query for related discussions: 
https://github.com/gvanrossum/patma/issues?q=__match_args_required__
___
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/JKZUE2BUDZQQHQLZK3IYBUNHYQWYMVA6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 653: Precise Semantics for Pattern Matching

2021-02-18 Thread Brandt Bucher
Brandt Bucher wrote:
> For a pattern with no positional subpatterns, such as like `C()` or `C(x=x, 
> y=y, z=z)`: ...

> It also appears that we lose a lot of expressive "idioms" by requiring 
> `__attributes__` to be complete.

> This also means that matching classes like `types.SimpleNamespace` are much 
> less powerful under PEP 653, since the class must know which attributes are 
> "allowed" to be looked up.

Never mind these three points... I *think* setting `__match_kind__ = 
MATCH_DEFAULT` allows for arbitrary attribute extraction like this. Perhaps 
make it bit clearer?
___
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/HCXNNE3B2SS3PFTDVMAA4EWNVXD6TH7W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 653: Precise Semantics for Pattern Matching

2021-02-18 Thread Brandt Bucher
Thanks for taking the time to work on this, Mark.

Overall, I'm skeptical of this proposal. It seems like it takes a lot of 
"simple" things and makes them quite complex, and takes many "static" things 
and makes them quite dynamic. I feel that it also misrepresents certain aspects 
of PEP 634.

Here's a more detailed commentary:

> Pattern matching will be more usable for complex classes, by allowing classes 
> more control over which patterns they match.

I fear this is at the expense of most simple classes, which currently "just 
work" with PEP 634. I'm not convinced that making it easier for very 
complicated classes (like those in `sympy`) to participate at the expense of 
everyday classes is a win.

For comparison, here is what (as I understand it) each PEP requires for a class 
to be used in a pattern such as `C(x, y, z)`:

```py
class C:
"""A PEP 634 matchable class."""
__match_args__ = ...

class C:
"""A PEP 653 matchable class."""
__match_kind__ = MATCH_CLASS
__attributes__ = ...
def __deconstruct__(self):
...
```

For a pattern with no positional subpatterns, such as like `C()` or `C(x=x, 
y=y, z=z)`:

```py
class C:
"""A PEP 634 matchable class (all classes work)."""

class C:
"""A PEP 653 matchable class."""
__match_kind__ = MATCH_CLASS
__attributes__ = ...
def __deconstruct__(self):
...
```

It also appears that we lose a lot of expressive "idioms" by requiring 
`__attributes__` to be complete. For example, the following attribute 
extractions work with PEP 634, but not PEP 653.

```py
match subject:
case object(a=_):
# Match any object with an "a" attribute.
...
case object(x=x, y=y, z=z):
# Match any object with "x", "y", and "z" attributes, extracting them.
...
```

This also means that matching classes like `types.SimpleNamespace` are much 
less powerful under PEP 653, since the class must know which attributes are 
"allowed" to be looked up.

Further, this whole specification shifts most of the matching logic from the 
class in the pattern to the subject itself:

```py
match ChildA(), ChildB():
case Parent(a, b), Parent(x, y):
...
```

The above pattern could have completely different rules for extracting `a` and 
`b` vs `x` and `y` if either child overrides `__deconstruct__`.  I think that 
is a mistake.

> PEP 634 also privileges some builtin classes with a special form of matching, 
> the "self" match. For example the pattern `list(x)` matches a list and 
> assigns the list to `x`. By allowing classes to choose which kinds of pattern 
> they match, other classes can use this form as well.

This is already fairly trivial to implement:

```py
class C:
__match_args__ = ("_self",)
_self = property(lambda s: s)
```

You can even avoid adding a `_self` attribute if you do some magic with 
descriptors... ;). We could consider provide a decorator for this somewhere in 
the stdlib if there's demonstrated need (but I'm not sure there will be).

> All classes should ensure that the the value of `__match_kind__` follows the 
> specification. Therefore, implementations can assume, without checking, that 
> all the following are false:
> `(__match_kind__ & (MATCH_SEQUENCE | MATCH_MAPPING)) == (MATCH_SEQUENCE | 
> MATCH_MAPPING)`
> `(__match_kind__ & (MATCH_SELF | MATCH_CLASS)) == (MATCH_SELF | MATCH_CLASS)`
> `(__match_kind__ & (MATCH_SELF | MATCH_DEFAULT)) == (MATCH_SELF | 
> MATCH_DEFAULT)`
> `(__match_kind__ & (MATCH_DEFAULT | MATCH_CLASS)) == (MATCH_DEFAULT | 
> MATCH_CLASS)`

Oof. I was scratching my head for way too long at this before I noticed the 
previous sentence said "false". Maybe reword this section to indicate the 
conditions that hold *true*? :)

> Security Implications
> Preventing the possible registering or unregistering of classes as sequences 
> or a mappings, that PEP 634 allows, should improve security. However, the 
> advantage is slight and is not a motivation for this PEP.

I would say the advantage is nonexistent. How is this any different than 
tweaking the flags in a class's `__match_kind__`?

> Efficient Implementation / Implementation

I won't get too deep into this section, but on the surface most flavors of 
implementation/optimization present here are also possible with PEP 634. I 
understand that you feel there are benefits to having "rules" for what 
optimizations are legal, but we don't need to completely change the mechanics 
of the match statement in order to do so.

> Because the object model is a core part of Python, implementations already 
> handle special attribute lookup efficiently. Looking up a special attribute 
> is much faster than performing a subclass test on an abstract base class.

But calling a `__deconstruct__` method whenever positional arguments are 
present will slow down normal class matches, right? I see it as mostly a wash.

> The changes to the semantics can be summarized as:
> - Selecting the kind of pattern uses 

[Python-Dev] Re: PEP 642 v2: Explicit constraint patterns *without* question marks in the syntax

2020-11-13 Thread Brandt Bucher
Paul Sokolovsky wrote:
> Use punctuation ("sigils") to mark as-binding terms. This choice still seems 
> to be under-considered. (As in: it doesn't seem like many people, including 
> the PEP authors, tried to say "indeed, what if?" and feel thru it. I mean, 
> try really hard. I trust the "gang of 4" spent maybe whole few hours on that 
> and delivered "no" to all us. It's still not the same as dozens of people 
> trying it over a few months).

To anyone actually wondering how much time and mental energy we’ve spent on a 
particular issue: please take a look at our tracker before guessing “maybe 
whole few hours”:

- Issue #1(!), April, 29 comments: https://github.com/gvanrossum/patma/issues/1
- Issue #90, June, 84 comments: https://github.com/gvanrossum/patma/issues/90
- Issue #92, June, 33 comments: https://github.com/gvanrossum/patma/issues/92
- Issue #105, June, 17 comments: https://github.com/gvanrossum/patma/issues/105
- Issue #143, August, 7 comments: https://github.com/gvanrossum/patma/issues/143

(I won't judge anyone for skimming a bit; it's a *lot* of discussion. Do note, 
though, that for months I was one of the proponents of store sigils like `?` 
until I was eventually convinced otherwise.)

That's also not counting side-discussions in other issues, countless mailing 
list threads, two competing PEPs that make many of the same choices, a video 
call with the SC, etc.

I'll also add, for anyone considering choosing yet another ASCII symbol off 
their keyboard and proposing it as a “novel”, “intuitive” marker: one problem 
with most of the hastily suggested adornments are that they do not nest very 
well, for even simple cases. Further, the fact that constructions like `p = 
Point(x, y)` look exactly the same as deconstructions like `case Point(x, y):` 
is absolutely intentional (which touches back on Guido’s “rhyme” comment last 
night).

Very briefly, compare the current syntax:

```
case first, *middle, last:
rebuilt = first, *middle, last
case {"key": value, **rest}:
rebuilt = {"key": value, **rest}
case Point(x=a, y=b):
rebuilt = Point(x=a, y=b)
```

with (using your own syntactic flavor):

```
case >first, *>middle, >last:
rebuilt = first, *middle, last
case {"key": >value, **>rest}:
rebuilt = {"key": value, **rest}
case Point(x=>a, y=>b):
rebuilt = Point(x=a, y=b)
```

(I had to stop and think *hard* where exactly the `>` should go in `*middle` 
and `**rest`. I'm not confident I made the correct guess, either.)
___
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/7SJ2SOPRD6XOAISOYXONKXUKB3JMLYNU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 642: Constraint Pattern Syntax for Structural Pattern Matching

2020-11-02 Thread Brandt Bucher
Glenn Linderman wrote:
> So what _is_ the syntax for "a tuple of two equal values" ?

If you’re asking about PEP 634:

```
case x, y if x == y:
```

Which is much clearer, in my opinion.
___
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/UM6ZACEZLF2B6YLMMO4TASWCVVKD2KPM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Thoughts on PEP 634 (Structural Pattern Matching)

2020-10-30 Thread Brandt Bucher
> Can we discuss whether we want pattern matching in Python and the broader 
> semantics first, before dealing with low level details?

This is a huge step backward. These discussions have already taken place, over 
the last 10 years.

Here's just a sampling:

- 
https://mail.python.org/archives/list/python-id...@python.org/thread/IEJFUSFC5GBDKFIPCAGS7JYXV5WGVAXP/
- 
https://mail.python.org/archives/list/python-id...@python.org/thread/GTRRJHUG4W2LXGDH4AU46SI3DLWXJF6A/
- 
https://mail.python.org/archives/list/python-id...@python.org/thread/EURSG3MYEFHXDDL2474PQNQZFJ3CUIOX/
- 
https://mail.python.org/archives/list/python-id...@python.org/thread/NTQEL3HRUJMULQYI6RDBTXQ2H3KHBBRO/
- 
https://mail.python.org/archives/list/python-id...@python.org/thread/NEC54II2RB3JRGHDP6PX3NOEALRAK6BV/
- 
https://mail.python.org/archives/list/python-id...@python.org/thread/T3VBUFECTLZMB424MBBGUHCI24YA4FPT/

We read all of these and more back way in March, before we even started 
brainstorming syntax and semantics.

> Do we want a fancy switch statement, or a powerful expression?

It's right here that you lose me. Anyone who reduces pattern matching to "a 
fancy switch statement" probably isn't the right person to be discussing its 
semantics and usefulness with. It seems that some people just can't separate 
the two ideas in their mind. It's like calling a class a "fancy module".

It's okay that you feel that way, but hopefully you'll understand if people 
start to tune out messages that contain these sorts of comments.

> What special method(s) should be added?

None. PEP 622 originally added one, but even that is more than we need right 
now. Some people may need to register their mappings or sequences as Mappings 
or Sequences, but otherwise that's it.

> I would ask anyone who wants pattern matching adding to Python, to not 
> support PEP 634.

Seriously?

I would ask anyone who wants pattern matching added to Python to carefully 
consider the PEPs for themselves (particularly PEP 636, which is much less dry 
and contains more examples and commentary). We've written four of the largest, 
most detailed PEPs of any new feature I've seen, complete with a working 
implementation that we've made available from any browser. Of course it's not 
the *only* way of getting pattern matching... but if you want it, this is 
probably your *best* shot at getting it.

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


[Python-Dev] Re: docs: I'd like new features to references their PEPs

2020-09-14 Thread Brandt Bucher
Agreed. To prevent the docs from going stale, the "Originally proposed in 
:pep:`XXX`." wording should probably be used for *all* of the new links, not 
just the ones that are currently out-of-date.

Depending on the scope of these changes, we could also just consider adding a 
new ".. pepadded:: XXX" directive for reuse and consistency.
___
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/2R4JJSJTCLVLWWQ4FKMMTVJ3UE3DVC2T/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Deferred, coalescing, and other very recent reference counting optimization

2020-09-03 Thread Brandt Bucher
Tim Peters wrote:
> `zip` then creates `n` 2-tuple objects, each of which lives only long enough 
> to be unpacked into `x` and `y`... With "immediate" reclamation of garbage 
> via refcounting, memory use is trival regardless of how large `n` is, as 
> CPython reuses the same heap space over & over & over, ASAP.  The space for 
> each 2-tuple is reclaimed before `x-y` is computed...

It's also worth noting that the current refcounting scheme allows for some 
pretty sneaky optimizations under-the-hood. In your example, `zip` only ever 
creates one 2-tuple, and keeps reusing it over and over:

https://github.com/python/cpython/blob/c96d00e88ead8f99bb6aa1357928ac4545d9287c/Python/bltinmodule.c#L2623

This is thanks to the fact that most `zip` usage looks exactly like yours, 
where the tuple is only around long enough to be unpacked. If `zip.__next__` 
knows it's not referenced anywhere else anymore, it is free to mutate(!) it in 
place. I believe PyUnicode_Append does something similar for string 
concatenation, as well.
___
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/MJ4BL42YSMP5BUGWT7EEK3EKNVGBDH35/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-10 Thread Brandt Bucher
Federico Salerno wrote:
> Is there anything (bar tradition or other subjective arguments) that speaks 
> in favour of this, especially in light of the fact that having the same 
> indentation level would also solve other problems? ...if anyone made an 
> argument against it I must have missed it:

We spend a fair bit of time discussing this exact proposal in the PEP (I just 
searched for "indent"):

https://www.python.org/dev/peps/pep-0622/#use-a-flat-indentation-scheme
___
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/KLP6CTEVLYXVGBGBWCTUARV2KQAPYJVS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-08 Thread Brandt Bucher
Ethan Furman wrote:
> Why is this no longer an issue?  My apologies if I missed it in the PEP.

This problem was an artifact of the default `object.__match__` implementation, 
which allowed one positional argument by default when `__match_args__` was 
missing or `None`. Since we've removed `__match__` from the proposal (and 
therefore the default `__match__` implementation from `object`), this issue no 
longer exists.

(Note that most common built-in types like `int` and `tuple` will still work 
this way, but this behavior is not inherited by *all* objects anymore).
___
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/NFP22VPMLZ4EERYU6KEB2KO7KQQ7ETA5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-07-08 Thread Brandt Bucher
Inada Naoki wrote:
> Since this is very new system, can we have some restriction to allow 
> aggressive optimization than regular Python code?

The authors were just discussing a related question yesterday (more 
specifically, can the compiler fold `C() | C()` -> `C( | )`). 
The answer we arrived at is "yes"; in general patterns may take reasonable 
shortcuts, and should not be expected to follow all the same rules as 
expressions. This means that users should never count on 
`__contains__`/`__getitem__`/`__instancecheck__`/`__len__`/`__match_args__` or 
other attributes being looked up or called more than once with the same 
arguments, and that name lookups *may* be "frozen", in a sense. We don't feel a 
need to cater to code that relies on these side-effecty behaviors (or doing 
even nastier things like changing local/global name bindings); in the eyes of 
the authors, code like that is buggy.

However, these rules only apply as long as we are still in "pattern-land", 
meaning all of our knowledge about the world is invalidated as soon as we hit a 
guard or stop matching.

In practice, I am currently experimenting with building decision-trees at 
compile-time. Given a match block of the following form:

```
match :
case  | : ...
case  |  if : ...
case  | : ...
```

It's safe to use the same decision tree for  through , but it must be 
rebuilt for  and , since  could have done literally *anything*.
___
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/XY3FXVB7HDYJIVKSOOBHW5BV2UB522FL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Why does _ need to be special ?

2020-07-08 Thread Brandt Bucher
Henk-Jaap Wagenaar wrote:
> The not binding is there only to allow the main way in which "_" is special 
> in match/case: ...

The non-binding behavior is useful in other ways:

match range(HUGE_INT):
case [*_, last]:
print(last)
___
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/2BYZQUCYIJKJSS6DRDVLRWI5B767S6ZO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 railroaded through?

2020-07-04 Thread Brandt Bucher
Since I took it upon myself to implement PEP 622, I just have a few thoughts to 
add to the other excellent responses here. Hopefully these will help clarify 
that the intent is not to "railroad" anything.

Rob Cliffe wrote:
> PEP 622 only seems to have been presented to the Python community only after 
> a well-developed (if not finalised) implementation was built.

Well, thanks for the "well-developed" bit, but I promise that the 
implementation is far from final. Since we first published the PEP, I've made 
dozens of commits touching pretty much every new line of code several times. 
Just last week we gutted the __match__ method in response to well-reasoned 
calls to defer it.

> So there will inevitably be resistance from the developers to accept changes 
> suggested on python-dev.

As the one who has been doing almost all of the development, I assure you this 
isn't true. 80% of the PEP's authors have been almost entirely detached from 
development of the reference implementation, so I would be very surprised if 
they gave my existing work more weight than the opinions of the community... I 
wrote the thing, and I certainly don't!

I volunteered to implement it because I thought the PEP and implementation 
would be an interesting project while trapped at home this spring. I *like* 
doing this stuff, so I'm not really worried about getting to do more of it. ;)

> And since the PEP has Guido's authority behind it, I think it is likely that 
> it will eventually be accepted pretty much as it was originally written.

It has already changed quite substantially from how it was originally written. 
Here's everything that's changed since we posted the first draft (we've been 
pretty much dominating PEP repo traffic over the past week):

https://github.com/python/peps/commits/master/pep-0622.rst

Again, you'll notice that the entire __match__ protocol was deferred based on 
feedback we received, and we've made an effort to describe the reasoning behind 
many decisions that seemed obvious to us but weren't to others. The opening 
sections are also getting a rewrite (again, based on Python-Dev feedback).

> Guido's 2nd email ("PEP 622: Structural Pattern Matching -- followup") 
> already to me (YMMV) reads rather like "OK, you've had your fun, now try not 
> to joggle our elbows too much while we get on with the work".

That's an extremely odd way to interpret his thread, which exists solely to 
collect of all of the "unheard" critiques in one central location.

> I do think it's a pity that the Python community did not have the chance to 
> supply feedback earlier down the road (when IMO it would have been taken more 
> seriously).

It did. The very first thing we did was perform detailed surveys of 8 different 
Python-Ideas threads (spanning 9 years), 13 other languages, and a handful of 
the most popular Python packages for pattern matching. This is not at all the 
first time this has been brought up by the community; I personally worked my 
way through hundreds of emails and dozens of documents before writing a single 
line of code (or PEP).

> While Guido and the other developers have obviously already put a huge amount 
> of work into this PEP (and by now probably have a significant emotional 
> investment in it), I do hope that they will take the time to consider 
> seriously and on their merits most/all suggested changes, rather than being 
> tempted to rush through the acceptance and implementation of the PEP.

Don't worry; I have a much stronger emotional connection to Python's continued 
success and community than to a quarantine project that Guido nerd-sniped me 
with a few months ago. ;)

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


[Python-Dev] Re: PEP 622 (match statement) playground

2020-07-01 Thread Brandt Bucher
Walter Dörwald wrote:
> This looks strange to me. In all other cases of variable lookup the global 
> variable z would be found.

The next case assigns to z, making z local to whereis. This is consistent with 
python's existing scoping rules (for example, try rewriting this as the 
equivalent if-elif chain and you'll get the same error). It sounds like you 
want to add "global z" to the top of the function definition.

> whereis(23) however works.

This branch is hit before the unbound local lookup is attempted.
___
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/CZAZYFSWWEYTXDEXEZ75TNTVKSIZZ27K/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Brandt Bucher
Ethan Furman wrote:
> Ouch.  That seems like a pretty serious drawback.  Will this issue be 
> resolved?

It's currently being revisited.

Realistically, I'd imagine that we either find some straightforward way of 
opting-in to the current default behavior (allowing one arg to be positionally 
matched against the proxy), or lose the nice behavior altogether. Obviously the 
former is preferable, since it's not trivial to reimplement yourself.
___
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/UZ77WPWH4DK3IK3ANKQYOCXKVW4AERIE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching -- followup

2020-06-25 Thread Brandt Bucher
Pablo Galindo Salgado wrote:
> ...users can do a positional match against the proxy with a name pattern:
>
> match input:
> case datetime.date(dt):
> print(f"The date {dt.isoformat()}"
>
> ...if 'datetime.date' were updated to implement a non-default __match_args__, 
> allowing individual fields to be pulled out of it like this, then the first 
> block would be valid, correct code before the change, but would raise an 
> ImpossibleMatch after the change because 'dt' is not a field in 
> __match_args__. Is this argument misinterpreting something about the PEP or 
> is missing some important detail?

Well yeah, it's actually a fair bit worse than you describe. Since dt is 
matched positionally, it wouldn't raise during matching - it would just succeed 
as before, but instead binding the year attribute (not the whole object) to the 
name "dt". So it wouldn't fail until later, when your method call raises a 
TypeError.
___
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/Y7DJJA2ONIRJSMMA6PYKAYCZSYIECY4D/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-24 Thread Brandt Bucher
Guido van Rossum wrote:
> So why not  .get(key, )? You can reuse the sentinel, and this way 
> it's a single call instead of two -- e.g. the code in Mapping implements both 
> __contains__() and get() by calling __getitem__() and catching KeyError.

Good point. Another option I've considered is using the `keys` method, since 
most non-dict mappings would get this called anyways for patterns with `**rest`.

All the more reason why we should allow the implementation some flexibility. ;)
___
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/RLBJKQNWFOTCBSAJT47J7RO2K26ZFQAL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-24 Thread Brandt Bucher
Guido van Rossum wrote:
> IIUC the pattern matching uses either .get(key, ) or 
> .__contains__(key) followed by .__getitem__(key). Neither of those will 
> auto-add the item to a defaultdict (and the Mapping protocol supports both). 
> @Brandt: what does your implementation currently do? Do you think we need to 
> specify this in the PEP?

I still prefer under-specifying rather than over-specifying, in order to allow 
the implementation some flexibility. Basically, "if you've got a funny mapping, 
it may behave funny".

For example, we currently perform a length check before even getting to this 
point, which is allowed because the spec isn't very strict. This is a good 
thing; we already have a section in the PEP that explicitly allows compiler to 
perform transformations such as C(x) | C(y) -> C(x | y).

If we have to specify it, __contains__ followed by __getitem__ is the way to do 
it. The current behavior is subtly different (and probably wrong), but I was 
going to change it today anyways... I had an outstanding TODO for it.
___
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/FGHL3HV3Z5W5DBURTE76WU4YI23IRZ3Z/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Accepting PEP 618: zip(strict=True)

2020-06-16 Thread Brandt Bucher
Woo! Many thanks to Ram for the idea, Antoine for sponsoring, Guido for 
PEP-Delegating, and everyone on -Ideas and -Dev for the spirited discussion and 
review.

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


[Python-Dev] Re: PEP 584 underspecified

2020-05-19 Thread Brandt Bucher
Maybe I'm missing something here. The PEP specifically says:

> Similarly, the iteration order of the key-value pairs in the dictionary will 
> follow the same semantics as the examples above, with each newly added key 
> (and its value) being appended to the current sequence.

That seems sufficient, no?
___
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/NM75M5N7BJOHSG3ZELIVBUNOG7ZQ3VQ4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 618: Add Optional Length-Checking To zip

2020-05-15 Thread Brandt Bucher
In the last 24 hours, this thread has grown a bit beyond my capacity to 
continue several different lines of discussion with each individual. I count 22 
messages from 14 different people since my last reply, and I assure you that 
I've carefully read each response and am considering them as I work on the next 
draft.

I'd like to thank everyone who took the time to read the PEP and provide 
thoughtful, actionable feedback here!

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


[Python-Dev] Re: PEP 618: Add Optional Length-Checking To zip

2020-05-15 Thread Brandt Bucher
Ethan Furman wrote:
> Can you do those with _pydecimal?  If performance were an issue anywhere I 
> would expect to see it with number crunching.

No difference, probably because those methods look like they spend most of 
their time doing string manipulation:

```

$ export PYPERFSETUP='from _pydecimal import Decimal; from random import 
getrandbits; l = Decimal(bin(getrandbits(28))[2:]); r = 
Decimal(bin(getrandbits(28))[2:])' 
$ export PYPERFRUN='l.logical_and(r); l.logical_or(r); l.logical_xor(r)'

$ ./python-master -m pyperf timeit -s "$PYPERFSETUP" "$PYPERFRUN"
Mean +- std dev: 53.4 us +- 2.8 us
$ ./python-zip-strict -m pyperf timeit -s "$PYPERFSETUP" "$PYPERFRUN"
Mean +- std dev: 53.8 us +- 2.5 us
$ ./python-zip-strict -m pyperf timeit -s "$PYPERFSETUP" "$PYPERFRUN"  # This 
time, with strict=True in each method.
Mean +- std dev: 53.6 us +- 3.0 us

```

I would encourage those who are still curious to pull the branch and experiment 
for themselves. Let's try to keep this a design discussion, since we've 
established that performance isn't a problem (and there is plenty of time for 
code review later).

> Paul Moore and Chris Angelico have made good arguments in favor of an 
> itertools addition which haven't been answered yet.

I don't consider their arguments particularly strong, but yeah, I was getting 
to those. I wanted to address your points first since you weren't part of the 
Ideas discussion!

Paul Moore wrote:
> ... so it's another beast because (among other reasons) it lives in a 
> separate namespace, and it should live in a separate namespace because it's 
> another beast? That's circular logic.

Sorry, that's on me for trying to respond to two questions with one answer 
right before bed. Strike the namespace argument, then. The rest stands.

> So importing zip_strict from itertools is an entirely reasonable way for 
> users to enable the check, then.

Still agreed. But I think they would be *better* served by the proposed keyword 
argument.

This whole sub-thread of discussion has left me very confused. Was anything 
unclear in the PEP's phrasing here? If so, I'd like to improve it. The original 
quote is: "The goal here is not just to provide a way to catch bugs, but to 
also make it easy (even tempting) for a user to enable the check whenever using 
`zip` at a call site with this property."

> It's very easy to suggest bad ways of using a feature. That doesn't make the 
> feature bad. You seem to be arguing that zip_strict is bad because people can 
> misuse it.

Well, I addressed this "irrelevant" point because right out of the gate people 
started suggesting that they want a separate function *because* it makes 
shadowing easy. Which brings me to my next quote:

Chris Angelico wrote:
> I am most in favour of the separate-functions option *because* it makes 
> shadowing easy. Not an anti-pattern at all.

I *really* hope this isn't how people use this (and I don't *think* it would be 
predominantly used this way), but at least it's clear to me now why you want it 
to be a separate function.

It would still be quite simple to follow this pattern, though, with 
`functools.partial` or a custom wrapper.

> Python is *deliberately* designed so that you can shadow things.

I wouldn't confuse "can" and "should" here. Python is deliberately designed to 
make *many* design patterns possible, good and bad.

> And considering that "from __future__ import print_function" is an 
> officially-sanctioned way to cause a semantic change to print, I don't think 
> it's really that strong an argument.

Well that's a parser directive that is just there for 2/3 compatibility (I'm 
pretty sure - I've never used Python 2). I see it as very, very different from 
my `from pprint import pprint as print` headache that was quoted two levels up.

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


[Python-Dev] Re: PEP 618: Add Optional Length-Checking To zip

2020-05-14 Thread Brandt Bucher
Ethan Furman wrote:
> So half of your examples are actually counter-examples.

I claimed to have found "dozens of other call sites in Python's standard 
library and tooling where it would be appropriate to enable this new feature". 
You asked for references, and I provided two dozen cases of zipping what must 
be equal length iterables.

I said they were "appropriate", not "needed" or even "recommended". These are 
call sites where unequal-length iterables, if encountered, would be an error 
that I would hope wouldn't pass silently. Besides, I don't think it's beyond 
the realm of imagination for a future refactoring of several of the "Mismatch 
cannot happen." cases to introduce a bug of this kind.

> Did you vet them, or just pick matches against `zip(`?

Of course. I spent hours vetting them, to the point of researching the GNU tar 
extended sparse header and Apple property list formats (and trying to figure 
out what the hell was happening in `os._fwalk`) just to make sure my 
understanding was correct.

Ethan Furman wrote:
> Not the call itself, but the running of zip.  Absent some clever programming 
> it seems to me that there are two choices if we have a flag:

I wouldn't call my implementation "clever", but it differs from both of these 
options.  We only need to check if we're strict when an error occurs in one of 
our iterators, which is a situation the C code for `zip` already needs to 
explicitly handle with a branch. So this condition is only hit on the "last" 
`__next__` call, not on every single iteration.

As a reminder, the actual C implementation is linked in the PEP (there's no PR 
yet but branch reviews are welcome), though I'd prefer if the PEP discussion 
didn't get bogged down in those specifics.  The pure-Python implementation in 
the PEP is *very* close to it, but it uses different abstractions for some of 
the details regarding error handling and argument parsing.[0]

However, for those who are interested, there is no measurable performance 
regression (and no additional parsing overhead for no-keyword-argument calls). 
Parsing the keyword argument (if present) adds <0.2us of overhead at creation 
time on my machine. I went ahead and ran some rough PGO/LTO benchmarks:

Creation time:

```

$ ./python-master -m pyperf timeit 'zip()'
Mean +- std dev: 79.4 ns +- 4.3 ns 
$ ./python-zip-strict -m pyperf timeit 'zip()'
Mean +- std dev: 79.0 ns +- 1.9 ns
$ ./python-zip-strict -m pyperf timeit 'zip(strict=True)'
Mean +- std dev: 240 ns +- 8 ns

```

Creation time + iteration time:

```

$ ./python-master -m pyperf timeit -s 'r = range(10)' '[*zip(r, r)]'
Mean +- std dev: 577 ns +- 35 ns
$ ./python-zip-strict -m pyperf timeit -s 'r = range(10)' '[*zip(r, r)]'
Mean +- std dev: 565 ns +- 16 ns
$ ./python-zip-strict -m pyperf timeit -s 'r = range(10)' '[*zip(r, r, 
strict=True)]'
Mean +- std dev: 756 ns +- 27 ns

$ ./python-master -m pyperf timeit -s 'r = range(100)' '[*zip(r, r)]'
Mean +- std dev: 3.54 us +- 0.14 us
$ ./python-zip-strict -m pyperf timeit -s 'r = range(100)' '[*zip(r, r)]'
Mean +- std dev: 3.49 us +- 0.07 us
$ ./python-zip-strict -m pyperf timeit -s 'r = range(100)' '[*zip(r, r, 
strict=True)]'
Mean +- std dev: 3.73 us +- 0.13 us

$ ./python-master -m pyperf timeit -s 'r = range(1000)' '[*zip(r, r)]'
Mean +- std dev: 44.1 us +- 2.0 us
$ ./python-zip-strict -m pyperf timeit -s 'r = range(1000)' '[*zip(r, r)]'
Mean +- std dev: 45.2 us +- 2.0 us
$ ./python-zip-strict -m pyperf timeit -s 'r = range(1000)' '[*zip(r, r, 
strict=True)]'
Mean +- std dev: 45.2 us +- 1.4 us

```

Additionally, the size of a `zip` instance has not changed.  Pickles for 
non-strict `zip` instances are unchanged as well.

Brandt

[0] And zip's current tuple caching, which is *very* clever.
___
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/ZVCBS2S7IRIEU346AAJUEVH45VNMVOKI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 618: Add Optional Length-Checking To zip

2020-05-12 Thread Brandt Bucher
Thanks for all of your feedback.

Antoine Pitrou wrote:
> I'm not sure what the iters bring here.  The snippet would be more readable 
> without, IMHO.

Good point. I was trying to demonstrate that it works with iterators, but I 
agree it's clearer to just use the lists here.

Ethan Furman wrote:
> > Many Python users find that most of their zip usage
> I don't think you have enough data to make that claim, unless by "many" you 
> mean five or more.

It's based on a combination of my own experience, the experiences of several 
others, and a survey of the CPython repo. I can dial back the wording, though, 
since this isn't necessarily representative of the larger userbase...

> > but silently start producing shortened, mismatched results if items is 
> > refactored by the caller to be a consumable iterator
> This seems like a weak argument; static type checking could catch it.

Well, that's why I go on to make stronger, non-toy ones immediately after. :) 
This is mainly just to introduce the problem in an easy-to-understand way.

> > the author has counted dozens of other call sites in Python's standard 
> > library
> References, please.

Here are two dozens:

- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/_pydecimal.py#L3394
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/_pydecimal.py#L3418
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/_pydecimal.py#L3435
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/ast.py#L94-L95
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/ast.py#L1184
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/ast.py#L1275
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/ast.py#L1363
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/ast.py#L1391
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/copy.py#L217
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/csv.py#L142
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/dis.py#L462
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/filecmp.py#L142
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/filecmp.py#L143
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/inspect.py#L1440
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/inspect.py#L2095
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/os.py#L510
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/plistlib.py#L577
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/tarfile.py#L1317
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/tarfile.py#L1323
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/tarfile.py#L1339
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/turtle.py#L3015
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/turtle.py#L3071
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/Lib/turtle.py#L3901
- 
https://github.com/python/cpython/blob/27c0d9b54abaa4112d5a317b8aa78b39ad60a808/setup.py#L455

I'll go ahead and link these in the PEP.

> > A good rule of thumb is that "mode-switches" which change return types or 
> > significantly alter functionality are indeed an anti-pattern,
> Source?

This was based on a chat with someone who has chosen not to become involved in 
the larger discussion, and it was lifted almost verbatim from my notes into the 
draft. Looking at it again, though, I don't think this sentence belongs in the 
PEP... it really shouldn't be prescribing design philosophies like this.

> > while ones which enable or disable complementary checks or behavior are not.
> None of the listed examples change behavior between "working" and "raising 
> exceptions", and none of the listed examples are for "complementary checks".

Thanks for pointing this out. If I keep this bit, I'll include some other 
examples from the stdlib that specifically behave this way.

> > At most one additional item may be consumed from one of the iterators when 
> > compared to normal zip usage.
> How, exactly?

I'm actually considering just leaving this line out, too. We don't currently 
make any promises about how "extra" items are drawn (just that they are drawn 
left-to-right, which is still true here), so I don't think this needs to be in 
the spec.

> > However, zip_longest is really another beast entirely
> No, it isn't.

It has a completely 

[Python-Dev] PEP 618: Add Optional Length-Checking To zip

2020-05-10 Thread Brandt Bucher
I have pushed a second draft of PEP 618:

https://www.python.org/dev/peps/pep-0618

Please let me know what you think – I'd love to hear any new feedback that 
hasn't yet been addressed in the PEP!

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


[Python-Dev] Re: Question about bytecode stability

2020-04-05 Thread Brandt Bucher
> The best way to look at this is to consider how long a .pyc file is valid. 
> They're currently named something like __pycache__/modulename.cpython-38.pyc 
> which is a fairly clear indication that the cached compiled module should be 
> valid for any CPython 3.8.x release.

Perhaps an even better indicator is the “magic number” that invalidates the 
cached bytecode. This can change several times during the alpha and beta 
phases, and a (mostly complete) record of changes can be found here:

https://github.com/python/cpython/blob/master/Lib/importlib/_bootstrap_external.py#L147-L284
___
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/NKNIMQCET2OKNUY6MCYMBFYVGJY7ZN7L/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 614 accepted

2020-03-04 Thread Brandt Bucher
Welcome Bhavani!

This is only my second PEP, but I'm sure somebody will correct me if I'm wrong! 
Basically, the next steps are:

- Mark the PEP as "Accepted": 
https://github.com/python/peps/commit/841188a45f17f0252267f016d7b2f11ac27c5aa1
- Review and merge the implementation/tests: 
https://github.com/python/cpython/pull/18570
- Add documentation: (in progress, sometime today)
- Mark the PEP as "Final": (last step)

PEP 1 (the meta-PEP), outlines the PEP lifecycle quite well:

https://www.python.org/dev/peps/pep-0001/#pep-review-resolution

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


[Python-Dev] Re: PEP 614 accepted

2020-03-03 Thread Brandt Bucher
Thanks to Guido for sponsoring, and to the SC for their acceptance!

Brandt
___
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/F3LVBGPDLB26QFJEKOLSPOHJ6DG7LWKJ/
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: Accepting PEP 584: Add Union Operators To dict

2020-02-24 Thread Brandt Bucher
> Are these three cookie classes sufficiently popular that we need to support 
> `|` on them?

I don't have much experience with `http`, so I figured I'd open a BPO issue and 
let the relevant folks make the call. The main reason I'm considering these is 
that `Morsel` was updated back in 3.5 with `copy` and `update` overrides:

https://bugs.python.org/issue2211
___
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/NWJIVQ35JYM2VAG6JHTNWPHZKAAM2GJQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 614: Relaxing Grammar Restrictions On Decorators

2020-02-22 Thread Brandt Bucher
Happy to help.

Since it doesn't seem like anybody has issues with the PEP, and the PR looks 
solid, I think I'll contact the Steering Council about moving this forward.

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


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

2020-02-22 Thread Brandt Bucher
> we'll also want to look at collections.UserDict, collections.ChainMap, and 
> types.MappingProxyType.

UserDict has already been updated in the PR (it has tests that fail if it 
doesn't have all of dict's methods). I'll look into the others... thanks for 
reminding me!

> collections.Mapping and collections.MutableMapping could provide concrete 
> method implementations that make subclasses behave in a way that's similar to 
> built-in dicts

Hm, haven't thought too much about this (I don't have much experience with the 
ABCs). Would they return dicts, or call the self.copy and self.update methods?

Those are just hypothetical questions for now; I don't necessarily want to dig 
too far into that discussion again. But I agree that it's definitely worth 
considering. ;)
___
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/QRX3NQPWTHFQFSQR6NJ54N2IKRGL3VET/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-22 Thread Brandt Bucher
Just to follow up on this, here are the subclasses I've found.

Should be updated:
- collections.OrderedDict
- collections.defaultdict
- http.cookies.BaseCookie
- http.cookies.Morsel
- http.cookies.SimpleCookie

Don’t think so:
- typing.TypedDict

Already defines the operator:
- collections.Counter

Not Public (or at least not documented):
- _strptime.TimeRE
- builtins.StgDict (this one's only available internally in _ctypes).
- email._encoded_words._QByteMap
- enum._EnumDict
- logging.config.ConvertingDict
- multiprocessing.pool._PoolCache
- urllib.parse.Quoter
___
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/BRNLVR4G7TDG7Z2BQMURCSYSTFHDXYW5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Three trivial PRs from first-timers in need of merging!

2020-02-21 Thread Brandt Bucher
All of these have been landed. Thanks, everybody!
___
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/GU6AWXQP4KIYMRSHPLGSNOATLR4RBTAK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Three trivial PRs from first-timers in need of merging!

2020-02-20 Thread Brandt Bucher
Hi everybody!

I've found a handful of trivial PRs from new contributors that have gone 
un-core-reviewed since November. CLAs are signed, tests are passing, and I've 
verified the quality and correctness of each one.

If anybody has a few spare minutes to merge these, I know that it would make 
the authors very happy! :)

Clarify numeric padding behaviour in string formatting:
- A helpful doc addition (just a few words).
- https://github.com/python/cpython/pull/17036

argparse unittest tracebacks are confusing if an error is raised when not 
expected:
- This just changes a "raise" to a "raise from None" in the argparse unit test 
machinery.
- https://github.com/python/cpython/pull/17120

Reuse identifier of PREDICT macros as PREDICT_ID:
- Unifies some shared naming logic in the ceval prediction macros (don't worry, 
it's simple).
- https://github.com/python/cpython/pull/17155/files

Thanks.

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


[Python-Dev] PEP 614: Relaxing Grammar Restrictions On Decorators

2020-02-18 Thread Brandt Bucher
PEP 614 has recently completed a round of review on Python-Ideas:

https://www.python.org/dev/peps/pep-0614/

It proposes that the current decorator syntax restrictions be relaxed to allow 
any valid expression. Nobody has raised any objections, but I wanted to gather 
more feedback here prior to bringing it before the Steering Council.

Please let me know what you think... thanks! :)
___
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/SLKFAR56RA6A533O5ZOZ7XTJ764EMB7I/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-18 Thread Brandt Bucher
> In particular, you may want to update the implementations of defaultdict and 
> ordereddict. (are there others?)

I have a checklist for PEP 584 follow-up PRs I'm planning to make after (and 
if) it is accepted. typeshed stubs, docs, and `defaultdict` were on it. I'll 
add `OrderedDict` as well (for some reason I didn't think it was a `dict` 
subclass). `Counter` already defines this operator for other purposes, so no 
need to do anything there.

I'm not aware of other public subclasses, but I may just try importing the 
whole stdlib and recursing through `dict.__subclasses__()` just to be sure.
___
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/3SJTNSTTZ4G5CXQQWNWRBY7WZHEWBYEY/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-18 Thread Brandt Bucher
> I am accepting this PEP. Congratulations Steven and Brandt!

Thank you for your guidance, especially the suggestions late last year. And 
thanks Steven for taking me on as a co-author and shaping the bulk of the 
proposal.

> Hm, the PEP should probably also link to that PR rather than to Brandt's 
> private branch.

Agreed. This can probably be changed when the status is updated.

Now, addressing Serhiy's points :)...

> ...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.

> 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.

> I suggest to include to objections that non-inplace merging of two dicts is 
> much less common operation than concatenating of two strings or other 
> sequences, and that the existing syntax {**d1, **d2} completely satisfies the 
> need.

This is really two objections.

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.

A rewording of your second objection has already been addressed:

https://www.python.org/dev/peps/pep-0584/#more-than-one-way-to-do-it

I feel that I've adequately responded to the other points you've raised here in 
this email (please let me know if I missed anything, and perhaps Steven may 
want to chime in as well). I don't know what the policy for changing the PEP is 
once it's gotten to this stage, but it's already grown to a huge size in its 
attempts to address every possible concern that has arisen over the past year 
(even some that, in my opinion, weren't serious proposals that needed to be 
acknowledged). I'd prefer not to bloat it even more this late in the game, if 
at all possible.
___
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/TEC4G6LVTHFL566ELDC4J6S527LI5C37/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-16 Thread Brandt Bucher
> So can we just finish PEP 584 without the .copy() call?

Sounds good. I’ll update the implementation and open a PR to the PEPs repo 
later tonight. Thanks everybody!
___
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/IPSPMBI6YKWWLVJJT7V2O5X7HHMPD7FJ/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-16 Thread Brandt Bucher
After a few days of thinking and experimenting, I’ve been convinced that `copy` 
(and also `__copy__`) is not the right protocol for what we want to do here. I 
believe that 584 can likely continue without subclass-preserving behavior, but 
that better behavior could perhaps could be added to *all* built-in types 
later, since it’s outside the scope of this PEP.

> My opinion is that Python built-in types make subclassing unnecessarily(?) 
> awkward to use, and I would like to see that change.

Yes! But, on further reflection, I don’t think this is the correct way of 
approaching it.

> For example, consider subclassing float. If you want your subclass to be 
> actually usable, you have to write a whole bunch of boilerplate, otherwise 
> the first time you perform arithmetic on your subclass, it will be converted 
> to a regular old float… This is painful and adds a great amount of friction 
> to subclassing.

`float` is a *perfect* example of the problems with the way things are 
currently, so let’s focus on this.

Currently, subclassing `float` requires ~30 overridden methods of repetitive 
(but non-trivial) boilerplate to get everything working right. However, calling 
the `float` equivalent of `dict.copy()` on the LHS before proceeding with the 
default implementation wouldn’t help us, because floats (like many built-in 
types) are immutable. So a new, plain, built-in `float` would still be returned 
by the default machinery. It doesn’t know how to construct a new, different 
instance of our subclass, and it can’t change one it’s already built.

This leads me to believe that we’re approaching the problem wrong. Rather than 
making a copy and working on it, I think the problem would be better served by 
a protocol that runs the default implementation, *then* calls some under hook 
on the subclass to build a new instance.

Let’s call this method `__build__`. I’m not sure what its arguments would look 
like, but it would probably need at least `self`, and an instance of the 
built-in base class (in this case a `float`), and return a new instance of the 
subclass based on the two. It would likely also need to work with `cls` instead 
of `self` for `classmethod` constructors like `dict.fromkeys`, or have a second 
hook for that case.

By subclassing `float` and defining `__build__` to something like this:

```
class MyFloat(float):
…
def __build__(self, result):
Return MyFloat(result, some_state=self.some_state)
…
```

I could now trust the built-in `float` machinery to try calling 
`lhs.__build__(result)` on the result that *would* have been returned *before* 
returning it. This is a simple example, but a protocol like this would work for 
mutables as well.

> A more pertinent example, from dict itself:

If `dict` *were* to grow more operators, they would likely be `^`, `&`, and 
`-`. You can consider the case of subclassing `set` or `frozenset`, since they 
currently has those. Calling `lhs.copy()` first before updating is fine for 
additive operations like `|`, but for subtractive operations like the others, 
this can be very bad for performance, especially if we’re now *required* to 
call them. Again, doing things the default way, and *then* constructing the 
appropriate subclass in an agreed-upon way seems like the path to take here.

> Changing all builtins is a big, backwards-incompatible change.

If implemented right, a system like the one described above (`__build__`) 
wouldn’t be backward-incompatible, as long as nobody was already using the name.

Just food for thought. I think this is a much bigger issue than PEP 584, but 
I'm convinced that the consistent status quo should prevail until a suitable 
solution for all types can be worked out (if ever).
___
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/7HNJ6RVVEX2VD37HYR5F5P5W2YAOMPDH/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-06 Thread Brandt Bucher
> > We already have an API for copying a dict (dict.copy). I still fail to see 
> > problem with using a method that doesn't start and end with underscores, 
> > other than that we "haven't done it".
>
> Before Python 3.0, iterators had a next() method, and that was explicitly and 
> consciously changed to __next__(). The arguments there seem relevant here too.

Thanks for bringing this up. PEP 3114 does a great job of explaining how and 
why Python uses dunders for *language-level* constructs. I would probably be 
opposed to language features or built-in functions doing magical things with 
the `copy` method of dicts; however, in this case, it's being used by the dict 
itself! As the PEP 3114 says:

> In Python, double underscores before and after a name are used to distinguish 
> names that belong to the language itself... Not all things that are called 
> "protocols" are made of methods with double-underscore names... even though 
> the read method is part of the file protocol, it does not have double 
> underscores because there is no language construct that implicitly invokes 
> x.read().

The language itself doesn't call `copy`, but `dict` should feel free to. 
Especially if it makes life easier for subclasses (which PEP 584 actually 
encourages users to make in the "Rejected Semantics" section: 
https://www.python.org/dev/peps/pep-0584/#rejected-semantics)!
___
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/FIPVZTUM4CJ5WJWAAYGS4E55Y7AP7J6E/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-06 Thread Brandt Bucher
Sorry Paul, I sent my reply too soon.

I see what you're saying, and I'm pretty firmly -1 on reinventing (or 
importing) copy.copy. We already have an API for copying a dict (dict.copy). 

I still fail to see problem with using a method that doesn't start and end with 
underscores, other than that we "haven't done it".

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


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

2020-02-06 Thread Brandt Bucher
> but I think the desired semantics can all be achieved using only magic 
> methods on the objects themselves

Hm. So, just to clarify, you're suggesting we use `__copy__`, if it exists? 
Interesting...
___
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/ZEB2VAVPGWHL6B55UAMYYQRALLILGQLE/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-06 Thread Brandt Bucher
> It would create an exception of two rules:

I don't think these are "rules", I think they're just "the way things are".

If I'm subclassing `dict`, and I see in the docs something to the effect of:

> By default, `dict` subclasses will return `dict` objects for `|` operations. 
> To force the creation of a new instance of the subclass, users can override 
> the `copy` method. In that case, the return value from this method will be 
> used instead.

Then my life suddenly becomes a lot better, because chances are I've already 
thought to override `copy`. And if I want the "legacy" behavior, it's as simple 
as not bothering with "copy" (or, if I need to, overriding the `__or__` 
trio)... but I'm sure this is the less common case.

If we're quoting the Zen, then let's not elevate past design patterns to 
"rules". Besides, practicality beats purity. ;)
___
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/L5ODZ2TEEY2T53C5KB25WJPFGJAU7IIP/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-06 Thread Brandt Bucher
> I see this asymmetry between the | and |= mentioned a few times in the PEP, 
> but I don't see any rationale other than "the authors have decided".

I agree that this probably deserves to be addressed. I can't speak for Steven, 
but I know that my motivation here is to restrict `|` in order to avoid 
confusing casting. It suddenly becomes a very complicated problem with strange 
edge-cases as soon as reflected operations get involved. In contrast, `|=` 
appears in dramatically simpler contexts, so we don't need to worry about 
resolving all of the combinations of possible LHS and RHS types (or whether the 
user can keep up with what we're doing under-the-hood).

I have no idea if this is what motivated the decision in `list`, but I think 
it's a good one.

> The specification mentions "Dict union will return a new dict containing the 
> left operand merged with the right operand, which must be a dict (or an 
> instance of a dict subclass)." Can you clarify if it is part of the spec that 
> it will always return a dict even if one or both of the operands is a dict 
> subclass?

See my recent post on this here. I believe that we should call an overridden 
`lhs.copy()`, but others disagreed during code review. For what it's worth, 
it's probably not good for us to use "dict" and "`dict`" (with 
monospace/backticks) to mean different things in the PEP... ;)

> Unless there is compelling reason to do otherwise, I am in favor of trying to 
> retain subclass identity after operation.

I'll count you as a vote for `new = lhs.copy(); dict.update(new, rhs)`, then. ;)
___
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/MRYKAFWIJFODH7PBVH5CKPWAS2M26VFO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Clarification of unpacking semantics.

2020-02-06 Thread Brandt Bucher
> We should fix that (by reverting to 3.8.1 behaviour) before 3.8.2 gets 
> released.

The commits which changed the behavior were bytecode/compiler changes that only 
went to master. I don't think they are present on any other branches.
___
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/GC3PGIGXFY47RQVOA4HLE3VX5IQ2VGTB/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-06 Thread Brandt Bucher
One issue that's come up during PR review with Guido and Serhiy is, when 
evaluating `a | b`, whether or not the default implementation should call an 
overridden `copy()` method on `a` in order to create an instance of the correct 
subclass (rather than a plain-ol' `dict`). For example, `defaultdict` works 
correctly without any additional modification:

```
>>> from collections import defaultdict
>>> i = defaultdict(int, {1: 1, 2: 2})
>>> s = defaultdict(str, {2: "2", 3: "3"})
>>> i | s
defaultdict(, {1: 1, 2: '2', 3: '3'})
>>> s | i
defaultdict(, {2: 2, 3: '3', 1: 1})
```

So this has immediate benefits for both usability and maintenance: subclasses 
only need to override `copy()` to get working `__or__`/`__ror__` behavior. 
While this isn't what `list` and `set` do, for example, I argue that `dict` is 
more often subclassed, and we shouldn't blindly follow the precedent of their 
behavior when designing a new API for `dict`.

We decided to bring the discussion here to get input from a larger audience. 
I'm currently +0 on calling `copy()`, but I know Steven feels a bit more 
strongly about this than I do:

> I think the standard handling of subclasses in Python builtins is wrong, and 
> I don't wish to emulate that wrong behaviour without a really good reason. Or 
> at least a better reason than "other methods break subclassing unless 
> explicitly overloaded, so this should do so too". Or at least not without a 
> fight :-)

The more detailed thread of discussion starts at 
https://github.com/python/cpython/pull/12088#issuecomment-582609024 (note that 
we are no longer considering calling an overridden `update` method).
___
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/Z5SSGCH736UWHKFGJEZROH6VKPKXIT7W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Clarification of unpacking semantics.

2020-02-05 Thread Brandt Bucher
Commits 13bc139 and 8a4cd70 introduced subtle changes in the evaluation logic 
of unpacking operations. Previously, all elements were evaluated prior to being 
collected in a container. Now, these operations are interleaved. For example, 
the code `[*a, *b]` used to evaluate in the order `a` -> `b` -> `a.__iter__()` 
-> `b.__iter__()`. Now, it evaluates as `a` -> `a.__iter__()` -> `b` -> 
`b.__iter__()`.

I believe this breaking semantic change is a bug, and I've opened a PR to fix 
it (https://github.com/python/cpython/pull/18264). My reasoning is that "unary 
*" isn't an operator; it doesn't appear on the operator precedence table in the 
docs, and you can't evaluate `*x`. Like the brackets and the comma, it's part 
of the syntax of the outer display expression, not the inner one. It specifies 
how the list should be built, so it should be evaluated last, as part of the 
list construction. And it has always been this way since PEP 448 (as far as I 
can tell).

The docs themselves seem to support this line of reasoning 
(https://docs.python.org/3/reference/expressions.html#evaluation-order):

> In the following lines, expressions will be evaluated in the arithmetic order 
> of their suffixes:
> ...
> expr1(expr2, expr3, *expr4, **expr5)

Note that the stars are not part of expressions 1-5, but are a part of the 
top-level call expression that operates on them all.

Mark Shannon disagrees with me (I'll let him reply rather than attempt to 
summarize his argument for him), but we figured it might be better to get more 
input here on exactly whether you all think the behavior should change or not. 
You can see the discussion on the PR itself for some additional points and 
context.

Thanks!

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


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

2020-02-05 Thread Brandt Bucher
> I have one suggestion: Wouldn't it be useful for these operators to also 
> accept sets (functionally acting like a dict with None for all values)?

> Why None?  Why not 0, or False, or 42?  This sort of thing belongs more  in a 
> function or method, IMHO.

Well, in their defense, None is the null object in Python, so it would be a 
natural choice. With that said, I am strongly against this for several reasons:

- The proposal in its current form is very easy to wrap your head around: "|" 
takes dicts, "|=" takes anything dict.update does.
- Python doesn't allow sets to be dictionaries anywhere else. It's much more 
natural to use a dict like a set than to use a set like a dict. Hence, this PEP!
- A consistent argument that we've gotten since the very beginning is something 
to the effect of "I don't know what types are being used in the expression 'a | 
b'." While we argue that this isn't the issue in practice that people make it 
out to be, accepting sets here would definitely muddy the waters.

> This would make it very elegant to 'normalize' dicts by pruning (dict & set) 
> or padding (set | dict) dictionaries.

Well, if the PEP lands, the padding part is easy:

padded = dict.fromkeys(expected) | given

Or even better, just do the dict.fromkeys construction at module level once, 
and do:

padded = EXPECTED | given

Or, implement the behavior in a subclass if you truly need it to be a set! 
We're intentionally very subclass-friendly (unlike list, for example).
___
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/G3NWWUFR3SJECCXIAUGHNEJLSCBQBEVG/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-04 Thread Brandt Bucher
It already has a PR open against master, with all tests passing:

https://github.com/python/cpython/pull/12088

Sorry about the messy history - this proposal has changed significantly several 
times over the past year (at least as far as the implementation is concerned). 
At one point, both operators were implemented for comparison with each other!
___
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/6DVUQ45EFTX3G5GF6SOZCYZK62GYFQ7V/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2020-02-04 Thread Brandt Bucher
Steven D'Aprano and I have pushed a third draft of PEP 584:

https://www.python.org/dev/peps/pep-0584/

The accompanying reference implementation is on GitHub:

https://github.com/brandtbucher/cpython/tree/addiction

For those who have been following the discussions over the past year on 
python-ideas, this new draft does not contain much additional content; the most 
notable difference is that the choice of operator has been changed from + to |. 
The rest of the revisions are mostly reformatting and reorganizing the 
information to bring the document in line with PEP standards.

Please let us know what you think – we'd love to hear any *new* feedback that 
hasn't yet been addressed in the PEP or the related discussions it links to!

Thanks!

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


[Python-Dev] Re: Should set objects maintain insertion order too?

2019-12-27 Thread Brandt Bucher
> On Dec 27, 2019, at 19:48, Tim Peters  wrote:
> 
> So, ya, I've seen and implemented lots of work queues along these
> lines - but an OrderedSet would be an "attractive nuisance"
> (offhandedly appearing to solve a problem it doesn't actually
> address):
> 
>  jobs = some_kind_of_queue()
>  finished_jobs = set()
>  ...
>  while jobs:
>  job = jobs.get()
>  if job in finished_jobs:
>  continue
>  try:
>  work on the job
>  possibly adding (sub)jobs to the `jobs` queue
>  except TransientExceptions:
>  jobs.put(job)  # try again later
>  else:
>  finished_jobs.add(job)

Well, if an OrderedSet were designed to gracefully handle resizes during 
iteration, something like this may make sense:

jobs = OrderedSet(initial_jobs)
for job in jobs:
  new_jobs = process(job)
  jobs |= new_jobs
... # jobs is now a set of every job processed

A dictionary with None values comes close if you replace the union line with a 
jobs.update(new_jobs) call (and ignore resizing issues), but it breaks because 
repeated jobs are shuffled to the end of the sequence and would be processed 
again.

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


[Python-Dev] Re: Helpers for dynamic bytecode generation

2019-10-25 Thread Brandt Bucher
Interesting that you bring this up. Just earlier this week I published the 
first version of a new package that lets you write compiled bytecode 
instructions inline with pure-Python syntax. The code's still a bit messy, 
being only a week old and all, but it works as advertised for CPython 3.6.2 
through 3.9.0a0, and even includes neat features like labeled jumps, unused 
name/constant removal, stack size adjustments, etc... Perhaps it'll be useful 
to you (or at least you'll find it interesting): 
https://github.com/brandtbucher/hax

Victor's Stinner's Bytecode package (already mentioned) is surely better for 
*dynamic* generation... I've never used it personally, but it looks great.

Definitely not for the faint of heart, though! ;)

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


[Python-Dev] Re: 4 first-time contributions that need core review.

2019-10-23 Thread Brandt Bucher
Thanks everybody for the quick response! These all now have core review (from 
Steering Council members, no less)!
___
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/NTOCTGY2XR6AMGAPTUGA5CFM5LCFBZUS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] 4 first-time contributions that need core review.

2019-10-22 Thread Brandt Bucher
Hi all. There are a few *very simple* PRs from first-time contributors that 
have been sitting un-core-reviewed for several weeks.

https://github.com/python/cpython/pull/16680: bpo-38419: fix "check-c-globals" 
path
https://github.com/python/cpython/pull/16678: bpo-38421: Update email.utils 
documentation
https://github.com/python/cpython/pull/16557: bpo-38361: syslog: fixed making 
default "ident" from sys.argv[0]
https://github.com/python/cpython/pull/16438: bpo-38293: Allow shallow and deep 
copying of property objects

I've reviewed them and they look good. If somebody has a small bit of time to 
look at these, I'm sure the authors would appreciate it!
___
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/BT5QELS56DHDXUPQVU6NFBFXB3EAXHJ2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: EnHackathon 2019 - seeking core dev support

2019-10-22 Thread Brandt Bucher
Hi Lewis.

I'm in the Pacific time zone. Barring any surprises (I'm getting married late 
next month), I can commit to being online in the morning (the last few hours of 
your business day), as well as during my normal business hours (late 
evening/night for you). Just tag "@brandtbucher" on any PRs you'd like reviewed.

You can also tag or email me directly with any questions you have. It would 
also help if you could nosy "brandtbucher" on any bpo issues you plan on 
working on.

Looking forward to getting some new contributors!

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


[Python-Dev] Re: EnHackathon 2019 - seeking core dev support

2019-10-20 Thread Brandt Bucher
Hi Lewis.

I'm a trigger (not a core developer), but I'd be happy to make myself available 
during that time for expedited PR reviews. Ideally, the core review / merge 
stage would be your only bottleneck then.

I'm a bit busy next month though, so do you know the actual dates / time / time 
zones you plan to be working in? Also, are there any specific issues you have 
identified that you want to work on within your stated areas of interest? If 
so, I can do some homework before in order to speed up the reviews.

I'd recommend that all PR authors review the contributing section of the 
developers guide beforehand:
https://devguide.python.org/pullrequest

Specifically, make sure that every contributor has signed the CLA at least a 
couple of business days before (it's often the longest blocker for first-time 
contributions):
https://devguide.python.org/pullrequest/#licensing

Looking forward to your help!

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


[Python-Dev] Re: Migrate typing in builtin

2019-10-08 Thread Brandt Bucher
I’m a bit confused. For my own understanding: what’s stopping 
PyObject_IsInstance/PyObject_IsSubclass from just trying 
PyImport_GetModule("typing") here?

If NULL, carry on. Otherwise, check the Union case.

Brandt

> On Oct 8, 2019, at 05:44, Philippe Prados  wrote:
> 
> 
> Glups.
> 
> I am not an expert of Pyhton source code. May be after this patch ;-)
> 
> I think I should discuss with the authors of the module typing, to identify 
> the best strategy.
> Who is he ?
> 
> Philippe
> 
> 
>> Le mar. 8 oct. 2019 à 10:19, Ivan Levkivskyi  a écrit :
>> You will need to rewrite most of things in C.
>> 
>> --
>> Ivan
>> 
>> 
>>> On Tue 8 Oct 2019, 08:53 Philippe Prados,  wrote:
>>> Ok, 
>>> 
>>> But _GenericAlias and dependencies are written with Python (Lib/typing.py), 
>>> not with C.
>>> So, I must rewrite the _GenericAlias in C or it's possible to merge the C 
>>> and Python in builtin and add a direct reference to _GenericAlias with C, 
>>> and add the reference in builtin module ?
>>> 
>>> Philippe
>>> 
>>> 
 Le lun. 7 oct. 2019 à 22:58, Random832  a écrit :
 On Mon, Oct 7, 2019, at 12:02, Philippe Prados wrote:
 > Because this PEP propose to accept, for all classes
 > assert isinstance("", int | str)
 > assert issubclass(int, int | str)
 > and add an operator __or__() for type type.
 > def f(list: List[int | str], param: int | None) -> float | str:
 > pass
 
 Oh, sorry, I didn't realize that this also included the | operator, I 
 thought this was just for isinstance("", Union[int, str]).
>>> ___
>>> 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/GD7WXPD26VUPMZT6WAATCJJBB42DDYYQ/
>>> 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/4K7WZ3RBGG7K6E6XK65MS44VQYZIKQS2/
> 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/RYGHVWJZT76GNDWNRSOLA74SHZFNDW42/
Code of Conduct: http://python.org/psf/codeofconduct/