Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
pip install --upgrade pip
pip install setuptools
pip install -r requirements-test.txt
bin/install_wheel_extras.sh dist --extra qasm3 --extra cirq --extra squin
bin/install_wheel_extras.sh dist --extra qasm3 --extra cirq --extra qiskit --extra squin
- name: Run tests with pyqir 0.11.x (typed pointers)
run: |
pip install "pyqir>=0.10.0,<0.12"
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Types of changes:

### ➕ New Features

- Added `qbraid_qir.qiskit` module for Qiskit to QIR conversion, ported from the archived [microsoft/qiskit-qir](https://github.com/microsoft/qiskit-qir) repository (MIT License). The module has been updated for compatibility with Qiskit 2.x and follows qbraid-qir conventions. Main entry point is `qiskit_to_qir(circuit, name, **kwargs)` which converts a Qiskit `QuantumCircuit` to a PyQIR `Module`. ([#272](https://github.com/qBraid/qbraid-qir/issues/272), [#271](https://github.com/qBraid/qbraid-qir/pull/271))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Correct the documented function signature for qiskit_to_qir.

The changelog currently implies name is required, but implementation uses name=None (optional). Please align docs to avoid API confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` at line 19, Update the CHANGELOG entry for the
qbraid_qir.qiskit addition to reflect the actual function signature of
qiskit_to_qir by noting that the name parameter is optional (defaults to None)
rather than required; locate the entry referencing qiskit_to_qir(circuit, name,
**kwargs) and change the description to show qiskit_to_qir(circuit, name=None,
**kwargs) or explicitly state "name is optional (defaults to None)" so the
documentation matches the implementation.


### 🌟 Improvements

### 📜 Documentation
Expand Down
37 changes: 37 additions & 0 deletions NOTICE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Third Party Notices

This software includes code derived from third party sources.
Comment on lines +1 to +3
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use “Third-Party” hyphenation for consistency with markdown grammar checks.

Line 1 and Line 3 should use “Third-Party” / “third-party”.

✏️ Proposed wording update
-# Third Party Notices
+# Third-Party Notices
 ...
-This software includes code derived from third party sources.
+This software includes code derived from third-party sources.
🧰 Tools
🪛 LanguageTool

[grammar] ~1-~1: Use a hyphen to join words.
Context: # Third Party Notices This software includes co...

(QB_NEW_EN_HYPHEN)


[grammar] ~3-~3: Use a hyphen to join words.
Context: ...oftware includes code derived from third party sources. ## qiskit-qir The `qbra...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@NOTICE.md` around lines 1 - 3, Update the header and phrasing to use
hyphenated “Third-Party” consistently: change the heading text "Third Party
Notices" to "Third-Party Notices" and change "third party sources" to
"third-party sources" so both the title and body use the hyphenated form.


## qiskit-qir

The `qbraid_qir.qiskit` module contains code derived from [microsoft/qiskit-qir](https://github.com/microsoft/qiskit-qir).

```
MIT License

Copyright (c) Microsoft Corporation.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
```

The qiskit-qir codebase has been adapted to:
- Work with Qiskit 2.x (updated for new QuantumCircuit API)
- Follow qbraid-qir conventions and coding style
- Support both pyqir 0.10.x and 0.12+ (typed and opaque pointers)
- Integrate with the qbraid-qir module structure
Comment on lines +33 to +37
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a single trailing newline at end of file.

markdownlint MD047 indicates the file should end with exactly one newline.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 35-35: Files should end with a single newline character

(MD047, single-trailing-newline)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@NOTICE.md` around lines 33 - 37, NOTICE.md currently does not end with
exactly one trailing newline; update the file to ensure it finishes with a
single newline character (no extra blank lines or missing newline) so it
satisfies markdownlint MD047—open NOTICE.md, remove any extra trailing blank
lines if present, and add exactly one '\n' at EOF.

22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ For Cirq to QIR conversions, install the `cirq` extra:
pip install 'qbraid-qir[cirq]'
```

For Qiskit to QIR conversions, install the `qiskit` extra:

```shell
pip install 'qbraid-qir[qiskit]'
```

For QIR to SQUIN conversions, install the `squin` extra:

```shell
Expand Down Expand Up @@ -146,6 +152,22 @@ module = cirq_to_qir(circuit, name="my-circuit")
ir = str(module)
```

### Qiskit conversions

```python
from qiskit import QuantumCircuit
from qbraid_qir import qiskit_to_qir

circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])

