Bug #71980 [NEW]: Decorated/Nested Generator is Uncloseable in Finally

From: Date: Wed, 06 Apr 2016 19:30:27 +0000
Subject: Bug #71980 [NEW]: Decorated/Nested Generator is Uncloseable in Finally
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-200399@lists.php.net to get a copy of this message
From: php at fleshgrinder dot com Operating system: PHP version: Irrelevant Package: Scripting Engine problem Bug Type: Bug Bug description:Decorated/Nested Generator is Uncloseable in Finally Description: ------------ The finally block of a Generator that is decorated with or nested in another Generator is never called. This behavior is of course true for multiple decoration or nesting levels. Using a finally block for clean-up in case a Generator is aborted is the official and only way of doing so. It is also recommended in the initial RFC: https://wiki.php.net/rfc/generators#closing_a_generator Please see attached test script as well as expected and actual result. Test script: --------------- #!/usr/bin/env php <?php function generator() { try { while (true) { yield 'Hello'; } } finally { echo "Generator Clean-up\n"; } } function generator_decoration() { try { foreach (generator() as $word) { yield $word . " World!\n"; } } finally { echo "Decorator Clean-up\n"; } } foreach (generator_decoration() as $sentence) { echo $sentence . "Break\n"; break; } echo "Shutdown\n"; Expected result: ---------------- Hello World! Break Decorator Clean-up Generator Clean-up Shutdown Actual result: -------------- Hello World! Break Decorator Clean-up Shutdown Generator Clean-up Workaround: ---------------- In case a frustrated user is finding this bug report. There is a possible workaround that works in all PHP versions that support Generators via a signal that is being sent to the Generator. Please have a look at the following example that makes use of it. #!/usr/bin/env php <?php const GENERATOR_BREAK = 'PHP_GENERATOR_BREAK'; function generator() { try { while (true) { if ((yield 'Hello') === GENERATOR_BREAK) { break; } } } finally { echo "Generator Clean-up\n"; } } function generator_decoration() { $generator = generator(); try { foreach ($generator as $word) { yield $word . " World!\n"; } } finally { echo "Decorator Clean-up\n"; $generator->send(GENERATOR_BREAK); } } foreach (generator_decoration() as $sentence) { echo $sentence . "Break\n"; break; } echo "Shutdown\n"; -- Edit bug report at https://bugs.php.net/bug.php?id=71980&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=71980&r=trysnapshot54 Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=71980&r=trysnapshot55 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=71980&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=71980&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=71980&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=71980&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=71980&r=needscript Try newer version: https://bugs.php.net/fix.php?id=71980&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=71980&r=support Expected behavior: https://bugs.php.net/fix.php?id=71980&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=71980&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=71980&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=71980&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=71980&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=71980&r=dst IIS Stability: https://bugs.php.net/fix.php?id=71980&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=71980&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=71980&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=71980&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=71980&r=mysqlcfg

« previous php.bugs (#200399) next »