Skip to content

stretch operands in duration arithmetic raise TypeError: ... 'float' and 'NoneType' #389

Description

@TheGupta2012

Limitation

Duration and stretch types defines
stretch as a duration that resolves at compile time, and
Operations on durations allows a
stretch to be combined with a duration in arithmetic. This is how the spec expresses
padding that absorbs whatever slack a schedule leaves.

pyqasm declares a stretch with a None value and then applies Python arithmetic to it,
producing an uncaught TypeError.

Example QASM failure

import pyqasm

m = pyqasm.loads('''
OPENQASM 3.0;
stretch s;
duration a = 300ns;
duration b = a + s;
''')
m.validate()
TypeError: unsupported operand type(s) for +: 'float' and 'NoneType'

A bare stretch s; declaration and delay[s] q[0]; both work today, so the gap is confined
to arithmetic involving a stretch operand.

Change Requested

  1. Duration expressions containing a stretch operand must not raise a Python TypeError.
  2. Preferred: represent a duration as an affine value (constant_ns, {stretch: coefficient})
    so that a + s, 2 * s, and a + 2 * s are all representable symbolically and can be
    emitted unchanged by dumps().
  3. Minimum acceptable: raise a ValidationError stating that stretch arithmetic is not yet
    supported, naming the stretch variable and its span. The current internal error is the only
    unacceptable outcome.

Implementation Details

  • Duration/stretch declarations are handled in src/pyqasm/visitor.py alongside the other
    classical declarations; the numeric evaluation happens in Qasm3ExprEvaluator
    (src/pyqasm/expressions.py), which is where the float + None occurs.
  • Unit conversion lives in DURATION_UNITS in src/pyqasm/maps/expressions.py; the affine
    representation should normalise the constant part to nanoseconds there, consistent with how
    plain durations are already handled.
  • The affine form composes with the existing box[...] duration validation and delay[...]
    handling, both of which currently expect a plain number — they will need to accept the new
    type or explicitly reject a non-constant duration where a concrete one is required.
  • Full stretch resolution (solving for stretch values against a schedule) is a much larger
    piece of work and is explicitly out of scope here. This issue only asks that stretch
    operands survive expression evaluation.
  • Tests: tests/qasm3/test_timing.py (or the existing delay/box tests) — a + s, 2 * s,
    a + 2 * s, a stretch inside box[...], and a dumps() round-trip.

Activity

  1. self-assigned this
    on Aug 21, 2026
  2. added
    bugSomething isn't working
    qasm3Related to openqasm3
    error-handlingIssues related to error handing and error propagation
    llm-assistedUsed LLMs to fine tune issue description.
    on Aug 21, 2026
  3. removed their assignment
    on Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingerror-handlingIssues related to error handing and error propagationllm-assistedUsed LLMs to fine tune issue description.qasm3Related to openqasm3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions