From 61150b3a054e1b0d0a0722a38409253f52919d84 Mon Sep 17 00:00:00 2001 From: TheGupta2012 Date: Tue, 18 Aug 2026 11:28:11 +0530 Subject: [PATCH] docs: reset the changelog after the v1.1.0 release [no ci] v1.1.0 shipped every entry that was sitting under Unreleased, so the section now describes work that is already released. Empty each Unreleased subsection and add the v1.1.0 archive link, so the next cycle starts from a clean slate. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f917f8..7b88193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,39 +15,16 @@ Types of changes: ## Unreleased ### Added -- Added support for `#pragma` statements, which previously raised `ValidationError: Unsupported statement of type ` and blocked any program carrying one. Pragmas are now passed through `loads`/`validate`/`unroll`/`dumps` unchanged, and are printed in their `#pragma` form (the upstream printer emits the bare `pragma` keyword). A `#pragma braket verbatim` additionally marks the `box` that immediately follows it: gates inside a verbatim box are emitted as written instead of being decomposed, so verbatim submissions to Braket QPUs keep the native gates they were built with. ([#341](https://github.com/qBraid/pyqasm/pull/341)) ### Improved / Modified -- Added / updated type hinting for `base.py`, `qasm2.py`, `qasm3.py`, and `visitor.py` signatures, plus the `visit_statement` / `visit_basic_block` signatures in `pulse/visitor.py`. Fixed grammatical typos in `base.py`, `qasm2.py`, `qasm3.py`, and `visitor.py` docstrings. Fixes incorrect return types in the docstrings of `visitor.py`. ([#346](https://github.com/qBraid/pyqasm/pull/346)) -- Added / updated type hinting for `pulse/visitor.py` signatures and fixes incorrect return types in the docstrings of `pulse/visitor.py`. ([#365](https://github.com/qBraid/pyqasm/pull/365)) -- **Breaking:** `loads()` and `load()` now raise `TypeError` on an unrecognised keyword argument instead of silently ignoring it, so a misspelling like `loads(src, devise_qubits=5)` fails at the call site rather than being dropped. Any caller currently passing a stray or misspelled kwarg will break on upgrade. ([#356](https://github.com/qBraid/pyqasm/issues/356)) ### Deprecated ### Removed ### Fixed -- Fixed `loads()` silently discarding a falsy kwarg value. The seven documented kwargs were stored behind a walrus truthiness test, so a caller value of `0`, `0.0`, `False`, `{}` or `[]` was treated as though the kwarg had never been passed. Each kwarg is now tested for presence, with an explicit `None` still meaning "not passed". What that changes per kwarg: `extern_functions={}` / `[]` is now stored rather than dropped; a non-positive `device_qubits` / `device_cycle_time` / `compiler_angle_type_size` / `frame_limit_per_port` is now **rejected** with a `ValueError` at the call site rather than silently dropped, along with a non-numeric or `bool` value (`TypeError`); and `frame_in_def_cal=None` / `play_in_cal_block=None` now mean "not passed" — previously an explicit `None` was stored and read as falsy, so passing `None` disabled the check that the `True` default enables. Pass `False` for the old `None` behaviour. ([#356](https://github.com/qBraid/pyqasm/issues/356)) -- Fixed `unroll(consolidate_qubits=True)` emitting two unrelated address spaces for a program mixing declared registers with physical qubits — a consolidated register plus as-written `$n` references. Such programs now raise a `ValidationError` naming the physical qubits, and a program using only physical qubits no longer receives an internal register declaration nothing references. ([#353](https://github.com/qBraid/pyqasm/issues/353)) -- Fixed external and verbatim-box gates counting the depth of the decomposition they skipped: `unroll(external_gates=["crz"])` on a single `crz` reported `depth() == 12` while emitting one statement. An external gate now records its own depth, matching how a single-level external custom gate is already handled. ([#352](https://github.com/qBraid/pyqasm/issues/352)) -- Fixed `has_measurements()` / `remove_measurements()` and `has_barriers()` / `remove_barriers()` missing occurrences inside `for` / `while` / `switch` bodies on a module that has not been unrolled — e.g. a measurement inside a `for` loop was invisible and `remove_measurements()` was a no-op. The statement walker now descends into loop and switch bodies. ([#354](https://github.com/qBraid/pyqasm/issues/354)) -- Fixed unrolling of `rzz`/`rxx` in an OpenQASM 2 program emitting an invalid `gphase(...)` statement — syntax QASM 2 does not have — so the output was not a loadable QASM 2 program. Global phase is unobservable, so unroll-emitted phases are now dropped for a QASM 2 target; a user-written `gphase` is still rejected. A conditional left with no body by the drop is removed too, since QASM 2 has no form for an `if` without a `qop`. ([#351](https://github.com/qBraid/pyqasm/issues/351)) -- Fixed the `negctrl @` expansion emitting the same `x` `QuantumGate` object at both the leading and trailing position, so in-place transformations mutated its operands twice — crashing `reverse_qubit_order()` (`KeyError`) and `unroll(consolidate_qubits=True)` (`KeyError: '__PYQASM_QUBITS__'`) on any unrolled `negctrl` gate. The two `x` gates are now distinct statements with fresh operand nodes. ([#350](https://github.com/qBraid/pyqasm/issues/350)) -- Fixed inaccurate `device_qubits` entry in `QasmModule.unroll()` docstring ([#349](https://github.com/qBraid/pyqasm/pull/349)) -- Fixed `remove_idle_qubits()` and `reverse_qubit_order()` ignoring statements nested inside `box` and `if` blocks. Top-level operands were rewritten while nested ones kept their old indices, so the result silently addressed the wrong qubits — and when a nested index fell outside the shrunken register, the output was not a loadable program at all. Both passes now walk nested bodies, as do `has_measurements()` / `remove_measurements()` and `has_barriers()` / `remove_barriers()`; a box left empty by a removal is dropped, since pyqasm rejects a box with no statements. Two consequences of the same blind spot are fixed alongside: a qubit operated on only inside an `if` block no longer counts as idle, and `remove_idle_qubits()` no longer raises `AssertionError` on a program that mixes physical qubits with declared registers. ([#345](https://github.com/qBraid/pyqasm/pull/345)) -- Fixed `unroll(consolidate_qubits=True)` raising `AttributeError: 'str' object has no attribute 'name'` for any gate applied to a physical qubit, e.g. `h $1;`. Consolidation assumed every gate operand was an `IndexedIdentifier`, but a physical qubit survives unrolling as `Identifier("$1")`. Physical qubits are absolute hardware indices belonging to no declared register, so they are now left as written — matching how `measure`, `reset` and `barrier` already treat them. ([#344](https://github.com/qBraid/pyqasm/pull/344)) -- Fixed `unroll()` and `rebase()` emitting statements that share operand AST nodes: gate decompositions passed the same `IndexedIdentifier` objects into every statement they emitted, so transformations that rewrite qubit indices in place mutated a shared node once per referencing statement. This crashed `reverse_qubit_order()` (`KeyError: -1`) and `remove_idle_qubits()` (`KeyError`, [#331](https://github.com/qBraid/pyqasm/issues/331)) on any decomposed gate (e.g. `crz`) whenever the remap was not the identity. Statement constructors in `maps/gates.py` and `Decomposer` now copy their qubit operands so every emitted statement owns its nodes. ([#333](https://github.com/qBraid/pyqasm/issues/333)) -- Fixed statements that OpenQASM 2 cannot condition being accepted as the body of a classical conditional. The QASM 2 grammar admits only a `` — a gate application, a measurement or a reset — as the body of an `if`. `barrier` is a separate production, and `delay`/`box` have no QASM 2 syntax at all, yet `if(m==1) barrier q;`, `if(m==1) delay[10ns] q;` and `if(m==1) box {...}` all validated and were emitted unchanged, producing output that QASM 2 parsers reject. Conditional bodies are now filtered against the `` whitelist at any nesting depth, raising a `ValidationError` that names the offending keyword and its source span. ([#339](https://github.com/qBraid/pyqasm/pull/339)) -- Fixed `remove_idle_qubits(in_place=False)` updating the qubit count on the wrong module: the original module's `num_qubits` was decremented while the returned copy kept the stale pre-removal count. The copy's AST was already correct; only the counters were swapped. ([#336](https://github.com/qBraid/pyqasm/pull/336)) -- Fixed `remove_idle_qubits()` raising `KeyError` when the unrolled AST contains operand nodes shared across multiple statements (e.g. the `crz` decomposition) and an idle lower-indexed qubit shifts the register indices. `_remap_qubits` now remaps each operand node exactly once instead of once per statement that references it. ([#332](https://github.com/qBraid/pyqasm/pull/332)) -- Fixed `box` duration validation summing `delay` durations across all qubits instead of tracking each qubit's timeline. Delays on disjoint qubits run in parallel, so `box[300ns] { delay[200ns] q[0]; delay[200ns] q[1]; }` was rejected while the identical schedule written as a broadcast delay (`delay[200ns] q;`) was accepted. Delays are now accumulated per qubit and the box is validated against the busiest single timeline; the error message names the offending qubit. Nested boxes now also contribute their declared duration to the enclosing box's timelines (previously the accumulator was reset when an inner box closed, dropping all inner delay accounting). ([#330](https://github.com/qBraid/pyqasm/pull/330)) ### Dependencies -- Updated `docutils` requirement from `<0.23` to `<0.24`. ([#319](https://github.com/qBraid/pyqasm/pull/319)) -- Bumped `codecov/codecov-action` from 6.0.0 to 7.0.0. ([#321](https://github.com/qBraid/pyqasm/pull/321)) -- Bumped `actions/checkout` from 6 to 7. ([#323](https://github.com/qBraid/pyqasm/pull/323)) -- Updated `pillow` requirement from `<12.3.0` to `<12.4.0`. ([#324](https://github.com/qBraid/pyqasm/pull/324)) -- Bumped `actions/setup-python` from 6 to 7. ([#328](https://github.com/qBraid/pyqasm/pull/328)) ### Other @@ -55,6 +32,7 @@ Types of changes: Archive of changelog entries from previous releases: +- [v1.1.0](https://github.com/qBraid/pyqasm/releases/tag/v1.1.0) - [v1.0.4](https://github.com/qBraid/pyqasm/releases/tag/v1.0.4) - [v1.0.3](https://github.com/qBraid/pyqasm/releases/tag/v1.0.3) - [v1.0.2](https://github.com/qBraid/pyqasm/releases/tag/v1.0.2)