`break` / `continue`: escapes as `BreakSignal` from a `for` loop, silently drops the iteration body in a `while` loop
Los mantenedores suelen responder en 1 día
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Limitation
Breaking and continuing loops
defines break and continue inside both for and while bodies. pyqasm implements them
as internal control-flow exceptions, and both loop visitors mishandle them — in two different
ways, from one shared root cause.
forloops: no handler at all. The signal propagates out ofvalidate()/unroll()
to the caller asBreakSignal/ContinueSignal— internal types that are not
ValidationErrorand are not part of the public API.whileloops: a handler exists, but it discards every statement of the iteration in
which thebreakoccurred. The gates executed before thebreakvanish from the unrolled
program with no error raised.
The second is the more dangerous of the two: it is silent wrong output.
Example QASM failure
for — internal signal escapes
import pyqasm
m = pyqasm.loads('''
OPENQASM 3.0;
for int i in [0:3] {
break;
}
''')
m.validate()
pyqasm.exceptions.BreakSignal: None
Same for continue, and for the common nested-in-a-branch form:
OPENQASM 3.0;
for int i in [0:3] { continue; } // ContinueSignal: None
OPENQASM 3.0;
for int i in [0:3] { if (i == 1) { break; } } // BreakSignal: None
while — silent loss of the iteration body
OPENQASM 3.0;
include "stdgates.inc";
qubit[1] q;
int[8] i = 0;
while (i < 3) { h q[0]; i += 1; break; }
>>> m = pyqasm.loads(qasm); m.unroll(); print(pyqasm.dumps(m))
OPENQASM 3.0;
include "stdgates.inc";
qubit[1] q;
The h q[0] executed before the break is gone, and depth() reports 0. Expected output is
a single h q[0].
The same while loop without the break unrolls correctly to three h q[0], which
confirms the loss is caused by the signal handling and not by while-loop unrolling in general.
Change Requested
forloop unrolling must catch both signals.continueabandons the rest of the current
iteration and proceeds to the next value;breakabandons the rest of the current
iteration and stops iterating.- Both loops must retain the statements already emitted in the interrupted iteration.
Only the statements after thebreak/continueare skipped. - Neither signal type may be observable from
validate(),unroll(), or any other public
entry point.
Implementation Details
-
_visit_while_loop(src/pyqasm/visitor.py:2700) has the handler atvisitor.py:2739:try: result.extend(self.visit_basic_block(statement.block)) except LoopControlSignal as lcs: ...visit_basic_blockraises from inside the call, so it never returns andresult.extend
never runs — the whole iteration's output is discarded. That is the silent-drop bug. -
_visit_forin_loop(src/pyqasm/visitor.py:2432) has notry/exceptaround its
result.extend(self.visit_basic_block(...))calls atvisitor.py:2500, so the signal
escapes. -
The shared fix is in
visit_basic_block, not in either loop. It must be able to hand
back the statements it produced before the signal was raised. Two workable shapes:
attach the partial result to the signal object (lcs.partial_result), or have
visit_basic_blockreturn(statements, signal_or_None)instead of raising. The second is
cleaner but touches every caller. -
LoopControlSignalalready exists as a common base insrc/pyqasm/exceptions.py:59, so a
singleexceptclause covers both signals — no new exception types are needed. -
Minor, in the same file:
ContinueSignal.__init__ignores itsmsgargument and always
passes the literal"continue"tosuper(), and neither signal callsException.__init__
with a message — which is why the escaping error prints asBreakSignal: None. Worth
tidying while here. -
Check the same handling inside a
switchcasebody, which is another block-scoped
statement list that can legally containbreak. -
Tests:
tests/qasm3/test_loop.py—break/continuedirectly in aforbody, nested one
and twoiflevels deep, inside a nestedfor, thewhile+breakcase above asserting the
pre-breakgate survives, and an assertion that the unrolled gate sequence matches the
truncated iteration count.
- Lenguaje dominante
- Python
- Estrellas
- 29
- Forks
- 33
- Merge medio
- 2 d 4 h
- PR fusionados (30 d)
- 15
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de qBraid/pyqasm
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 63/100
Los mantenedores suelen responder en 1 día
-
enhancement error-handling program-validation
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día
-
Move the QASM 2 printer and its branch pre-processing out of qasm2.pyPosiblemente ocupada @danielgaskins la tomó hace 10 días. Abiertoenhancement qasm2
Dificultad 4/5 3-5 días Aptitud para principiantes 22/100
qBraid/pyqasm#447 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
[BUG] dumps() emits extern calls without a semicolon, producing unparsable QASMPosiblemente ocupada @Jah-yee la tomó hace 18 días. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 25/100
qBraid/pyqasm#438 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Parse failures raise ValidationError with an empty message; the ANTLR diagnostic is lostPosiblemente ocupada @tonycoder-hub la tomó hace 11 días. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 22/100
qBraid/pyqasm#436 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de qBraid/pyqasm
Issues similares
-
good first issue infrastructure
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
kuznia-rdzeni/coreblocks#1135 ·
-
good first issue server
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
Los mantenedores suelen responder en 1 día
-
documentation priority: high
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
a-lex-s/mealie-telegram-bot#54 ·
Los mantenedores suelen responder en 1 día
-
type/test
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
SaltedTan/virgil-language-server#218 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
btclib-org/btclib-wallet#541 ·
Los mantenedores suelen responder en 1 día