module = qiskit_to_qir(circuit, name="bell")

ir = str(module)
```

### SQUIN conversions

```python
Expand Down
8 changes: 8 additions & 0 deletions docs/api/qbraid_qir.qiskit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
:orphan:

qbraid_qir.qiskit
==================

.. automodule:: qbraid_qir.qiskit
:undoc-members:
:show-inheritance:
Comment on lines +6 to +8
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check automodule directive patterns in API docs
fd --glob '*.rst' docs/api | head -20

Repository: qBraid/qbraid-qir

Length of output: 204


🏁 Script executed:

#!/bin/bash
# Examine the specific file and surrounding context
if [ -f "docs/api/qbraid_qir.qiskit.rst" ]; then
  cat -n "docs/api/qbraid_qir.qiskit.rst"
else
  echo "File not found, searching for qiskit.rst files:"
  find . -name "*qiskit.rst" -type f 2>/dev/null
fi

Repository: qBraid/qbraid-qir

Length of output: 239


🏁 Script executed:

#!/bin/bash
# Check all automodule directives in docs/api to see the pattern
fd --glob '*.rst' docs/api | xargs grep -l "automodule" | while read file; do
  echo "=== $file ==="
  grep -A 3 "automodule" "$file"
done

Repository: qBraid/qbraid-qir

Length of output: 567


🏁 Script executed:

#!/bin/bash
# Check Sphinx configuration for automodule settings
find docs -name "conf.py" -o -name "conf.rst" | head -5

Repository: qBraid/qbraid-qir

Length of output: 73


🏁 Script executed:

#!/bin/bash
# Check if there's any documentation or comments about why members aren't included
rg -B2 -A2 "undoc-members|:members:" docs/ --type rst

Repository: qBraid/qbraid-qir

Length of output: 849


🌐 Web query:

Sphinx automodule :members: vs :undoc-members: directive difference documentation

💡 Result:

In Sphinx autodoc (e.g., .. automodule:: yourpkg.yourmod):

  • :members: tells Sphinx to include the module’s members (classes, functions, variables, etc.) in the generated docs. Without it, you generally get just the module-level docstring. You can also pass a comma-separated list to document only specific members. [1]

  • :undoc-members: tells Sphinx to also include members that have no docstring/doc-comment (i.e., “undocumented” members). This is typically used in addition to :members: to get all members, not just the documented ones. [1]

Example:

.. automodule:: noodles
   :members:
   :undoc-members:

This includes members with docstrings (because of :members:) and those without docstrings (because of :undoc-members:). [1]

Source: Sphinx autodoc options documentation. [1]

[1] https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html


🏁 Script executed:

#!/bin/bash
# Check the Sphinx configuration for autodoc settings
cat -n docs/conf.py | head -100

Repository: qBraid/qbraid-qir

Length of output: 4288


🏁 Script executed:

#!/bin/bash
# Look for autodoc_default_options or any special autodoc configuration
rg -n "autodoc|automodule" docs/conf.py

Repository: qBraid/qbraid-qir

Length of output: 414


Add :members: to include actual module members in API documentation.

The :undoc-members: option requires :members: to function properly in Sphinx. Without :members:, the automodule directive produces only module-level content and omits all classes, functions, and other members.

This pattern affects all module API documentation files (qbraid_qir.cirq.rst, qbraid_qir.qasm3.rst, qbraid_qir.qiskit.rst, and qbraid_qir.squin.rst). Add :members: to each to ensure complete API documentation.

Proposed fix
 .. automodule:: qbraid_qir.qiskit
+   :members:
    :undoc-members:
    :show-inheritance:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.. automodule:: qbraid_qir.qiskit
