> I'm pretty sure it can be made to work (at least for CPython). The > proposed patch is not correct since it doesn't handle "finally" code > that creates a new reference to the generator. As Oren pointed out, how can you create a reference to the generator when its reference count was 0? There can't be a global referencing it, and (unlike __del__) you aren't getting a pointer to yourself. > Also, setting the instruction pointer to the return statement is > really ugly, IMO. Agreed. ;-) > There could be valid code out there that does not end with > LOAD_CONST+RETURN. The current code generator always generates that as the final instruction. But someone might add an optimizer that takes that out if it is provably unreachable... > Those are minor details though. We need to decide if we really want > this. For example, what happens if 'yield' is inside the finally block? > With the proposed patch: > > >>> def f(): > ... try: > ... assert 0 > ... finally: > ... return 1 > ... > >>> f() > 1 > >>> def g(): > ... try: > ... assert 0 > ... finally: > ... yield 1 > ... > >>> list(g()) > Traceback (most recent call last): > File "<stdin>", line 1, in ? > File "<stdin>", line 3, in g > AssertionError > > Maybe some people whould expect [1] in the second case. The latter is not new; that example has no yield in the try clause. If you'd used a for loop or next() calls, you'd have noticed the yield got executed normally, but following next() call raises AssertionError. But this example behaves strangely: >>> def f(): ... try: ... yield 1 ... assert 0 ... finally: ... yield 2 ... >>> a = f() >>> a.next() 1 >>> del a >>> What happens at the yield here?!?! If I put prints before and after it, the finally clause is entered, but not exited. Bizarre!!! --Guido van Rossum (home page: http://www.python.org/~guido/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4