On Sun, Apr 26, 2020 at 04:13:27PM -0700, Andrew Barnert via Python-ideas wrote:
But if we add methods on zip objects, and then we add a new skip() method in 3.10, how does the backport work? It can’t monkeypatch the zip type (unless we both make the type public and specifically design it to be monkeypatchable, which C builtins usually aren’t).
Depends on how you define monkey-patching. I'm not saying this because I see the need for a plethora of methods on zip (on the contrary); but I do like the methods-on-function API, like itertools.chain has. Functions are namespaces, and we under-utilise that fact in our APIs. Namespaces are one honking great idea -- let's do more of those! Here is a sketch of how you might do it: # Untested. class MyZipBackport(): real_zip = builtins.zip def __call__(self, *args): return self.real_zip(*args) def __getattr__(self, name): # Delegation is another under-utilised technique. return getattr(self.real_zip, name) def skip(self, *args): # insert implementation here... builtins.zip = MyZipBackport() I don't know what "zip.skip" is supposed to do, but I predict that (like all the other variants we have discussed) it will end up being a small wrapper around zip_longest.
So more-itertools or zip310 or whatever has to provide a full implementation of the zip type, with all of its methods, and probably twice (in Python for other implementations plus a C accelerator for CPython). Sure, maybe it could delegate to a real zip object for the methods that are already there, but that’s still not trivial (and adds a performance cost).
I dunno, a two-line method (including the `def` signature line) seems pretty trivial to me. Nobody has established that *any* use of zip_whatever is performance critical. In what sort of real-world code is the bottleneck going to be the performance of zip_whatever *itself* rather than the work done on the zipped up tuples? I don't especially want zip_whatever to be slow, but the stdlib has no obligation to provide a super-fast highly optimized C accelerated version of **everything**. Especially not backports. It is perfectly acceptable to say: "Here's a functionally equivalent version that works in Python 3.old, if you want speed then provide your own C version or upgrade to 3.new"
Also, what exactly do these methods return?
An iterator. What kind of iterator is an implementation detail. The type of the zip objects is not part of the public API, only the functional behaviour. -- Steven