:undoc-members:
:show-inheritance:
.. automodule:: qbraid_qir.qiskit
:members:
:undoc-members:
:show-inheritance:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/api/qbraid_qir.qiskit.rst` around lines 6 - 8, The automodule directives
(e.g., the one for qbraid_qir.qiskit) are missing the :members: option so module
members (classes/functions) are not included; update each API rst
(qbraid_qir.qiskit.rst, qbraid_qir.cirq.rst, qbraid_qir.qasm3.rst,
qbraid_qir.squin.rst) to add the :members: option alongside :undoc-members: and
:show-inheritance: in the automodule directive to ensure all module members are
documented.

2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
# set_type_checking_flag = True
autodoc_member_order = "bysource"
autoclass_content = "both"
autodoc_mock_imports = ["cirq", "openqasm3", "pyqasm", "numpy", "numpy.typing", "kirin", "bloqade"]
autodoc_mock_imports = ["cirq", "openqasm3", "pyqasm", "numpy", "numpy.typing", "kirin", "bloqade", "qiskit"]
napoleon_numpy_docstring = False
todo_include_todos = True
mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
Expand Down
5 changes: 3 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ qBraid-QIR requires Python 3.10 or greater. The base package can be installed wi
pip install qbraid-qir


To enable specific conversions such as OpenQASM 3 to QIR or Cirq to QIR, you can install one or both extras:
To enable specific conversions such as OpenQASM 3 to QIR, Cirq to QIR, or Qiskit to QIR, you can install the extras:

.. code-block:: bash

pip install 'qbraid-qir[qasm3,cirq]'
pip install 'qbraid-qir[qasm3,cirq,qiskit]'


Resources
Expand Down Expand Up @@ -117,6 +117,7 @@ Resources
api/qbraid_qir
api/qbraid_qir.cirq
api/qbraid_qir.qasm3
api/qbraid_qir.qiskit
api/qbraid_qir.squin

.. toctree::
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description = "qBraid-SDK extension providing support for QIR conversions."
readme = "README.md"
authors = [{name = "qBraid Development Team"}, {email = "contact@qbraid.com"}]
license = "Apache-2.0"
keywords = ["qbraid", "quantum", "qir", "llvm", "cirq", "openqasm", "squin"]
keywords = ["qbraid", "quantum", "qir", "llvm", "cirq", "openqasm", "qiskit", "squin"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
Expand Down Expand Up @@ -40,10 +40,11 @@ Discord = "https://discord.gg/TPBU2sa8Et"
[project.optional-dependencies]
cirq = ["cirq-core>=1.3.0,<1.6.0"]
qasm3 = ["pyqasm>=0.4.0,<1.1.0", "numpy"]
qiskit = ["qiskit>=2.0"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

What is the latest major version of Qiskit and are there breaking changes between Qiskit 2.x and 3.x?

💡 Result:

  • Latest major version of Qiskit (SDK, qiskit PyPI package): 2.x (latest release shown on PyPI is 2.3.0). [1]
  • Breaking changes between Qiskit 2.x and 3.x: Qiskit 3.x has not been released yet (IBM’s 2.3 release notes say they do not expect to release Qiskit 3.0 until much later in 2026), so there are no actual 2→3 breaking changes to assess today—only plans/expectations. [2]
    • One explicitly noted planned change for 3.0 in the 2.3 notes: annotated=None will no longer be allowed (default would change to annotated=True, while annotated=False remains available). [2]

Sources: [1] PyPI qiskit project page, [2] IBM Quantum “Qiskit SDK 2.3 release notes”.


Consider constraining the Qiskit extra to 2.x as defensive major-version pinning.

While qiskit>=2.0 would technically allow Qiskit 3.x if released with breaking changes, Qiskit 3.0 has not been released yet and is not planned until later in 2026. However, pinning to a major version constraint is a reasonable defensive practice to avoid unexpected breakage from future major releases.

📦 Suggested fix
-qiskit = ["qiskit>=2.0"]
+qiskit = ["qiskit>=2.0,<3.0"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
qiskit = ["qiskit>=2.0"]
qiskit = ["qiskit>=2.0,<3.0"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pyproject.toml` at line 43, Update the Qiskit extra dependency specification
in pyproject.toml (the line currently reading qiskit = ["qiskit>=2.0"]) to
constrain to the 2.x series so future major releases won’t be pulled in; replace
the loose ">=2.0" spec with a 2.x‑bounded spec (e.g., >=2.0,<3.0) to pin the
major version while allowing patch/minor updates.

