Bug report
Bug description:
For my Python compiler Nuitka, I use CPython as the oracle of what the correct behaviour is. I am running some tests that I used to clarify the behavior from decades ago, in this case I wanted to know when exactly the iterator creation is used. I striped this test a bunch, so the regression is still visible. I first noticed the issue on GitHub Actions, where 3.13.0 got replaced with 3.13.1 for Windows and Linux, but it applies to all OSes. See below for a diff, that the same iterator is created multiple times.
""" Generator expression tests"""from __future__ importprint_functionimportinspectprint("Generator expression that demonstrates the timing:")
defiteratorCreationTiming():
defgetIterable(x):
print("Getting iterable", x)
returnIterable(x)
classIterable:
def__init__(self, x):
self.x=x# pylint: disable=invalid-nameself.values=list(range(x))
self.count=0def__iter__(self):
print("Giving iterator now", self.x)
returnselfdef__next__(self):
print("Next of", self.x, "is", self.count)
iflen(self.values) >self.count:
self.count+=1returnself.values[self.count-1]
else:
print("Raising StopIteration for", self.x)
raiseStopIteration# Python2/3 compatibility.next=__next__def__del__(self):
print("Deleting", self.x)
gen= ((y, z) foryingetIterable(3) forzingetIterable(2))
print("next value is", next(gen))
res=tuple(gen)
print("remaining generator is", res)
try:
next(gen)
exceptStopIteration:
print("Usage past end gave StopIteration exception as expected.")
try:
print("Generator state then is", inspect.getgeneratorstate(gen))
exceptAttributeError:
passprint("Its frame is now", gen.gi_frame)
print("Early aborting generator:")
gen2= ((y, z) foryingetIterable(3) forzingetIterable(2))
delgen2iteratorCreationTiming()The unified diff between 3.13.0 output (and basically all Python versions before) and 3.13.1 output.
--- out-3.13.0.txt 2024-12-06 12:37:19.447115100 +0100
+++ out-3.13.1.txt 2024-12-06 12:37:23.452239500 +0100
@@ -1,9 +1,11 @@
Generator expression that demonstrates the timing:
Getting iterable 3
Giving iterator now 3
+Giving iterator now 3
Next of 3 is 0
Getting iterable 2
Giving iterator now 2
+Giving iterator now 2
Next of 2 is 0
next value is (0, 0)
Next of 2 is 1
@@ -13,6 +15,7 @@
Next of 3 is 1
Getting iterable 2
Giving iterator now 2
+Giving iterator now 2
Next of 2 is 0
Next of 2 is 1
Next of 2 is 2
@@ -21,6 +24,7 @@
Next of 3 is 2
Getting iterable 2
Giving iterator now 2
+Giving iterator now 2
Next of 2 is 0
The duplicated prints out the iterator creation are new. This is not optimal and new. I don't know if the iterator being through a slot cause cause this or what it is. I checked if generator.c changed but I think it didn't at all.
My self compiled Python 3.13.1 for Linux and the official Windows download agree in behaviour.
CPython versions tested on:
3.13
Operating systems tested on:
Linux, Windows
Linked PRs
Bug report
Bug description:
For my Python compiler Nuitka, I use CPython as the oracle of what the correct behaviour is. I am running some tests that I used to clarify the behavior from decades ago, in this case I wanted to know when exactly the iterator creation is used. I striped this test a bunch, so the regression is still visible. I first noticed the issue on GitHub Actions, where 3.13.0 got replaced with 3.13.1 for Windows and Linux, but it applies to all OSes. See below for a diff, that the same iterator is created multiple times.
The unified diff between 3.13.0 output (and basically all Python versions before) and 3.13.1 output.
The duplicated prints out the iterator creation are new. This is not optimal and new. I don't know if the iterator being through a slot cause cause this or what it is. I checked if
generator.cchanged but I think it didn't at all.My self compiled Python 3.13.1 for Linux and the official Windows download agree in behaviour.
CPython versions tested on:
3.13
Operating systems tested on:
Linux, Windows
Linked PRs
__iter__once in generator expressions. #132351