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 independent implementation, a different interface, lives in 
a separate namespace, and doesn't even reference zip in its documentation. So 
it seems to me that it is indeed another beast entirely.

> > so it makes sense that it would live in itertools while zip grows in-place.
> No, it doesn't

See above for why I think it does.

> > 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.
> Importing necessary functions is not an anti-pattern.

Um, agreed?

> > Another proposed idiom, per-module shadowing of the built-in zip with some 
> > subtly different variant from itertools, is an anti-pattern that shouldn't 
> > be encouraged.
> Source?

Point taken. I probably went a bit far labeling this a straight-up 
"anti-pattern", but it is certainly annoying to find that someone has added 
`from pprint import pprint as print` at the top of a module, for example (which 
has actually happened to me before).  Very hard to figure out what's happening.

> > It's not obvious which one will succeed, or how the other will fail. If 
> > zip.strict is implemented as a method, zm will succeed, but zd will fail in 
> > one of several confusing ways:
> How is this any different from calling zip the wrong way?

Because there are now twice as many ways to get it wrong, no matter how it's 
spelled. And in either case, we now have a brand new class of silently wrong 
results.

> > This proposal is further complicated by the fact that CPython's actual zip 
> > type is an undocumented implementation detail.
> That actually gives us complete freedom to redesign as long we keep the API 
> backward-compatible.

I should have phrased this line better. My point wasn't that we don't currently 
have the freedom to do whatever we want with the implementation, it was that 
making a decision like method/classmethod/staticmethod pretty much locks us 
into a particular implementation going forward. I'll make that clearer here.

Rhodri James wrote:
> But zip_equals() is also another beast entirely; it takes on the 
> responsibility of raising an exception, a problem neither of the other 
> variants even have.

Would you consider `os.makedirs(...)` and `os.makedirs(..., exist_ok=True)` to 
be entirely different beasts? I certainly don't.

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

Reply via email to