squin = ["kirin-toolchain>=0.17.33", "bloqade-circuit>=0.9.1"]

[tool.setuptools]
packages = ["qbraid_qir", "qbraid_qir.cirq", "qbraid_qir.qasm3", "qbraid_qir.squin"]
packages = ["qbraid_qir", "qbraid_qir.cirq", "qbraid_qir.qasm3", "qbraid_qir.qiskit", "qbraid_qir.squin"]

[tool.setuptools.dynamic]
version = {attr = "qbraid_qir.__version__"}
Expand Down
4 changes: 3 additions & 1 deletion qbraid_qir/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@
"dumps",
"qasm3_to_qir",
"cirq_to_qir",
"qiskit_to_qir",
]

_lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir"}
_lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir", "qiskit": "qiskit_to_qir"}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Normalize _lazy values to sequences, not strings.

Current _lazy uses string values, but downstream logic treats them as iterables of object names. This causes character-level flattening in __dir__ and substring matching in __getattr__.

💡 Proposed fix
-_lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir", "qiskit": "qiskit_to_qir"}
+_lazy = {
+    "cirq": ("cirq_to_qir",),
+    "qasm3": ("qasm3_to_qir",),
+    "qiskit": ("qiskit_to_qir",),
+}
@@
-        if name in objects:
+        if name in objects:
             module = importlib.import_module(f".{mod_name}", __name__)
             obj = getattr(module, name)
             globals()[name] = obj
             return obj
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir", "qiskit": "qiskit_to_qir"}
_lazy = {
"cirq": ("cirq_to_qir",),
"qasm3": ("qasm3_to_qir",),
"qiskit": ("qiskit_to_qir",),
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@qbraid_qir/__init__.py` at line 57, _lazy currently maps backends to plain
strings which are iterated as character sequences by __dir__ and __getattr__;
change the values in _lazy to sequences (e.g., tuples or lists) of object/module
names (e.g., ("cirq_to_qir",) not "cirq_to_qir") so downstream logic treats each
entry as a single name. Update the _lazy definition and ensure any code that
iterates _lazy (notably __dir__ and __getattr__) expects sequences of names
rather than characters; keep the same identifiers "cirq", "qasm3", "qiskit" as
keys and use singleton tuples/lists as their values.


if TYPE_CHECKING:
from .cirq import cirq_to_qir
from .qasm3 import qasm3_to_qir
from .qiskit import qiskit_to_qir


def __getattr__(name):
Expand Down
59 changes: 59 additions & 0 deletions qbraid_qir/qiskit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright 2025 qBraid
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# pylint: disable=line-too-long
# Portions of this module are adapted from microsoft/qiskit-qir
# (https://github.com/microsoft/qiskit-qir), with modifications by qBraid.
# The original MIT license notice is reproduced in NOTICE.md.
# pylint: enable=line-too-long

"""
Module containing Qiskit QIR functionality.

.. currentmodule:: qbraid_qir.qiskit

Functions
-----------

.. autosummary::
:toctree: ../stubs/

qiskit_to_qir


Classes
---------

.. autosummary::
:toctree: ../stubs/

QiskitModule
BasicQiskitVisitor

Exceptions
-----------

.. autosummary::
:toctree: ../stubs/

QiskitConversionError

"""

from .convert import qiskit_to_qir
from .elements import QiskitModule
from .exceptions import QiskitConversionError
from .visitor import BasicQiskitVisitor

__all__ = ["qiskit_to_qir", "QiskitModule", "QiskitConversionError", "BasicQiskitVisitor"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Optional: sort __all__ for lint consistency (RUF022).

No functional issue, but sorting avoids recurring lint churn.

🧰 Tools
🪛 Ruff (0.15.2)

[warning] 59-59: __all__ is not sorted

Apply an isort-style sorting to __all__

(RUF022)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@qbraid_qir/qiskit/__init__.py` at line 59, The __all__ export list is
unsorted which triggers lint churn; in qiskit/__init__.py, sort the names in the
__all__ list alphabetically (e.g., "BasicQiskitVisitor",
"QiskitConversionError", "QiskitModule", "qiskit_to_qir") so the exported
symbols BasicQiskitVisitor, QiskitConversionError, QiskitModule and
qiskit_to_qir appear in lexicographic order.

89 changes: 89 additions & 0 deletions qbraid_qir/qiskit/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright 2025 qBraid
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# pylint: disable=line-too-long
# Portions of this module are adapted from microsoft/qiskit-qir
# (https://github.com/microsoft/qiskit-qir), with modifications by qBraid.
# The original MIT license notice is reproduced in NOTICE.md.
# pylint: enable=line-too-long

"""
Module containing Qiskit to QIR conversion functions.

"""

from typing import Optional

from pyqir import Context, Module, qir_module
from qiskit.circuit import QuantumCircuit

from .elements import QiskitModule, generate_module_id
from .exceptions import QiskitConversionError
from .visitor import BasicQiskitVisitor


def qiskit_to_qir(circuit: QuantumCircuit, name: Optional[str] = None, **kwargs) -> Module:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Type the visitor kwargs for API clarity.

**kwargs is part of a public entry point; adding explicit typing (or a typed keyword-only signature) will improve static validation and IDE hints.

🧰 Tools
🪛 Ruff (0.15.2)

[warning] 36-36: Missing type annotation for **kwargs

(ANN003)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@qbraid_qir/qiskit/convert.py` at line 36, The public entry function
qiskit_to_qir currently uses an untyped **kwargs; change its signature to
document and type the visitor/visitor-related kwargs (e.g., add a typed
keyword-only parameter or type the var-kwargs). For example, import typing (Any,
Optional, Mapping) and replace **kwargs with a typed parameter such as *,
visitors: Optional[Mapping[str, Any]] = None (or keep **kwargs: Any if you must
accept arbitrary keys) and update all internal uses of kwargs inside
qiskit_to_qir to reference the new name (visitors or visitor_kwargs) so callers
and static checkers get proper hints.

"""
Converts a Qiskit QuantumCircuit to a PyQIR module.

Args:
circuit: The Qiskit QuantumCircuit to convert.
name: Identifier for created QIR module. Auto-generated if not provided.

Keyword Args:
initialize_runtime (bool): Whether to perform quantum runtime environment initialization,
default `True`.
record_output (bool): Whether to record output calls for registers, default `True`.
emit_barrier_calls (bool): Whether to emit barrier calls in the QIR, default `False`.

Returns:
The QIR ``pyqir.Module`` representation of the input Qiskit circuit.

Raises:
TypeError: If the input is not a valid Qiskit QuantumCircuit.
ValueError: If the input circuit is empty.
QiskitConversionError: If the conversion fails.

Example:
>>> from qiskit import QuantumCircuit
>>> from qbraid_qir.qiskit import qiskit_to_qir
>>>
>>> qc = QuantumCircuit(2, 2)
>>> qc.h(0)
>>> qc.cx(0, 1)
>>> qc.measure([0, 1], [0, 1])
>>>
>>> module = qiskit_to_qir(qc, name="bell")
>>> ir = str(module)
"""
if not isinstance(circuit, QuantumCircuit):
raise TypeError("Input quantum program must be of type qiskit.QuantumCircuit.")

if len(circuit.data) == 0:
raise ValueError("Input quantum circuit must consist of at least one operation.")

if name is None:
name = generate_module_id(circuit)

llvm_module = qir_module(Context(), name)
module = QiskitModule.from_circuit(circuit, llvm_module)

visitor = BasicQiskitVisitor(**kwargs)
module.accept(visitor)

error = llvm_module.verify()
if error is not None:
raise QiskitConversionError(error)

return llvm_module
Loading