php / php/php-src

Inconsistent behaviour with AppendIterator and empty generators

Offen
#11,591 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Category: Generators Extension: spl Status: Verified
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

I've encountered inconsistent behaviour in the handling of empty generators with AppendIterator. Please can you confirm whether this is a bug or some weird expected behaviour.

Scenario 1

When iterating over a generator that yields nothing, foreach has no items to iterate over so var_dump isn't called, as expected.

<?php

function yieldEmpty()
{
    yield from [];
}

foreach (yieldEmpty() as $item) {
    var_dump($item);
}

Scenario 2

When attaching a generator yielding items and a generator yielding nothing and attaching both to an AppendIterator, foreach iterates over the items from the former and the three values are output, as expected.

<?php

function yieldRows()
{
    yield from ['one', 'two', 'three'];
}

function yieldEmpty()
{
    yield from [];
}

$iterator = new AppendIterator();
$iterator->append(yieldRows());
$iterator->append(yieldEmpty());

foreach ($iterator as $item) {
    var_dump($item);
}

Outputs (as expected):

string(3) "one"
string(3) "two"
string(5) "three"

Scenario 3

When attaching ONLY a generator yielding nothing and attaching it to an AppendIterator, foreach unexpectedly fails with an exception.

<?php

function yieldEmpty()
{
    yield from [];
}

$iterator = new AppendIterator();
$iterator->append(yieldEmpty());

foreach ($iterator as $item) {
    var_dump($item);
}

Expected output (following on from scenario 1 and 2):

string(3) "one"
string(3) "two"
string(5) "three"

Actual output:

PHP Fatal error:  Uncaught Exception: Cannot traverse an already closed generator in /Users/richard.coupland/test3.php:11
Stack trace:
#0 /Users/richard.coupland/test3.php(11): AppendIterator->rewind()
#1 {main}
  thrown in /Users/richard.coupland/test3.php on line 11

Fatal error: Uncaught Exception: Cannot traverse an already closed generator in /Users/richard.coupland/test3.php:11
Stack trace:
#0 /Users/richard.coupland/test3.php(11): AppendIterator->rewind()
#1 {main}
  thrown in /Users/richard.coupland/test3.php on line 11
PHP Version

8.2.7

Operating System

No response

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie damit, die drei AppendIterator-Szenarien mit den Generatoren yieldEmpty und yieldRows unter PHP 8.2.7 zu reproduzieren, wobei Sie sich auf den Fehler während foreach und AppendIterator->rewind() konzentrieren. Ermitteln Sie, ob das unterschiedliche Verhalten beabsichtigt ist oder einen Fehler darstellt, und fügen Sie anschließend Regressionstests hinzu oder aktualisieren Sie diese, sodass der Fall des leeren Generators ein definiertes, erfolgreiches Verhalten aufweist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
php
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
55/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.