Skip to content

loads() silently drops falsy kwarg values (device_qubits=0, device_cycle_time=0.0, ...) #356

Closed

Description

@ryanhill1

Description

loads() stores six of its documented kwargs with a walrus truthiness test rather than a presence test:

if dev_qbts := kwargs.get("device_qubits"):
    module._device_qubits = dev_qbts

So any falsy value is silently treated as "not passed" — no error, no warning, the caller's argument is discarded. entrypoint.py:103-116.

The same function already uses the correct pattern for its two bool kwargs:

if "frame_in_def_cal" in kwargs:
    module._frame_in_def_cal = kwargs["frame_in_def_cal"]

Reproduction

from pyqasm import loads

src = 'OPENQASM 3.0;\ninclude "stdgates.inc";\nqubit[2] q;\nh q[0];\n'

loads(src, device_qubits=0)._device_qubits                 # None  <- expected 0
loads(src, device_cycle_time=0.0)._device_cycle_time       # None  <- expected 0.0
loads(src, compiler_angle_type_size=0)._compiler_angle_type_size  # None
loads(src, frame_limit_per_port=0)._frame_limit_per_port   # None

loads(src, frame_in_def_cal=False)._frame_in_def_cal       # False <- correctly honoured

Scope

Pre-existing on main; unrelated to any open PR.

extern_functions={} is affected by the same test but is harmless in practice — the attribute already defaults to {}, so the dropped value is indistinguishable from the default. The four Optional[...] = None attributes above are the ones where a caller's 0 becomes None.

Two adjacent gaps in the same block, worth deciding on together:

  • No value validation. Negative values are truthy, so they are stored and surface later as a confusing message rather than being rejected at the call site:

    m = loads(src, device_qubits=-5)
    m.validate()   # ValidationError: Total qubits '2' exceed device qubits '-5'.
  • Unknown kwargs are silently ignored. loads(src, devise_qubits=5) raises nothing and produces a module with _device_qubits = None. A typo in a documented kwarg is invisible until the resulting behaviour is wrong.

Suggested fix

Use presence tests consistently for all of them:

if "device_qubits" in kwargs:
    module._device_qubits = kwargs["device_qubits"]

Optionally reject non-positive device_qubits / device_cycle_time / frame_limit_per_port at load time, and raise on unrecognised kwarg names, so mistakes fail where they are made.

Found while verifying #349, which documents device_qubits as a loads() kwarg.

Activity

  1. added
    bugSomething isn't working
    error-handlingIssues related to error handing and error propagation
    llm-assistedUsed LLMs to fine tune issue description.
    on Aug 6, 2026
  2. added a commit that references this issue on Aug 13, 2026
    274b13c
  3. added a commit that references this issue on Aug 17, 2026
    39ab339
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.no-qc-knowledge-reqdDoes not require knowledge of QC or QIS

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions