Skip to content

Conversation

@denialhaag
Copy link
Member

@denialhaag denialhaag commented Jan 9, 2026

Description

This PR fully replaces pybind11 with nanobind. This change will allow us to ship stable ABI wheels, saving us PyPI space.

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

@github-project-automation github-project-automation bot moved this to In Progress in MQT Verification Jan 9, 2026
@denialhaag denialhaag changed the base branch from main to config-updates January 9, 2026 17:07
@denialhaag denialhaag self-assigned this Jan 9, 2026
@denialhaag denialhaag added python Anything related to Python code packaging Anything related to Python packaging c++ Anything related to C++ code labels Jan 9, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 9, 2026

Warning

Rate limit exceeded

@denialhaag has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 45 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between dbd9db8 and c8ac661.

📒 Files selected for processing (3)
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • python/mqt/qcec/_compat/optional.py
📝 Walkthrough

Walkthrough

This PR migrates Python bindings and build tooling from pybind11 to nanobind across CI, CMake dependency resolution, binding sources, and packaging metadata; it enables Stable ABI wheels for Python 3.12+ and bumps the required mqt-core version to 3.4.0.

Changes

Cohort / File(s) Summary
CI & Top-level CMake
/.github/workflows/ci.yml, CMakeLists.txt
CI install-pkgs switched from pybind11==3.0.1nanobind==2.10.2; cmake_minimum_required bumped and find_package(Python ...) call consolidated to use ${SKBUILD_SABI_COMPONENT}.
Bindings build CMake
bindings/CMakeLists.txt
Binding helper renamed to add_mqt_python_binding_nanobind; removed pybind11_json from LINK_LIBS.
External deps & packaging
cmake/ExternalDependencies.cmake, pyproject.toml
Replaced pybind11 handling with nanobind (nanobind --cmake_dir / find_package(nanobind CONFIG REQUIRED)); removed pybind11_json FetchContent; bumped MQT Core to 3.4.0; build deps and wheel metadata updated for Stable ABI (Python 3.12+).
Binding implementations
bindings/...
bindings/bindings.cpp, bindings/application_scheme.cpp, bindings/configuration.cpp, bindings/equivalence_checking_manager.cpp, bindings/equivalence_criterion.cpp, bindings/state_type.cpp
Comprehensive migration from pybind11 → nanobind: headers/namespaces → nanobind/nb, module param types py::modulenb::module_, PYBIND11_MODULENB_MODULE, py::class_nb::class_, py::initnb::init, member/property API adjusted (def_readwritedef_rw/def_prop_rw), .finalize() removed, and some enums extended with new values.
Docs & changelog
CHANGELOG.md, UPGRADING.md
Added entries documenting pybind11→nanobind migration, Stable ABI wheels for 3.12+, and mqt-core bump; UPGRADING updated wheel targets and notes.
Minor runtime message
python/mqt/qcec/_compat/optional.py
Tweaked OptionalDependencyTester message (removed trailing clause).

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI workflow
  participant CMake as CMake
  participant Nanobind as nanobind tool/package
  participant Build as Compiler/Build system
  participant Wheel as Packaging (wheel build)

  CI->>CMake: configure project (invoke cmake)
  CMake->>Nanobind: run `nanobind --cmake_dir` / find_package(nanobind)
  Nanobind-->>CMake: return cmake dir / config
  CMake->>Build: generate build rules linking nanobind
  Build->>Build: compile C++ bindings using NB_MODULE/nanobind APIs
  Build->>Wheel: produce wheel with Stable ABI metadata (3.12+)
  Wheel-->>CI: upload/store produced artifact
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

dependencies

Poem

🐰 I hopped from pybind to nanobind with cheer,

nibbling headers, making bindings clear.
Stable wheels now dance for three-point-twelve,
enums grew whiskers, builds ready to delve.
Hooray — the rabbit shipped a painless gear ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: replacing pybind11 with nanobind throughout the codebase.
Description check ✅ Passed The description provides a clear summary of changes, motivation (stable ABI wheels and PyPI space savings), and completes the required checklist items appropriately.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
python/mqt/qcec/_compat/optional.py (1)

105-108: Simplify the redundant wording in the error message.

The error message on line 107 is awkwardly phrased: "to use functionality related to its functionality" is repetitive and unclear. Revise it to be more concise and direct.

 HAS_QISKIT = OptionalDependencyTester(
     "qiskit",
-    msg="Please install the `mqt.qcec[qiskit]` extra or a compatible version of Qiskit to use functionality related to its functionality.",
+    msg="Please install the `mqt.qcec[qiskit]` extra or a compatible version of Qiskit.",
 )
🤖 Fix all issues with AI agents
In @bindings/equivalence_checking_manager.cpp:
- Around line 87-96: The setter lambda for
EquivalenceCheckingManager::Results::checkerResults is using nb::str(obj) which
yields a Python repr (invalid JSON); replace that with calling Python's
json.dumps(obj) and cast the resulting string to std::string before passing to
nlohmann::json::parse; specifically update the setter lambda in the def_prop_rw
for "checker_results" to import the json module (nb::module::import("json")) and
call its dumps(obj) (e.g., nb::module::import("json").attr("dumps")(obj)) to
obtain a proper JSON string, then parse that into results.checkerResults.

In @pyproject.toml:
- Around line 81-82: The pyproject sets wheel.py-api = "cp312" under
[tool.scikit-build], which forces ABI3 cp312 wheels (incompatible with Python
3.10/3.11); update the configuration so wheel.py-api is changed to "cp310" to
produce ABI3 wheels compatible with Python >=3.10 (or alternatively remove
wheel.py-api to build non-ABI3 wheels for 3.10/3.11, or change requires-python
to ">=3.12" and remove 3.10/3.11 classifiers). Locate the wheel.py-api entry and
adjust its value to "cp310" (or apply one of the two alternative options) and
ensure the package metadata fields requires-python and classifiers remain
consistent with the chosen approach.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2326c51 and 7a042e3.

⛔ Files ignored due to path filters (2)
  • docs/images/parameterized_flow.svg is excluded by !**/*.svg
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (79)
  • .github/workflows/ci.yml
  • .license-tools-config.json
  • .pre-commit-config.yaml
  • CMakeLists.txt
  • bindings/CMakeLists.txt
  • bindings/application_scheme.cpp
  • bindings/bindings.cpp
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/equivalence_criterion.cpp
  • bindings/state_type.cpp
  • cmake/ExternalDependencies.cmake
  • cmake/cmake_uninstall.cmake.in
  • docs/conf.py
  • include/Configuration.hpp
  • include/EquivalenceCheckingManager.hpp
  • include/EquivalenceCriterion.hpp
  • include/ThreadSafeQueue.hpp
  • include/checker/EquivalenceChecker.hpp
  • include/checker/dd/DDAlternatingChecker.hpp
  • include/checker/dd/DDConstructionChecker.hpp
  • include/checker/dd/DDEquivalenceChecker.hpp
  • include/checker/dd/DDPackageConfigs.hpp
  • include/checker/dd/DDSimulationChecker.hpp
  • include/checker/dd/TaskManager.hpp
  • include/checker/dd/applicationscheme/ApplicationScheme.hpp
  • include/checker/dd/applicationscheme/GateCostApplicationScheme.hpp
  • include/checker/dd/applicationscheme/LookaheadApplicationScheme.hpp
  • include/checker/dd/applicationscheme/OneToOneApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ProportionalApplicationScheme.hpp
  • include/checker/dd/applicationscheme/SequentialApplicationScheme.hpp
  • include/checker/dd/simulation/StateGenerator.hpp
  • include/checker/dd/simulation/StateType.hpp
  • include/checker/zx/ZXChecker.hpp
  • noxfile.py
  • pyproject.toml
  • python/mqt/qcec/__init__.py
  • python/mqt/qcec/_compat/__init__.py
  • python/mqt/qcec/_compat/optional.py
  • python/mqt/qcec/_compat/typing.py
  • python/mqt/qcec/_version.pyi
  • python/mqt/qcec/compilation_flow_profiles.py
  • python/mqt/qcec/configuration_options.py
  • python/mqt/qcec/parameterized.py
  • python/mqt/qcec/pyqcec.pyi
  • python/mqt/qcec/verify.py
  • python/mqt/qcec/verify_compilation_flow.py
  • sitecustomize.py
  • src/CMakeLists.txt
  • src/Configuration.cpp
  • src/EquivalenceCheckingManager.cpp
  • src/checker/EquivalenceChecker.cpp
  • src/checker/dd/DDAlternatingChecker.cpp
  • src/checker/dd/DDConstructionChecker.cpp
  • src/checker/dd/DDEquivalenceChecker.cpp
  • src/checker/dd/DDSimulationChecker.cpp
  • src/checker/dd/applicationscheme/LookaheadApplicationScheme.cpp
  • src/checker/dd/simulation/StateGenerator.cpp
  • src/checker/zx/ZXChecker.cpp
  • test/CMakeLists.txt
  • test/python/test.py
  • test/python/test_compilation_flow_profiles.py
  • test/python/test_configuration.py
  • test/python/test_construction.py
  • test/python/test_dynamic_circuits.py
  • test/python/test_partial_equivalence.py
  • test/python/test_symbolic.py
  • test/python/test_verify.py
  • test/python/test_verify_compilation.py
  • test/test_compilationflow.cpp
  • test/test_dynamic_circuits.cpp
  • test/test_equality.cpp
  • test/test_functionality.cpp
  • test/test_journal.cpp
  • test/test_partial_equivalence.cpp
  • test/test_simple_circuit_identities.cpp
  • test/test_simulation.cpp
  • test/test_symbolic.cpp
  • test/test_zx.cpp
🧰 Additional context used
🧠 Learnings (29)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.
📚 Learning: 2025-12-07T09:10:31.836Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: src/qdmi/sc/Device.cpp:97-102
Timestamp: 2025-12-07T09:10:31.836Z
Learning: In the munich-quantum-toolkit/core repository, duplication of QDMI-related macros (such as IS_INVALID_ARGUMENT) across device implementations (e.g., in src/qdmi/sc/Device.cpp and src/qdmi/dd/Device.cpp) is acceptable as a temporary measure. The preferred long-term solution is to upstream these macros to the QDMI repository rather than creating local shared headers, so they can be reused across all dependent projects.

Applied to files:

  • include/checker/dd/simulation/StateType.hpp
  • src/checker/dd/DDConstructionChecker.cpp
  • include/checker/dd/applicationscheme/GateCostApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ApplicationScheme.hpp
  • include/EquivalenceCheckingManager.hpp
  • test/python/test_symbolic.py
  • test/test_dynamic_circuits.cpp
  • test/test_partial_equivalence.cpp
  • python/mqt/qcec/configuration_options.py
  • src/checker/dd/DDEquivalenceChecker.cpp
  • src/checker/dd/simulation/StateGenerator.cpp
  • include/checker/dd/DDPackageConfigs.hpp
  • test/python/test_compilation_flow_profiles.py
  • src/CMakeLists.txt
  • include/checker/dd/applicationscheme/OneToOneApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ProportionalApplicationScheme.hpp
  • test/python/test_configuration.py
  • include/checker/dd/DDEquivalenceChecker.hpp
  • src/checker/EquivalenceChecker.cpp
  • test/CMakeLists.txt
  • include/ThreadSafeQueue.hpp
  • include/EquivalenceCriterion.hpp
  • python/mqt/qcec/__init__.py
  • include/checker/dd/applicationscheme/SequentialApplicationScheme.hpp
  • include/checker/dd/TaskManager.hpp
  • cmake/cmake_uninstall.cmake.in
  • include/checker/dd/DDSimulationChecker.hpp
  • sitecustomize.py
  • test/test_functionality.cpp
  • test/test_simulation.cpp
  • test/test_simple_circuit_identities.cpp
  • include/Configuration.hpp
  • test/python/test_dynamic_circuits.py
  • src/checker/zx/ZXChecker.cpp
  • python/mqt/qcec/_compat/optional.py
  • src/checker/dd/DDAlternatingChecker.cpp
  • test/python/test_verify_compilation.py
  • include/checker/zx/ZXChecker.hpp
  • python/mqt/qcec/pyqcec.pyi
  • src/Configuration.cpp
  • bindings/equivalence_criterion.cpp
  • python/mqt/qcec/compilation_flow_profiles.py
  • test/test_zx.cpp
  • src/EquivalenceCheckingManager.cpp
  • test/python/test_construction.py
  • python/mqt/qcec/_compat/typing.py
  • src/checker/dd/DDSimulationChecker.cpp
  • python/mqt/qcec/parameterized.py
  • test/test_journal.cpp
  • test/python/test_verify.py
  • include/checker/dd/simulation/StateGenerator.hpp
  • test/test_equality.cpp
  • include/checker/dd/DDAlternatingChecker.hpp
  • python/mqt/qcec/verify_compilation_flow.py
  • include/checker/EquivalenceChecker.hpp
  • docs/conf.py
  • src/checker/dd/applicationscheme/LookaheadApplicationScheme.cpp
  • test/python/test.py
  • python/mqt/qcec/_compat/__init__.py
  • bindings/state_type.cpp
  • test/python/test_partial_equivalence.py
  • cmake/ExternalDependencies.cmake
  • include/checker/dd/DDConstructionChecker.hpp
  • python/mqt/qcec/verify.py
  • include/checker/dd/applicationscheme/LookaheadApplicationScheme.hpp
  • python/mqt/qcec/_version.pyi
  • pyproject.toml
  • test/test_compilationflow.cpp
  • test/test_symbolic.cpp
  • bindings/configuration.cpp
  • bindings/CMakeLists.txt
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2025-12-05T17:45:37.602Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1360
File: .github/workflows/reusable-mlir-tests.yml:40-43
Timestamp: 2025-12-05T17:45:37.602Z
Learning: In the munich-quantum-toolkit/core repository, patch releases of LLVM dependencies don't require documentation updates, changelog entries, or additional tests beyond what's validated by passing CI checks.

Applied to files:

  • include/checker/dd/simulation/StateType.hpp
  • src/checker/dd/DDConstructionChecker.cpp
  • include/checker/dd/applicationscheme/GateCostApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ApplicationScheme.hpp
  • include/EquivalenceCheckingManager.hpp
  • test/python/test_symbolic.py
  • test/test_dynamic_circuits.cpp
  • test/test_partial_equivalence.cpp
  • python/mqt/qcec/configuration_options.py
  • src/checker/dd/DDEquivalenceChecker.cpp
  • src/checker/dd/simulation/StateGenerator.cpp
  • include/checker/dd/DDPackageConfigs.hpp
  • test/python/test_compilation_flow_profiles.py
  • src/CMakeLists.txt
  • include/checker/dd/applicationscheme/OneToOneApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ProportionalApplicationScheme.hpp
  • test/python/test_configuration.py
  • include/checker/dd/DDEquivalenceChecker.hpp
  • src/checker/EquivalenceChecker.cpp
  • test/CMakeLists.txt
  • include/ThreadSafeQueue.hpp
  • include/EquivalenceCriterion.hpp
  • python/mqt/qcec/__init__.py
  • include/checker/dd/applicationscheme/SequentialApplicationScheme.hpp
  • include/checker/dd/TaskManager.hpp
  • cmake/cmake_uninstall.cmake.in
  • include/checker/dd/DDSimulationChecker.hpp
  • sitecustomize.py
  • test/test_functionality.cpp
  • test/test_simulation.cpp
  • test/test_simple_circuit_identities.cpp
  • include/Configuration.hpp
  • test/python/test_dynamic_circuits.py
  • src/checker/zx/ZXChecker.cpp
  • python/mqt/qcec/_compat/optional.py
  • src/checker/dd/DDAlternatingChecker.cpp
  • test/python/test_verify_compilation.py
  • include/checker/zx/ZXChecker.hpp
  • python/mqt/qcec/pyqcec.pyi
  • src/Configuration.cpp
  • bindings/equivalence_criterion.cpp
  • python/mqt/qcec/compilation_flow_profiles.py
  • test/test_zx.cpp
  • src/EquivalenceCheckingManager.cpp
  • test/python/test_construction.py
  • python/mqt/qcec/_compat/typing.py
  • src/checker/dd/DDSimulationChecker.cpp
  • python/mqt/qcec/parameterized.py
  • test/test_journal.cpp
  • test/python/test_verify.py
  • include/checker/dd/simulation/StateGenerator.hpp
  • test/test_equality.cpp
  • include/checker/dd/DDAlternatingChecker.hpp
  • python/mqt/qcec/verify_compilation_flow.py
  • include/checker/EquivalenceChecker.hpp
  • docs/conf.py
  • src/checker/dd/applicationscheme/LookaheadApplicationScheme.cpp
  • test/python/test.py
  • python/mqt/qcec/_compat/__init__.py
  • bindings/state_type.cpp
  • test/python/test_partial_equivalence.py
  • cmake/ExternalDependencies.cmake
  • include/checker/dd/DDConstructionChecker.hpp
  • python/mqt/qcec/verify.py
  • include/checker/dd/applicationscheme/LookaheadApplicationScheme.hpp
  • python/mqt/qcec/_version.pyi
  • CMakeLists.txt
  • pyproject.toml
  • test/test_compilationflow.cpp
  • test/test_symbolic.cpp
  • bindings/configuration.cpp
  • bindings/CMakeLists.txt
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2025-10-09T13:14:10.178Z
Learnt from: DRovara
Repo: munich-quantum-toolkit/core PR: 1108
File: mlir/lib/Dialect/MQTOpt/Transforms/ReplaceBasisStateControlsWithIfPattern.cpp:219-221
Timestamp: 2025-10-09T13:14:10.178Z
Learning: The MQT Core project (munich-quantum-toolkit/core repository) uses the C++20 standard, not C++17. C++20 features such as abbreviated function templates (e.g., `const auto&` parameters) are supported and valid in this codebase.

Applied to files:

  • include/checker/dd/simulation/StateType.hpp
  • src/checker/dd/DDConstructionChecker.cpp
  • include/checker/dd/applicationscheme/GateCostApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ApplicationScheme.hpp
  • include/EquivalenceCheckingManager.hpp
  • test/test_dynamic_circuits.cpp
  • test/test_partial_equivalence.cpp
  • src/checker/dd/DDEquivalenceChecker.cpp
  • src/checker/dd/simulation/StateGenerator.cpp
  • include/checker/dd/DDPackageConfigs.hpp
  • include/checker/dd/applicationscheme/OneToOneApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ProportionalApplicationScheme.hpp
  • include/checker/dd/DDEquivalenceChecker.hpp
  • src/checker/EquivalenceChecker.cpp
  • include/ThreadSafeQueue.hpp
  • include/EquivalenceCriterion.hpp
  • include/checker/dd/applicationscheme/SequentialApplicationScheme.hpp
  • include/checker/dd/TaskManager.hpp
  • include/checker/dd/DDSimulationChecker.hpp
  • test/test_functionality.cpp
  • test/test_simulation.cpp
  • test/test_simple_circuit_identities.cpp
  • include/Configuration.hpp
  • src/checker/zx/ZXChecker.cpp
  • .github/workflows/ci.yml
  • src/checker/dd/DDAlternatingChecker.cpp
  • include/checker/zx/ZXChecker.hpp
  • src/Configuration.cpp
  • bindings/equivalence_criterion.cpp
  • test/test_zx.cpp
  • src/EquivalenceCheckingManager.cpp
  • src/checker/dd/DDSimulationChecker.cpp
  • test/test_journal.cpp
  • include/checker/dd/simulation/StateGenerator.hpp
  • test/test_equality.cpp
  • include/checker/dd/DDAlternatingChecker.hpp
  • include/checker/EquivalenceChecker.hpp
  • src/checker/dd/applicationscheme/LookaheadApplicationScheme.cpp
  • bindings/state_type.cpp
  • cmake/ExternalDependencies.cmake
  • include/checker/dd/DDConstructionChecker.hpp
  • include/checker/dd/applicationscheme/LookaheadApplicationScheme.hpp
  • CMakeLists.txt
  • test/test_compilationflow.cpp
  • test/test_symbolic.cpp
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2025-11-04T14:28:32.371Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/test_qdmi_qiskit_backend.py:0-0
Timestamp: 2025-11-04T14:28:32.371Z
Learning: In the munich-quantum-toolkit/core repository, at least one FoMaC device is always available during testing, so skip logic for missing devices in QDMI Qiskit backend tests is not necessary.

Applied to files:

  • include/checker/dd/simulation/StateType.hpp
  • src/checker/dd/DDConstructionChecker.cpp
  • include/checker/dd/applicationscheme/GateCostApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ApplicationScheme.hpp
  • include/EquivalenceCheckingManager.hpp
  • test/python/test_symbolic.py
  • test/test_dynamic_circuits.cpp
  • test/test_partial_equivalence.cpp
  • python/mqt/qcec/configuration_options.py
  • src/checker/dd/DDEquivalenceChecker.cpp
  • src/checker/dd/simulation/StateGenerator.cpp
  • include/checker/dd/DDPackageConfigs.hpp
  • test/python/test_compilation_flow_profiles.py
  • src/CMakeLists.txt
  • include/checker/dd/applicationscheme/OneToOneApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ProportionalApplicationScheme.hpp
  • test/python/test_configuration.py
  • include/checker/dd/DDEquivalenceChecker.hpp
  • src/checker/EquivalenceChecker.cpp
  • test/CMakeLists.txt
  • include/ThreadSafeQueue.hpp
  • include/EquivalenceCriterion.hpp
  • python/mqt/qcec/__init__.py
  • include/checker/dd/applicationscheme/SequentialApplicationScheme.hpp
  • include/checker/dd/TaskManager.hpp
  • cmake/cmake_uninstall.cmake.in
  • include/checker/dd/DDSimulationChecker.hpp
  • sitecustomize.py
  • test/test_functionality.cpp
  • test/test_simulation.cpp
  • test/test_simple_circuit_identities.cpp
  • include/Configuration.hpp
  • test/python/test_dynamic_circuits.py
  • src/checker/zx/ZXChecker.cpp
  • python/mqt/qcec/_compat/optional.py
  • src/checker/dd/DDAlternatingChecker.cpp
  • test/python/test_verify_compilation.py
  • include/checker/zx/ZXChecker.hpp
  • python/mqt/qcec/pyqcec.pyi
  • src/Configuration.cpp
  • bindings/equivalence_criterion.cpp
  • python/mqt/qcec/compilation_flow_profiles.py
  • test/test_zx.cpp
  • src/EquivalenceCheckingManager.cpp
  • test/python/test_construction.py
  • python/mqt/qcec/_compat/typing.py
  • src/checker/dd/DDSimulationChecker.cpp
  • python/mqt/qcec/parameterized.py
  • test/test_journal.cpp
  • test/python/test_verify.py
  • include/checker/dd/simulation/StateGenerator.hpp
  • test/test_equality.cpp
  • include/checker/dd/DDAlternatingChecker.hpp
  • python/mqt/qcec/verify_compilation_flow.py
  • include/checker/EquivalenceChecker.hpp
  • docs/conf.py
  • src/checker/dd/applicationscheme/LookaheadApplicationScheme.cpp
  • test/python/test.py
  • python/mqt/qcec/_compat/__init__.py
  • bindings/state_type.cpp
  • test/python/test_partial_equivalence.py
  • cmake/ExternalDependencies.cmake
  • include/checker/dd/DDConstructionChecker.hpp
  • python/mqt/qcec/verify.py
  • include/checker/dd/applicationscheme/LookaheadApplicationScheme.hpp
  • python/mqt/qcec/_version.pyi
  • pyproject.toml
  • test/test_compilationflow.cpp
  • test/test_symbolic.cpp
  • bindings/configuration.cpp
  • bindings/CMakeLists.txt
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2025-12-09T00:55:11.926Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Flux/IR/Operations/StandardGates/BarrierOp.cpp:45-54
Timestamp: 2025-12-09T00:55:11.926Z
Learning: In the Flux dialect (mlir/lib/Dialect/Flux), qubits follow single-user/linear-type semantics where each qubit value can only be consumed once, similar to MQTOpt. This invariant makes it safe to dereference getUsers().begin() in canonicalization patterns like MergeSubsequentBarrier in BarrierOp.cpp, as there will be at most one user per qubit output.

Applied to files:

  • include/checker/dd/simulation/StateType.hpp
  • src/checker/dd/DDConstructionChecker.cpp
  • include/checker/dd/applicationscheme/GateCostApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ApplicationScheme.hpp
  • include/EquivalenceCheckingManager.hpp
  • test/test_dynamic_circuits.cpp
  • test/test_partial_equivalence.cpp
  • src/checker/dd/DDEquivalenceChecker.cpp
  • src/checker/dd/simulation/StateGenerator.cpp
  • include/checker/dd/DDPackageConfigs.hpp
  • include/checker/dd/applicationscheme/OneToOneApplicationScheme.hpp
  • include/checker/dd/applicationscheme/ProportionalApplicationScheme.hpp
  • include/checker/dd/DDEquivalenceChecker.hpp
  • src/checker/EquivalenceChecker.cpp
  • include/ThreadSafeQueue.hpp
  • include/EquivalenceCriterion.hpp
  • include/checker/dd/applicationscheme/SequentialApplicationScheme.hpp
  • include/checker/dd/TaskManager.hpp
  • include/checker/dd/DDSimulationChecker.hpp
  • test/test_functionality.cpp
  • test/test_simulation.cpp
  • test/test_simple_circuit_identities.cpp
  • include/Configuration.hpp
  • src/checker/zx/ZXChecker.cpp
  • src/checker/dd/DDAlternatingChecker.cpp
  • include/checker/zx/ZXChecker.hpp
  • src/Configuration.cpp
  • bindings/equivalence_criterion.cpp
  • test/test_zx.cpp
  • src/EquivalenceCheckingManager.cpp
  • src/checker/dd/DDSimulationChecker.cpp
  • test/test_journal.cpp
  • include/checker/dd/simulation/StateGenerator.hpp
  • test/test_equality.cpp
  • include/checker/dd/DDAlternatingChecker.hpp
  • include/checker/EquivalenceChecker.hpp
  • src/checker/dd/applicationscheme/LookaheadApplicationScheme.cpp
  • bindings/state_type.cpp
  • include/checker/dd/DDConstructionChecker.hpp
  • include/checker/dd/applicationscheme/LookaheadApplicationScheme.hpp
  • test/test_compilationflow.cpp
  • test/test_symbolic.cpp
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2025-10-14T14:37:38.047Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/yaqs PR: 212
File: CHANGELOG.md:12-15
Timestamp: 2025-10-14T14:37:38.047Z
Learning: In the munich-quantum-toolkit/yaqs project, changelog entries follow the template: "- $TITLE ([#$NUMBER]($URL)) ([**AUTHOR**](https://github.com/$AUTHOR))". Issue references should not be included in changelog entries; the PR number is sufficient for traceability.

Applied to files:

  • test/python/test_symbolic.py
  • python/mqt/qcec/configuration_options.py
  • test/python/test_compilation_flow_profiles.py
  • src/CMakeLists.txt
  • test/python/test_configuration.py
  • test/CMakeLists.txt
  • python/mqt/qcec/__init__.py
  • cmake/cmake_uninstall.cmake.in
  • sitecustomize.py
  • test/python/test_dynamic_circuits.py
  • python/mqt/qcec/_compat/optional.py
  • test/python/test_verify_compilation.py
  • python/mqt/qcec/pyqcec.pyi
  • src/Configuration.cpp
  • python/mqt/qcec/compilation_flow_profiles.py
  • test/python/test_construction.py
  • python/mqt/qcec/_compat/typing.py
  • python/mqt/qcec/parameterized.py
  • test/test_journal.cpp
  • test/python/test_verify.py
  • .license-tools-config.json
  • python/mqt/qcec/verify_compilation_flow.py
  • docs/conf.py
  • test/python/test.py
  • python/mqt/qcec/_compat/__init__.py
  • test/python/test_partial_equivalence.py
  • cmake/ExternalDependencies.cmake
  • python/mqt/qcec/verify.py
  • python/mqt/qcec/_version.pyi
  • pyproject.toml
  • bindings/CMakeLists.txt
📚 Learning: 2025-12-15T01:59:17.023Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: python/mqt/core/ir/operations.pyi:9-16
Timestamp: 2025-12-15T01:59:17.023Z
Learning: In the munich-quantum-toolkit/core repository, stub files (.pyi) are auto-generated by nanobind's stubgen tool and should not be manually modified for style preferences, as changes would be overwritten during regeneration.

Applied to files:

  • test/python/test_symbolic.py
  • python/mqt/qcec/configuration_options.py
  • test/python/test_compilation_flow_profiles.py
  • src/CMakeLists.txt
  • test/python/test_configuration.py
  • test/CMakeLists.txt
  • python/mqt/qcec/__init__.py
  • cmake/cmake_uninstall.cmake.in
  • sitecustomize.py
  • test/python/test_dynamic_circuits.py
  • python/mqt/qcec/_compat/optional.py
  • test/python/test_verify_compilation.py
  • python/mqt/qcec/pyqcec.pyi
  • python/mqt/qcec/compilation_flow_profiles.py
  • test/python/test_construction.py
  • python/mqt/qcec/_compat/typing.py
  • python/mqt/qcec/parameterized.py
  • test/python/test_verify.py
  • python/mqt/qcec/verify_compilation_flow.py
  • docs/conf.py
  • test/python/test.py
  • python/mqt/qcec/_compat/__init__.py
  • bindings/state_type.cpp
  • test/python/test_partial_equivalence.py
  • cmake/ExternalDependencies.cmake
  • python/mqt/qcec/verify.py
  • bindings/bindings.cpp
  • python/mqt/qcec/_version.pyi
  • pyproject.toml
  • bindings/CMakeLists.txt
📚 Learning: 2026-01-09T16:51:12.629Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qcec PR: 816
File: python/mqt/qcec/__init__.py:20-20
Timestamp: 2026-01-09T16:51:12.629Z
Learning: In the munich-quantum-toolkit/qcec repository, RUF067 (non-empty-init-module) is a Ruff preview rule introduced in version 0.14.11 that flags non-empty __init__.py files. The `# noqa: RUF067` directive in python/mqt/qcec/__init__.py is necessary and correct to suppress warnings for legitimate code (like the Windows DLL patch).

Applied to files:

  • python/mqt/qcec/__init__.py
📚 Learning: 2025-12-15T01:54:22.129Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.

Applied to files:

  • .github/workflows/ci.yml
  • bindings/equivalence_criterion.cpp
  • bindings/state_type.cpp
  • cmake/ExternalDependencies.cmake
  • bindings/bindings.cpp
  • CMakeLists.txt
  • pyproject.toml
  • bindings/configuration.cpp
  • bindings/CMakeLists.txt
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2025-10-10T08:09:54.528Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: bindings/CMakeLists.txt:0-0
Timestamp: 2025-10-10T08:09:54.528Z
Learning: In the Munich Quantum Toolkit (MQT) Core project, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which automatically prefixes all CMake `DESTINATION` paths with `mqt/core/` during wheel installation. Therefore, CMake install destinations are relative to the `mqt/core` package namespace, not `site-packages`.

Applied to files:

  • .github/workflows/ci.yml
  • cmake/ExternalDependencies.cmake
  • CMakeLists.txt
  • pyproject.toml
  • bindings/CMakeLists.txt
📚 Learning: 2025-12-14T16:51:52.504Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 23
File: .readthedocs.yaml:13-18
Timestamp: 2025-12-14T16:51:52.504Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, LLVM and MLIR toolchains are required for the documentation build because `uv run` includes a full build of the package, which compiles C++/MLIR extensions using scikit-build-core.

Applied to files:

  • .github/workflows/ci.yml
  • pyproject.toml
📚 Learning: 2025-12-07T01:21:27.544Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.

Applied to files:

  • .github/workflows/ci.yml
  • bindings/state_type.cpp
  • bindings/bindings.cpp
  • pyproject.toml
  • bindings/configuration.cpp
  • bindings/CMakeLists.txt
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-22T01:25:21.609Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.

Applied to files:

  • bindings/equivalence_criterion.cpp
  • bindings/state_type.cpp
  • bindings/bindings.cpp
  • bindings/configuration.cpp
  • bindings/CMakeLists.txt
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-19T00:05:54.428Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.

Applied to files:

  • bindings/equivalence_criterion.cpp
  • bindings/state_type.cpp
  • bindings/bindings.cpp
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/application_scheme.cpp
📚 Learning: 2026-01-09T00:27:15.019Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 39
File: .pre-commit-config.yaml:135-135
Timestamp: 2026-01-09T00:27:15.019Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, `.pre-commit-config.yaml` intentionally uses `https://github.com/adhtruong/mirrors-typos` instead of the official `https://github.com/crate-ci/typos` repository to avoid pre-commit autoupdate tag confusion described in https://github.com/crate-ci/typos/issues/390.

Applied to files:

  • .pre-commit-config.yaml
📚 Learning: 2025-11-28T14:33:15.199Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1337
File: pyproject.toml:351-351
Timestamp: 2025-11-28T14:33:15.199Z
Learning: In the munich-quantum-toolkit/core repository, the dev dependency "ty==0.0.1a27" is intentionally pinned to an exact pre-release version. This dependency is used by the `ty-check` pre-commit hook (via `uv run --only-dev ty check`), and the exact pin ensures all developers run the same version, preventing unexpected issues from updates since ty is in alpha and changing rapidly.

Applied to files:

  • .pre-commit-config.yaml
  • pyproject.toml
📚 Learning: 2025-12-01T11:00:40.342Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 1
File: CHANGELOG.md:18-18
Timestamp: 2025-12-01T11:00:40.342Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, the CHANGELOG.md intentionally references the parent MQT Core repository's release notes (https://github.com/munich-quantum-toolkit/core/releases) because the plugin repository is based on work performed in the parent repository.

Applied to files:

  • docs/conf.py
📚 Learning: 2025-12-21T22:35:08.572Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:348-364
Timestamp: 2025-12-21T22:35:08.572Z
Learning: In the munich-quantum-toolkit/core repository's nanobind bindings, use `.sig("...")` on parameter arguments that have vector or container defaults (e.g., `"sites"_a.sig("...") = std::vector<fomac::Session::Device::Site>{}`) to prevent exposing mutable defaults in the Python API, which would be flagged as a code smell by Python linters. This pattern is preferred over removing `.sig("...")` even though it shows `...` in the stub signature.

Applied to files:

  • bindings/state_type.cpp
  • bindings/bindings.cpp
  • bindings/CMakeLists.txt
📚 Learning: 2025-12-28T17:14:53.890Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: src/qdmi/na/CMakeLists.txt:31-38
Timestamp: 2025-12-28T17:14:53.890Z
Learning: In the munich-quantum-toolkit/core repository, the NA device generator target (mqt-core-qdmi-na-device-gen) is intentionally propagated to MQT_CORE_TARGETS via list(APPEND) because it's publicly linked to the NA device library (the NA device uses a public function from the generator). The SC device generator is not propagated because it has no such dependency with the SC device library.

Applied to files:

  • cmake/ExternalDependencies.cmake
  • bindings/CMakeLists.txt
📚 Learning: 2025-10-10T08:10:16.394Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: test/python/na/test_na_fomac.py:35-0
Timestamp: 2025-10-10T08:10:16.394Z
Learning: In the munich-quantum-toolkit/core repository, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which means CMake `install()` commands with `DESTINATION <path>` install files relative to `mqt/core/` in the wheel, making them accessible via `files("mqt.core").joinpath("<path>")`.

Applied to files:

  • cmake/ExternalDependencies.cmake
  • pyproject.toml
  • bindings/CMakeLists.txt
📚 Learning: 2025-12-05T15:57:39.701Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 3
File: lib/Conversion/CatalystQuantumToMQTOpt/CMakeLists.txt:22-25
Timestamp: 2025-12-05T15:57:39.701Z
Learning: The munich-quantum-toolkit projects (core and core-plugins-catalyst) use `file(GLOB_RECURSE ...)` patterns in CMakeLists.txt files to collect header files, following an established convention in the parent repository for consistency across the codebase.

Applied to files:

  • cmake/ExternalDependencies.cmake
  • bindings/CMakeLists.txt
📚 Learning: 2025-11-03T23:09:26.881Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1287
File: test/qdmi/dd/CMakeLists.txt:9-21
Timestamp: 2025-11-03T23:09:26.881Z
Learning: The CMake functions `generate_device_defs_executable` and `generate_prefixed_qdmi_headers` used in QDMI device test CMakeLists.txt files are provided by the external QDMI library (fetched via FetchContent from https://github.com/Munich-Quantum-Software-Stack/qdmi.git), specifically in the cmake/PrefixHandling.cmake module of the QDMI repository.

Applied to files:

  • cmake/ExternalDependencies.cmake
  • CMakeLists.txt
📚 Learning: 2025-11-04T15:22:19.558Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:155-157
Timestamp: 2025-11-04T15:22:19.558Z
Learning: The munich-quantum-toolkit/core repository requires Python 3.10 or later, so Python 3.10+ features (such as `zip(..., strict=...)`, pattern matching, etc.) are acceptable and should not be flagged as compatibility issues.

Applied to files:

  • CMakeLists.txt
  • pyproject.toml
📚 Learning: 2025-12-13T20:08:45.549Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 862
File: pyproject.toml:65-66
Timestamp: 2025-12-13T20:08:45.549Z
Learning: In the qmap project (pyproject.toml), maintain broad compatibility with dependencies across supported Python versions. Avoid artificially raising minimum version requirements unless there's a specific need (e.g., to guarantee binary wheel availability for certain Python versions, or to access required features). The goal is to keep the software as broadly compatible as possible with the rest of the ecosystem.

Applied to files:

  • CMakeLists.txt
  • pyproject.toml
📚 Learning: 2025-12-28T17:13:36.900Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: pyproject.toml:98-102
Timestamp: 2025-12-28T17:13:36.900Z
Learning: In the munich-quantum-toolkit/core project, scikit-build-core is intelligent enough to skip build targets listed in pyproject.toml that don't exist for a given platform, so platform-specific targets (like `-dyn` targets conditioned on `NOT WIN32`) can be unconditionally listed in `build.targets` without causing Windows build failures.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-10-11T19:39:32.050Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/debugger PR: 160
File: pyproject.toml:54-54
Timestamp: 2025-10-11T19:39:32.050Z
Learning: Qiskit packages use cp39-abi3 wheels (stable ABI) which are forward-compatible with Python 3.9+ including Python 3.14, even if the package classifiers don't explicitly list Python 3.14 support.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-10-09T22:15:59.924Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-10-13T00:03:08.078Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/debugger PR: 160
File: pyproject.toml:252-256
Timestamp: 2025-10-13T00:03:08.078Z
Learning: In uv's `override-dependencies`, multiple entries for the same package with different environment markers (or one without a marker and one with a specific marker) can coexist. uv correctly resolves these by applying the appropriate constraint based on the active Python version. For example, `["symengine>=0.11,<0.14", "symengine>=0.14.1; python_version >= '3.14'"]` is valid and will apply the second constraint on Python 3.14+.

Applied to files:

  • pyproject.toml
🧬 Code graph analysis (2)
bindings/configuration.cpp (1)
src/Configuration.cpp (2)
  • toString (109-112)
  • toString (109-109)
bindings/equivalence_checking_manager.cpp (1)
python/mqt/qcec/pyqcec.pyi (3)
  • results (341-342)
  • Configuration (64-312)
  • equivalence (345-346)
🪛 Cppcheck (2.19.0)
bindings/equivalence_criterion.cpp

[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[style] 21-21: The function 'registerEquivalenceCriterion' is never used.

(unusedFunction)

bindings/state_type.cpp

[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[style] 21-21: The function 'registerStateType' is never used.

(unusedFunction)

bindings/bindings.cpp

[information] 11-11: Include file

(missingIncludeSystem)


[error] 26-26: syntax error

(syntaxError)

bindings/configuration.cpp

[information] 13-13: Include file

(missingInclude)


[information] 14-14: Include file

(missingInclude)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[style] 22-22: The function 'registerConfiguration' is never used.

(unusedFunction)


[style] 39-39: The function 'reset' is never used.

(unusedFunction)


[style] 48-48: The function 'getInternalState' is never used.

(unusedFunction)


[style] 51-51: The function 'setInternalState' is never used.

(unusedFunction)


[style] 52-52: The function 'flipDirection' is never used.

(unusedFunction)


[style] 71-71: The function 'getIterator' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

bindings/equivalence_checking_manager.cpp

[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 20-20: Include file

(missingInclude)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingInclude)


[information] 22-22: Include file

(missingInclude)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 27-27: Include file

(missingIncludeSystem)


[information] 28-28: Include file

(missingIncludeSystem)


[information] 29-29: Include file

(missingIncludeSystem)


[information] 30-30: Include file

(missingIncludeSystem)


[information] 31-31: Include file

(missingIncludeSystem)


[information] 32-32: Include file

(missingIncludeSystem)


[information] 33-33: Include file

(missingIncludeSystem)


[information] 34-34: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[style] 27-27: The function 'registerEquivalenceCheckingManager' is never used.

(unusedFunction)


[style] 27-27: The function 'waitAndPop' is never used.

(unusedFunction)


[style] 34-34: The function 'waitAndPopUntil' is never used.

(unusedFunction)


[style] 37-37: The function 'getEquivalence' is never used.

(unusedFunction)


[style] 40-40: The function 'getRuntime' is never used.

(unusedFunction)


[style] 37-37: The function 'getInitialState' is never used.

(unusedFunction)


[style] 41-41: The function 'getInternalState1' is never used.

(unusedFunction)


[style] 80-80: The function 'reset' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

bindings/application_scheme.cpp

[information] 13-13: Include file

(missingInclude)


[information] 14-14: Include file

(missingInclude)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[style] 21-21: The function 'registerApplicationSchema' is never used.

(unusedFunction)

🪛 Ruff (0.14.10)
python/mqt/qcec/__init__.py

20-20: Unused noqa directive (unknown: RUF067)

Remove unused noqa directive

(RUF100)

Base automatically changed from config-updates to main January 9, 2026 17:14
@codecov
Copy link

codecov bot commented Jan 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bindings/equivalence_checking_manager.cpp (1)

39-47: Fix checker_results JSON conversion (currently broken) and add unused-variable warning mitigation.

The setter at lines 87–97 has two critical issues: (1) dumps is imported on line 94 but never used—likely causing compilation failure with -Werror; (2) nb::str(value) on a Python dict produces a repr (e.g., {'key': value} with single quotes) which is not valid JSON, so nlohmann::json::parse() will fail at runtime. Use Python's json.dumps() to serialize the dict to a valid JSON string, and use json.loads() to deserialize back.

Add explicit nb::rv_policy::reference_internal to properties returning internal references (qc1, qc2, results). These methods return const auto& to internal state; without explicit lifetime policy, Python may retain stale references after the parent is deleted. Per nanobind migration guidelines, reference_internal keeps the parent alive while children exist.

Avoid relying on implicit nb::cast(nlohmann::json) without an explicit type caster. The codebase contains no type_caster for nlohmann::json, so casting on lines 89 and 73 is fragile. Use JSON string round-trip via results.json().dump() + json.loads() instead.

Proposed patch
   // Access to circuits
-  ecm.def_prop_ro("qc1", &EquivalenceCheckingManager::getFirstCircuit);
-  ecm.def_prop_ro("qc2", &EquivalenceCheckingManager::getSecondCircuit);
+  ecm.def_prop_ro("qc1", &EquivalenceCheckingManager::getFirstCircuit,
+                  nb::rv_policy::reference_internal);
+  ecm.def_prop_ro("qc2", &EquivalenceCheckingManager::getSecondCircuit,
+                  nb::rv_policy::reference_internal);

   // Access to configuration
   ecm.def_prop_rw(
       "configuration", &EquivalenceCheckingManager::getConfiguration,
       [](EquivalenceCheckingManager& manager, const Configuration& config) {
         manager.getConfiguration() = config;
       });

   // Run
   ecm.def("run", &EquivalenceCheckingManager::run);

   // Results
-  ecm.def_prop_ro("results", &EquivalenceCheckingManager::getResults);
+  ecm.def_prop_ro("results", &EquivalenceCheckingManager::getResults,
+                  nb::rv_policy::reference_internal);
@@
       .def_prop_rw(
           "checker_results",
           [](const EquivalenceCheckingManager::Results& results) {
+            nb::module_ json = nb::module_::import_("json");
+            nb::object loads = json.attr("loads");
+            return loads(results.checkerResults.dump());
-            return nb::cast(results.checkerResults);
           },
           [](EquivalenceCheckingManager::Results& results,
              const nb::dict& value) {
             nb::module_ json = nb::module_::import_("json");
             nb::object dumps = json.attr("dumps");
-            const auto jsonString = nb::cast<std::string>(nb::str(value));
+            const auto jsonString = nb::cast<std::string>(dumps(value));
             results.checkerResults = nlohmann::json::parse(jsonString);
           })
       .def("considered_equivalent",
            &EquivalenceCheckingManager::Results::consideredEquivalent)
       .def("json",
            [](const EquivalenceCheckingManager::Results& results) {
+            nb::module_ json = nb::module_::import_("json");
+            nb::object loads = json.attr("loads");
+            return loads(results.json().dump());
-            return nb::cast(results.json());
            })

Also applies to: lines 53–55 (results property), 71–74 (json() method).

🤖 Fix all issues with AI agents
In @UPGRADING.md:
- Around line 7-25: In the "### Python wheels" section, add one explicit
sentence stating that Python 3.13 (non-`t`) is covered by the "3.12+ Stable ABI"
wheel so readers don’t assume 3.13 is unsupported; update the paragraph after
the sentence "First, we have removed all wheels for Python 3.13t." to say
something like "Note: Python 3.13 (non-`t`) is supported via the 3.12+ Stable
ABI wheel." to make the mapping unambiguous.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a042e3 and 5f7e9c3.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • UPGRADING.md
  • bindings/bindings.cpp
  • bindings/equivalence_checking_manager.cpp
  • pyproject.toml
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
📚 Learning: 2025-10-09T22:15:59.924Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.

Applied to files:

  • UPGRADING.md
  • pyproject.toml
📚 Learning: 2025-10-11T19:39:32.050Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/debugger PR: 160
File: pyproject.toml:54-54
Timestamp: 2025-10-11T19:39:32.050Z
Learning: Qiskit packages use cp39-abi3 wheels (stable ABI) which are forward-compatible with Python 3.9+ including Python 3.14, even if the package classifiers don't explicitly list Python 3.14 support.

Applied to files:

  • UPGRADING.md
  • pyproject.toml
📚 Learning: 2025-12-05T17:45:37.602Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1360
File: .github/workflows/reusable-mlir-tests.yml:40-43
Timestamp: 2025-12-05T17:45:37.602Z
Learning: In the munich-quantum-toolkit/core repository, patch releases of LLVM dependencies don't require documentation updates, changelog entries, or additional tests beyond what's validated by passing CI checks.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-10-14T14:37:38.047Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/yaqs PR: 212
File: CHANGELOG.md:12-15
Timestamp: 2025-10-14T14:37:38.047Z
Learning: In the munich-quantum-toolkit/yaqs project, changelog entries follow the template: "- $TITLE ([#$NUMBER]($URL)) ([**AUTHOR**](https://github.com/$AUTHOR))". Issue references should not be included in changelog entries; the PR number is sufficient for traceability.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-12-01T11:00:40.342Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 1
File: CHANGELOG.md:18-18
Timestamp: 2025-12-01T11:00:40.342Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, the CHANGELOG.md intentionally references the parent MQT Core repository's release notes (https://github.com/munich-quantum-toolkit/core/releases) because the plugin repository is based on work performed in the parent repository.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-12-15T01:54:22.129Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.

Applied to files:

  • CHANGELOG.md
  • bindings/bindings.cpp
  • pyproject.toml
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-07T01:21:27.544Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.

Applied to files:

  • CHANGELOG.md
  • bindings/bindings.cpp
  • pyproject.toml
📚 Learning: 2025-11-04T15:22:19.558Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:155-157
Timestamp: 2025-11-04T15:22:19.558Z
Learning: The munich-quantum-toolkit/core repository requires Python 3.10 or later, so Python 3.10+ features (such as `zip(..., strict=...)`, pattern matching, etc.) are acceptable and should not be flagged as compatibility issues.

Applied to files:

  • CHANGELOG.md
  • pyproject.toml
📚 Learning: 2025-12-15T01:59:17.023Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: python/mqt/core/ir/operations.pyi:9-16
Timestamp: 2025-12-15T01:59:17.023Z
Learning: In the munich-quantum-toolkit/core repository, stub files (.pyi) are auto-generated by nanobind's stubgen tool and should not be manually modified for style preferences, as changes would be overwritten during regeneration.

Applied to files:

  • CHANGELOG.md
  • bindings/bindings.cpp
📚 Learning: 2025-12-22T01:25:21.609Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.

Applied to files:

  • bindings/bindings.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-19T00:05:54.428Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.

Applied to files:

  • bindings/bindings.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-21T22:35:08.572Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:348-364
Timestamp: 2025-12-21T22:35:08.572Z
Learning: In the munich-quantum-toolkit/core repository's nanobind bindings, use `.sig("...")` on parameter arguments that have vector or container defaults (e.g., `"sites"_a.sig("...") = std::vector<fomac::Session::Device::Site>{}`) to prevent exposing mutable defaults in the Python API, which would be flagged as a code smell by Python linters. This pattern is preferred over removing `.sig("...")` even though it shows `...` in the stub signature.

Applied to files:

  • bindings/bindings.cpp
📚 Learning: 2025-12-13T20:08:45.549Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 862
File: pyproject.toml:65-66
Timestamp: 2025-12-13T20:08:45.549Z
Learning: In the qmap project (pyproject.toml), maintain broad compatibility with dependencies across supported Python versions. Avoid artificially raising minimum version requirements unless there's a specific need (e.g., to guarantee binary wheel availability for certain Python versions, or to access required features). The goal is to keep the software as broadly compatible as possible with the rest of the ecosystem.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-10-10T08:09:54.528Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: bindings/CMakeLists.txt:0-0
Timestamp: 2025-10-10T08:09:54.528Z
Learning: In the Munich Quantum Toolkit (MQT) Core project, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which automatically prefixes all CMake `DESTINATION` paths with `mqt/core/` during wheel installation. Therefore, CMake install destinations are relative to the `mqt/core` package namespace, not `site-packages`.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-11-27T21:22:11.330Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 846
File: pyproject.toml:213-214
Timestamp: 2025-11-27T21:22:11.330Z
Learning: In the qmap project (pyproject.toml), the maintainers intentionally enable `unsafe-fixes = true` in the ruff configuration. This is an established practice that has worked well for the project, with the expectation that PR authors review any automated fixes.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-12-28T17:13:36.900Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: pyproject.toml:98-102
Timestamp: 2025-12-28T17:13:36.900Z
Learning: In the munich-quantum-toolkit/core project, scikit-build-core is intelligent enough to skip build targets listed in pyproject.toml that don't exist for a given platform, so platform-specific targets (like `-dyn` targets conditioned on `NOT WIN32`) can be unconditionally listed in `build.targets` without causing Windows build failures.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-10-10T08:10:16.394Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: test/python/na/test_na_fomac.py:35-0
Timestamp: 2025-10-10T08:10:16.394Z
Learning: In the munich-quantum-toolkit/core repository, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which means CMake `install()` commands with `DESTINATION <path>` install files relative to `mqt/core/` in the wheel, making them accessible via `files("mqt.core").joinpath("<path>")`.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-12-14T16:51:52.504Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 23
File: .readthedocs.yaml:13-18
Timestamp: 2025-12-14T16:51:52.504Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, LLVM and MLIR toolchains are required for the documentation build because `uv run` includes a full build of the package, which compiles C++/MLIR extensions using scikit-build-core.

Applied to files:

  • pyproject.toml
🧬 Code graph analysis (1)
bindings/equivalence_checking_manager.cpp (3)
src/Configuration.cpp (2)
  • json (58-107)
  • json (58-58)
src/checker/EquivalenceChecker.cpp (2)
  • json (20-23)
  • json (20-20)
src/EquivalenceCheckingManager.cpp (2)
  • json (884-901)
  • json (884-884)
🪛 Cppcheck (2.19.0)
bindings/bindings.cpp

[information] 11-11: Include file

(missingIncludeSystem)


[error] 25-25: syntax error

(syntaxError)

bindings/equivalence_checking_manager.cpp

[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 20-20: Include file

(missingInclude)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingInclude)


[information] 22-22: Include file

(missingInclude)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 27-27: Include file

(missingIncludeSystem)


[information] 28-28: Include file

(missingIncludeSystem)


[information] 29-29: Include file

(missingIncludeSystem)


[information] 30-30: Include file

(missingIncludeSystem)


[information] 31-31: Include file

(missingIncludeSystem)


[information] 32-32: Include file

(missingIncludeSystem)


[information] 33-33: Include file

(missingIncludeSystem)


[information] 34-34: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[style] 26-26: The function 'registerEquivalenceCheckingManager' is never used.

(unusedFunction)


[style] 27-27: The function 'waitAndPop' is never used.

(unusedFunction)


[style] 34-34: The function 'waitAndPopUntil' is never used.

(unusedFunction)


[style] 37-37: The function 'getEquivalence' is never used.

(unusedFunction)


[style] 40-40: The function 'getRuntime' is never used.

(unusedFunction)


[style] 37-37: The function 'getInitialState' is never used.

(unusedFunction)


[style] 41-41: The function 'getInternalState1' is never used.

(unusedFunction)


[style] 80-80: The function 'reset' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

🔇 Additional comments (2)
CHANGELOG.md (1)

14-16: Changelog entries look consistent with existing style.

Also applies to: 118-118

bindings/bindings.cpp (1)

11-32: No action needed. The code is correct as-is.

Nanobind delegates free-threading support to the CMake build system via the FREE_THREADED flag in nanobind_add_module(), not through explicit GIL declarations in the module init code like pybind11 used. The custom add_mqt_python_binding_nanobind() macro (provided by MQT Core ≥3.4.0) handles the build-time configuration. The standard NB_MODULE() macro works correctly with free-threaded builds when properly configured at build time. The project already distributes Python 3.14t wheels, confirming free-threading support is functional.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @bindings/configuration.cpp:
- Around line 51-113: The nested nanobind class bindings (Execution,
Optimizations, Application, Functionality, Simulation, Parameterized) lack
Python docstrings; add concise docstrings for each nb::class_ and for their
fields (e.g., Execution: parallel, nthreads, timeout, runConstructionChecker,
runSimulationChecker, runAlternatingChecker, runZXChecker, numericalTolerance,
setAllAncillaeGarbage; Optimizations: fuseSingleQubitGates, reconstructSWAPs,
removeDiagonalGatesBeforeMeasure, transformDynamicCircuit, reorderOperations,
backpropagateOutputPermutation, elidePermutations; Application:
constructionScheme, simulationScheme, alternatingScheme, profile; Functionality:
traceThreshold, checkPartialEquivalence; Simulation: fidelityThreshold, maxSims,
stateType, seed; Parameterized: parameterizedTol, nAdditionalInstantiations) by
supplying R"pb(... )pb" strings in the binding code (either in the nb::class_
constructor or immediately after creation) so the Python API surfaces helpful
documentation for each class and field.

In @bindings/equivalence_checking_manager.cpp:
- Around line 40-41: The property bindings for qc1 and qc2 use ecm.def_prop_ro
with EquivalenceCheckingManager::getFirstCircuit and ::getSecondCircuit but omit
a return-value policy; update both calls to pass
nb::rv_policy::reference_internal so Python-held references to the returned
QuantumComputation objects keep the parent EquivalenceCheckingManager alive
(i.e., change the two ecm.def_prop_ro invocations to include
nb::rv_policy::reference_internal as the third argument).

In @cmake/ExternalDependencies.cmake:
- Around line 36-40: The MQT Core version variables (MQT_CORE_MINIMUM_VERSION
and MQT_CORE_VERSION) point to a non-existent 3.4.0 release and the MQT_CORE_REV
is therefore invalid; change both MQT_CORE_MINIMUM_VERSION and MQT_CORE_VERSION
to a real release (e.g., 3.3.3) and update MQT_CORE_REV to the commit hash or
tag that corresponds to the 3.3.3 release on the MQT Core repository so the
version and revision match an actual published release.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7e9c3 and dbe593a.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • CMakeLists.txt
  • UPGRADING.md
  • bindings/CMakeLists.txt
  • bindings/application_scheme.cpp
  • bindings/bindings.cpp
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/equivalence_criterion.cpp
  • bindings/state_type.cpp
  • cmake/ExternalDependencies.cmake
  • pyproject.toml
🧰 Additional context used
🧠 Learnings (23)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.
📚 Learning: 2025-12-15T01:54:22.129Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.

Applied to files:

  • .github/workflows/ci.yml
  • bindings/CMakeLists.txt
  • UPGRADING.md
  • bindings/application_scheme.cpp
  • bindings/equivalence_criterion.cpp
  • bindings/bindings.cpp
  • CHANGELOG.md
  • cmake/ExternalDependencies.cmake
  • bindings/equivalence_checking_manager.cpp
  • bindings/state_type.cpp
  • bindings/configuration.cpp
  • pyproject.toml
📚 Learning: 2025-10-10T08:09:54.528Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: bindings/CMakeLists.txt:0-0
Timestamp: 2025-10-10T08:09:54.528Z
Learning: In the Munich Quantum Toolkit (MQT) Core project, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which automatically prefixes all CMake `DESTINATION` paths with `mqt/core/` during wheel installation. Therefore, CMake install destinations are relative to the `mqt/core` package namespace, not `site-packages`.

Applied to files:

  • .github/workflows/ci.yml
  • bindings/CMakeLists.txt
  • CMakeLists.txt
  • cmake/ExternalDependencies.cmake
  • pyproject.toml
📚 Learning: 2025-10-09T13:14:10.178Z
Learnt from: DRovara
Repo: munich-quantum-toolkit/core PR: 1108
File: mlir/lib/Dialect/MQTOpt/Transforms/ReplaceBasisStateControlsWithIfPattern.cpp:219-221
Timestamp: 2025-10-09T13:14:10.178Z
Learning: The MQT Core project (munich-quantum-toolkit/core repository) uses the C++20 standard, not C++17. C++20 features such as abbreviated function templates (e.g., `const auto&` parameters) are supported and valid in this codebase.

Applied to files:

  • .github/workflows/ci.yml
  • CMakeLists.txt
  • cmake/ExternalDependencies.cmake
📚 Learning: 2025-12-14T16:51:52.504Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 23
File: .readthedocs.yaml:13-18
Timestamp: 2025-12-14T16:51:52.504Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, LLVM and MLIR toolchains are required for the documentation build because `uv run` includes a full build of the package, which compiles C++/MLIR extensions using scikit-build-core.

Applied to files:

  • .github/workflows/ci.yml
  • pyproject.toml
📚 Learning: 2025-12-07T01:21:27.544Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.

Applied to files:

  • .github/workflows/ci.yml
  • bindings/CMakeLists.txt
  • bindings/bindings.cpp
  • bindings/state_type.cpp
  • pyproject.toml
📚 Learning: 2025-12-21T22:35:08.572Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:348-364
Timestamp: 2025-12-21T22:35:08.572Z
Learning: In the munich-quantum-toolkit/core repository's nanobind bindings, use `.sig("...")` on parameter arguments that have vector or container defaults (e.g., `"sites"_a.sig("...") = std::vector<fomac::Session::Device::Site>{}`) to prevent exposing mutable defaults in the Python API, which would be flagged as a code smell by Python linters. This pattern is preferred over removing `.sig("...")` even though it shows `...` in the stub signature.

Applied to files:

  • bindings/CMakeLists.txt
📚 Learning: 2025-12-22T01:25:21.609Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.

Applied to files:

  • bindings/CMakeLists.txt
  • bindings/equivalence_criterion.cpp
  • bindings/bindings.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/state_type.cpp
  • bindings/configuration.cpp
📚 Learning: 2025-12-28T17:14:53.890Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: src/qdmi/na/CMakeLists.txt:31-38
Timestamp: 2025-12-28T17:14:53.890Z
Learning: In the munich-quantum-toolkit/core repository, the NA device generator target (mqt-core-qdmi-na-device-gen) is intentionally propagated to MQT_CORE_TARGETS via list(APPEND) because it's publicly linked to the NA device library (the NA device uses a public function from the generator). The SC device generator is not propagated because it has no such dependency with the SC device library.

Applied to files:

  • bindings/CMakeLists.txt
  • cmake/ExternalDependencies.cmake
📚 Learning: 2025-12-05T15:57:39.701Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 3
File: lib/Conversion/CatalystQuantumToMQTOpt/CMakeLists.txt:22-25
Timestamp: 2025-12-05T15:57:39.701Z
Learning: The munich-quantum-toolkit projects (core and core-plugins-catalyst) use `file(GLOB_RECURSE ...)` patterns in CMakeLists.txt files to collect header files, following an established convention in the parent repository for consistency across the codebase.

Applied to files:

  • bindings/CMakeLists.txt
  • cmake/ExternalDependencies.cmake
📚 Learning: 2025-10-10T08:10:16.394Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: test/python/na/test_na_fomac.py:35-0
Timestamp: 2025-10-10T08:10:16.394Z
Learning: In the munich-quantum-toolkit/core repository, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which means CMake `install()` commands with `DESTINATION <path>` install files relative to `mqt/core/` in the wheel, making them accessible via `files("mqt.core").joinpath("<path>")`.

Applied to files:

  • bindings/CMakeLists.txt
  • cmake/ExternalDependencies.cmake
  • pyproject.toml
📚 Learning: 2025-12-15T01:59:17.023Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: python/mqt/core/ir/operations.pyi:9-16
Timestamp: 2025-12-15T01:59:17.023Z
Learning: In the munich-quantum-toolkit/core repository, stub files (.pyi) are auto-generated by nanobind's stubgen tool and should not be manually modified for style preferences, as changes would be overwritten during regeneration.

Applied to files:

  • bindings/CMakeLists.txt
  • bindings/bindings.cpp
  • bindings/state_type.cpp
📚 Learning: 2025-10-09T22:15:59.924Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.

Applied to files:

  • UPGRADING.md
  • pyproject.toml
📚 Learning: 2025-10-11T19:39:32.050Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/debugger PR: 160
File: pyproject.toml:54-54
Timestamp: 2025-10-11T19:39:32.050Z
Learning: Qiskit packages use cp39-abi3 wheels (stable ABI) which are forward-compatible with Python 3.9+ including Python 3.14, even if the package classifiers don't explicitly list Python 3.14 support.

Applied to files:

  • UPGRADING.md
  • pyproject.toml
📚 Learning: 2025-12-19T00:05:54.428Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.

Applied to files:

  • bindings/equivalence_criterion.cpp
  • bindings/bindings.cpp
  • bindings/equivalence_checking_manager.cpp
  • bindings/state_type.cpp
  • bindings/configuration.cpp
📚 Learning: 2025-12-05T17:45:37.602Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1360
File: .github/workflows/reusable-mlir-tests.yml:40-43
Timestamp: 2025-12-05T17:45:37.602Z
Learning: In the munich-quantum-toolkit/core repository, patch releases of LLVM dependencies don't require documentation updates, changelog entries, or additional tests beyond what's validated by passing CI checks.

Applied to files:

  • CMakeLists.txt
  • CHANGELOG.md
  • cmake/ExternalDependencies.cmake
📚 Learning: 2025-10-14T14:37:38.047Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/yaqs PR: 212
File: CHANGELOG.md:12-15
Timestamp: 2025-10-14T14:37:38.047Z
Learning: In the munich-quantum-toolkit/yaqs project, changelog entries follow the template: "- $TITLE ([#$NUMBER]($URL)) ([**AUTHOR**](https://github.com/$AUTHOR))". Issue references should not be included in changelog entries; the PR number is sufficient for traceability.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-12-01T11:00:40.342Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 1
File: CHANGELOG.md:18-18
Timestamp: 2025-12-01T11:00:40.342Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, the CHANGELOG.md intentionally references the parent MQT Core repository's release notes (https://github.com/munich-quantum-toolkit/core/releases) because the plugin repository is based on work performed in the parent repository.

Applied to files:

  • CHANGELOG.md
  • cmake/ExternalDependencies.cmake
📚 Learning: 2025-11-04T15:22:19.558Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:155-157
Timestamp: 2025-11-04T15:22:19.558Z
Learning: The munich-quantum-toolkit/core repository requires Python 3.10 or later, so Python 3.10+ features (such as `zip(..., strict=...)`, pattern matching, etc.) are acceptable and should not be flagged as compatibility issues.

Applied to files:

  • CHANGELOG.md
  • pyproject.toml
📚 Learning: 2025-11-03T23:09:26.881Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1287
File: test/qdmi/dd/CMakeLists.txt:9-21
Timestamp: 2025-11-03T23:09:26.881Z
Learning: The CMake functions `generate_device_defs_executable` and `generate_prefixed_qdmi_headers` used in QDMI device test CMakeLists.txt files are provided by the external QDMI library (fetched via FetchContent from https://github.com/Munich-Quantum-Software-Stack/qdmi.git), specifically in the cmake/PrefixHandling.cmake module of the QDMI repository.

Applied to files:

  • cmake/ExternalDependencies.cmake
📚 Learning: 2025-12-13T20:08:45.549Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 862
File: pyproject.toml:65-66
Timestamp: 2025-12-13T20:08:45.549Z
Learning: In the qmap project (pyproject.toml), maintain broad compatibility with dependencies across supported Python versions. Avoid artificially raising minimum version requirements unless there's a specific need (e.g., to guarantee binary wheel availability for certain Python versions, or to access required features). The goal is to keep the software as broadly compatible as possible with the rest of the ecosystem.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-11-27T21:22:11.330Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 846
File: pyproject.toml:213-214
Timestamp: 2025-11-27T21:22:11.330Z
Learning: In the qmap project (pyproject.toml), the maintainers intentionally enable `unsafe-fixes = true` in the ruff configuration. This is an established practice that has worked well for the project, with the expectation that PR authors review any automated fixes.

Applied to files:

  • pyproject.toml
📚 Learning: 2025-12-28T17:13:36.900Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: pyproject.toml:98-102
Timestamp: 2025-12-28T17:13:36.900Z
Learning: In the munich-quantum-toolkit/core project, scikit-build-core is intelligent enough to skip build targets listed in pyproject.toml that don't exist for a given platform, so platform-specific targets (like `-dyn` targets conditioned on `NOT WIN32`) can be unconditionally listed in `build.targets` without causing Windows build failures.

Applied to files:

  • pyproject.toml
🧬 Code graph analysis (2)
bindings/bindings.cpp (5)
bindings/application_scheme.cpp (2)
  • registerApplicationSchema (21-37)
  • registerApplicationSchema (21-21)
bindings/configuration.cpp (2)
  • registerConfiguration (22-114)
  • registerConfiguration (22-22)
bindings/equivalence_checking_manager.cpp (2)
  • registerEquivalenceCheckingManager (27-110)
  • registerEquivalenceCheckingManager (27-27)
bindings/equivalence_criterion.cpp (2)
  • registerEquivalenceCriterion (21-34)
  • registerEquivalenceCriterion (21-21)
bindings/state_type.cpp (2)
  • registerStateType (21-29)
  • registerStateType (21-21)
bindings/configuration.cpp (2)
python/mqt/qcec/pyqcec.pyi (2)
  • configuration (332-332)
  • configuration (334-335)
src/Configuration.cpp (2)
  • toString (109-112)
  • toString (109-109)
🪛 Cppcheck (2.19.0)
bindings/application_scheme.cpp

[information] 13-13: Include file

(missingInclude)


[information] 14-14: Include file

(missingInclude)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[style] 21-21: The function 'registerApplicationSchema' is never used.

(unusedFunction)

bindings/equivalence_criterion.cpp

[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[style] 21-21: The function 'registerEquivalenceCriterion' is never used.

(unusedFunction)

bindings/bindings.cpp

[information] 11-11: Include file

(missingIncludeSystem)


[error] 26-26: syntax error

(syntaxError)

bindings/equivalence_checking_manager.cpp

[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 20-20: Include file

(missingInclude)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingInclude)


[information] 22-22: Include file

(missingInclude)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 27-27: Include file

(missingIncludeSystem)


[information] 28-28: Include file

(missingIncludeSystem)


[information] 29-29: Include file

(missingIncludeSystem)


[information] 30-30: Include file

(missingIncludeSystem)


[information] 31-31: Include file

(missingIncludeSystem)


[information] 32-32: Include file

(missingIncludeSystem)


[information] 33-33: Include file

(missingIncludeSystem)


[information] 34-34: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[style] 27-27: The function 'registerEquivalenceCheckingManager' is never used.

(unusedFunction)


[style] 27-27: The function 'waitAndPop' is never used.

(unusedFunction)


[style] 34-34: The function 'waitAndPopUntil' is never used.

(unusedFunction)


[style] 37-37: The function 'getEquivalence' is never used.

(unusedFunction)


[style] 40-40: The function 'getRuntime' is never used.

(unusedFunction)


[style] 37-37: The function 'getInitialState' is never used.

(unusedFunction)


[style] 41-41: The function 'getInternalState1' is never used.

(unusedFunction)


[style] 80-80: The function 'reset' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

bindings/state_type.cpp

[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[style] 21-21: The function 'registerStateType' is never used.

(unusedFunction)

bindings/configuration.cpp

[information] 13-13: Include file

(missingInclude)


[information] 14-14: Include file

(missingInclude)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[style] 22-22: The function 'registerConfiguration' is never used.

(unusedFunction)


[style] 39-39: The function 'reset' is never used.

(unusedFunction)


[style] 48-48: The function 'getInternalState' is never used.

(unusedFunction)


[style] 51-51: The function 'setInternalState' is never used.

(unusedFunction)


[style] 52-52: The function 'flipDirection' is never used.

(unusedFunction)


[style] 71-71: The function 'getIterator' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 🇨‌ Test 🏁 (windows-11-arm, msvc, Release) / 🏁 windows-11-arm msvc Release
  • GitHub Check: 🇨‌ Coverage / 📈 Coverage
  • GitHub Check: 🇨‌ Lint / 🚨 Lint
🔇 Additional comments (23)
.github/workflows/ci.yml (1)

151-151: LGTM! Nanobind version is consistent with pyproject.toml.

The update correctly replaces pybind11==3.0.1 with nanobind==2.10.2, matching the version specified in the build-system requirements and dependency groups in pyproject.toml.

CHANGELOG.md (2)

14-16: LGTM! Changelog entries follow project conventions.

The three changelog entries correctly describe the migration to nanobind, introduction of Stable ABI wheels, and mqt-core version bump. The format follows the established template with proper emoji prefixes, PR references, and author attribution.


118-118: LGTM! PR link correctly added.

The PR reference link is properly formatted and placed in the PR links section.

UPGRADING.md (1)

7-24: LGTM! Documentation clearly explains the wheel distribution changes.

The updated section appropriately expands the scope from just removal of 3.13t wheels to cover both that removal and the introduction of Stable ABI wheels for Python 3.12+. The explanation clearly attributes the Stable ABI capability to the nanobind migration and accurately lists the distributed wheel variants.

pyproject.toml (4)

81-82: LGTM! Stable ABI configuration correctly set.

The wheel.py-api = "cp312" setting properly enables Stable ABI builds for CPython 3.12+, as described in the PR objectives and documentation. Based on learnings from the mqt-core repository's nanobind migration, this is the correct configuration for nanobind-based Stable ABI wheels.


335-340: LGTM! Shared library exclusions updated for mqt-core 3.4.

The repair-wheel exclusions correctly reference the 3.4 series of mqt-core shared libraries, matching the updated dependency version. This ensures the wheel repair process doesn't vendor these libraries, which should be provided by the mqt.core Python package.


31-31: Remove or reframe this review comment.

The repository contains only one commit, and there is no previous version to compare against. The Development Status classifier cannot be a change from a prior value since this is the initial state. The review comment's premise—that this was "changed from the previous value" during "migration"—is not supported by the codebase history. If the concern is whether "Production/Stable" status is appropriate for the project, that should be addressed directly rather than framed as verifying an accidental change.

Likely an incorrect or invalid review comment.


11-11: nanobind 2.10.2 and mqt.core 3.4.0 are valid, published versions.

Both versions exist on PyPI and are correctly specified across build-system requirements and runtime dependencies.

cmake/ExternalDependencies.cmake (1)

28-32: LGTM! Nanobind detection follows established pattern.

The nanobind detection logic correctly follows the same pattern used for mqt-core detection earlier in the file. It executes python -m nanobind --cmake_dir to locate the nanobind CMake configuration and uses find_package with the CONFIG mode, which is the recommended approach for nanobind.

bindings/bindings.cpp (1)

11-31: LGTM! Clean migration to nanobind module entry point.

The migration correctly replaces PYBIND11_MODULE with NB_MODULE, updates namespace aliases, and forward declarations match the signatures in the implementation files. The Cppcheck syntax error on line 26 is a false positive—it doesn't recognize the NB_MODULE macro.

Minor note: using namespace nb::literals; on line 16 is unused in this file since no _a argument literals appear here, but it's harmless and maintains consistency with other binding files.

bindings/CMakeLists.txt (1)

30-39: LGTM! Correct CMake updates for nanobind migration.

The binding activation function is correctly renamed to add_mqt_python_binding_nanobind, and pybind11_json is appropriately removed from LINK_LIBS since nanobind handles JSON conversion differently (via Python's json module as seen in the binding implementations).

CMakeLists.txt (2)

10-10: LGTM! CMake version bump is appropriate.

Bumping the upper bound to 4.2 ensures compatibility with newer CMake features needed for the nanobind migration.


40-41: LGTM! Proper Stable ABI component configuration.

The consolidated find_package(Python ...) call correctly includes ${SKBUILD_SABI_COMPONENT}, which enables the Stable ABI support that's a key objective of this PR for shipping stable ABI wheels.

bindings/state_type.cpp (1)

17-28: LGTM! Clean enum binding migration to nanobind.

The StateType enum binding correctly uses nb::enum_<StateType> with nb::is_arithmetic() trait, which is the proper nanobind equivalent of the pybind11 pattern. The enum value mappings are preserved, and the removal of finalize() is correct for nanobind.

bindings/application_scheme.cpp (1)

17-36: LGTM! Proper enum binding with inline docstring.

The ApplicationSchemeType enum binding correctly migrates to nanobind with nb::is_arithmetic(). The inline docstring for gate_cost (lines 29-34) follows the nanobind pattern where docstrings are added directly in the C++ binding code rather than in separate stub files. Based on learnings, this is the preferred approach after nanobind migration.

bindings/equivalence_criterion.cpp (1)

17-33: LGTM! Clean enum binding migration.

The EquivalenceCriterion enum binding correctly uses nb::enum_<EquivalenceCriterion> with nb::is_arithmetic() and properly maps all enum values including equivalent_up_to_phase and equivalent_up_to_global_phase.

bindings/equivalence_checking_manager.cpp (5)

16-24: LGTM! Proper nanobind includes and setup.

The includes are appropriate for the bindings: nanobind.h for core functionality, stl/string.h and stl/string_view.h for automatic string type conversions. The NOLINT(misc-include-cleaner) comments correctly suppress false positives since these headers are needed for implicit conversions.


35-37: LGTM! Constructor binding correctly migrated.

The nb::init<...> correctly replaces py::init<...> with the same parameter types and default argument handling.


44-48: LGTM! Configuration property correctly migrated.

The def_prop_rw with custom getter and setter is the correct nanobind replacement for def_property. The setter pattern using manager.getConfiguration() = config is appropriate.


73-98: LGTM! Results bindings with proper JSON handling.

The Results class bindings are correctly migrated:

  • nb::init<>() replaces py::init<>()
  • def_rw replaces def_readwrite for all member fields
  • The checker_results property uses def_prop_rw with custom getter/setter that routes through Python's json module, which is the appropriate approach without pybind11_json

The JSON serialization/deserialization via nb::module_::import_("json") and json.dumps/nlohmann::json::parse is a clean solution.


101-104: LGTM! JSON method binding.

The json() method correctly returns the result via nb::cast(results.json()), which handles the nlohmann::json to Python dict conversion.

bindings/configuration.cpp (2)

13-22: Migration to nanobind looks correct.

The header includes, namespace aliases, and function signature have been properly migrated from pybind11 to nanobind. The addition of const to the module parameter is a good improvement.


39-48: The Configuration class bindings are correctly implemented and already properly documented.

The code at lines 39-48 correctly uses nanobind syntax (nb::init, def_rw, nb::cast), and the json() method is fully documented in the .pyi stub file (python/mqt/qcec/pyqcec.pyi) with the docstring "Returns a JSON-style dictionary of the configuration." No additional documentation in the C++ binding code is needed, as qcec maintains all API documentation in the generated stub files rather than in C++ binding code.

Likely an incorrect or invalid review comment.

@denialhaag denialhaag requested a review from burgholzer January 9, 2026 17:44
@burgholzer burgholzer added the minor Part of a minor release label Jan 9, 2026
Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

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

This looks great to me.
The one suggestion from the rabbit seems to make sense. The other one is a false positive.
Thanks for the quick turnaround here! 🙏🏼

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bindings/equivalence_checking_manager.cpp (1)

46-50: Add rv_policy::reference_internal for consistency and safety.

The configuration property returns a reference to internal state but doesn't specify an explicit return value policy. For consistency with qc1/qc2 (lines 40-43) and to ensure proper lifetime management, add nb::rv_policy::reference_internal to the getter.

🔒 Suggested fix
 ecm.def_prop_rw(
-    "configuration", &EquivalenceCheckingManager::getConfiguration,
+    "configuration", &EquivalenceCheckingManager::getConfiguration,
+    nb::rv_policy::reference_internal,
     [](EquivalenceCheckingManager& manager, const Configuration& config) {
       manager.getConfiguration() = config;
     });
🤖 Fix all issues with AI agents
In @bindings/equivalence_checking_manager.cpp:
- Line 56: The results property returns an internal reference and must keep the
parent alive while Python holds it; update the binding call for
EquivalenceCheckingManager::getResults to use nanobind's reference-internal
policy by changing ecm.def_prop_ro("results",
&EquivalenceCheckingManager::getResults) to ecm.def_prop_ro("results",
nb::rv_policy::reference_internal, &EquivalenceCheckingManager::getResults) so
Python references keep the manager alive.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dbe593a and 5c3db8b.

📒 Files selected for processing (1)
  • bindings/equivalence_checking_manager.cpp
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qcec PR: 817
File: pyproject.toml:81-82
Timestamp: 2026-01-09T17:58:05.212Z
Learning: In the Munich Quantum Toolkit projects using nanobind, setting `wheel.py-api = "cp312"` in `[tool.scikit-build]` enables Stable ABI wheels only for Python 3.12+ (where nanobind supports it), while automatically building regular non-ABI3 wheels for earlier Python versions (3.10, 3.11) and free-threading builds (3.14t). This allows a single configuration to appropriately handle both old and new Python versions without forcing incompatible ABI requirements.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.
📚 Learning: 2025-12-15T01:54:22.129Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.

Applied to files:

  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-22T01:25:21.609Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.

Applied to files:

  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-19T00:05:54.428Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.

Applied to files:

  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-21T22:35:08.572Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:348-364
Timestamp: 2025-12-21T22:35:08.572Z
Learning: In the munich-quantum-toolkit/core repository's nanobind bindings, use `.sig("...")` on parameter arguments that have vector or container defaults (e.g., `"sites"_a.sig("...") = std::vector<fomac::Session::Device::Site>{}`) to prevent exposing mutable defaults in the Python API, which would be flagged as a code smell by Python linters. This pattern is preferred over removing `.sig("...")` even though it shows `...` in the stub signature.

Applied to files:

  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-07T01:21:27.544Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.

Applied to files:

  • bindings/equivalence_checking_manager.cpp
🧬 Code graph analysis (1)
bindings/equivalence_checking_manager.cpp (2)
src/Configuration.cpp (2)
  • json (58-107)
  • json (58-58)
src/EquivalenceCheckingManager.cpp (2)
  • json (884-901)
  • json (884-884)
🪛 Cppcheck (2.19.0)
bindings/equivalence_checking_manager.cpp

[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 20-20: Include file

(missingInclude)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingInclude)


[information] 22-22: Include file

(missingInclude)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 27-27: Include file

(missingIncludeSystem)


[information] 28-28: Include file

(missingIncludeSystem)


[information] 29-29: Include file

(missingIncludeSystem)


[information] 30-30: Include file

(missingIncludeSystem)


[information] 31-31: Include file

(missingIncludeSystem)


[information] 32-32: Include file

(missingIncludeSystem)


[information] 33-33: Include file

(missingIncludeSystem)


[information] 34-34: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[style] 27-27: The function 'registerEquivalenceCheckingManager' is never used.

(unusedFunction)


[style] 27-27: The function 'waitAndPop' is never used.

(unusedFunction)


[style] 34-34: The function 'waitAndPopUntil' is never used.

(unusedFunction)


[style] 37-37: The function 'getEquivalence' is never used.

(unusedFunction)


[style] 40-40: The function 'getRuntime' is never used.

(unusedFunction)


[style] 45-45: The function 'isDone' is never used.

(unusedFunction)


[style] 37-37: The function 'getInitialState' is never used.

(unusedFunction)


[style] 41-41: The function 'getInternalState1' is never used.

(unusedFunction)


[style] 46-46: The function 'getInternalState2' is never used.

(unusedFunction)


[style] 80-80: The function 'reset' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: 🇨‌ Coverage / 📈 Coverage
  • GitHub Check: 🐍 Test (windows-2022) / 🐍 windows-2022
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04-arm, gcc, Release) / 🐧 ubuntu-24.04-arm gcc Release
  • GitHub Check: 🐍 Test (ubuntu-24.04) / 🐍 ubuntu-24.04
  • GitHub Check: 🐍 Test (macos-14) / 🐍 macos-14
  • GitHub Check: 🐍 Test (macos-15-intel) / 🐍 macos-15-intel
  • GitHub Check: 🐍 Test (ubuntu-24.04-arm) / 🐍 ubuntu-24.04-arm
  • GitHub Check: 🇨‌ Test 🍎 (macos-15-intel, clang, Release) / 🍎 macos-15-intel clang Release
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Debug) / 🐧 ubuntu-24.04 gcc Debug
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Release) / 🐧 ubuntu-24.04 gcc Release
  • GitHub Check: 🇨‌ Test 🏁 (windows-11-arm, msvc, Release) / 🏁 windows-11-arm msvc Release
  • GitHub Check: 🇨‌ Test 🍎 (macos-14, clang, Debug) / 🍎 macos-14 clang Debug
  • GitHub Check: 🇨‌ Test 🏁 (windows-2022, msvc, Release) / 🏁 windows-2022 msvc Release
  • GitHub Check: 🇨‌ Test 🍎 (macos-14, clang, Release) / 🍎 macos-14 clang Release
  • GitHub Check: 🇨‌ Test 🏁 (windows-2022, msvc, Debug) / 🏁 windows-2022 msvc Debug
  • GitHub Check: 🇨‌ Lint / 🚨 Lint
🔇 Additional comments (4)
bindings/equivalence_checking_manager.cpp (4)

16-24: LGTM! Clean migration to nanobind headers and namespace.

The include changes and namespace alias correctly reflect the migration from pybind11 to nanobind. The STL converters for string types are appropriately included.


27-37: LGTM! Class and constructor bindings correctly migrated.

The function signature appropriately adds const to the module parameter, and the class/constructor bindings follow nanobind conventions.


40-43: Excellent! Correct lifetime management with rv_policy::reference_internal.

The addition of nb::rv_policy::reference_internal correctly ensures the parent EquivalenceCheckingManager remains alive while Python holds references to the internal circuits. This follows nanobind best practices for binding methods that return references to internal state.

Based on learnings, this is the correct pattern to replace pybind11's keep_alive mechanism.


89-100: Consider optimizing the setter's repeated json module import.

The setter (lines 94-99) imports the json module on every call to convert the dict to nlohmann::json, which is inefficient. Moving the import outside the lambda or using an alternative approach would avoid this overhead.

However, the suggestion to replace the json round-trip with direct casting—nb::cast<nlohmann::json>(value)—requires verification. The getter's direct cast works because it's converting an already-constructed nlohmann::json object to Python. Converting from a Python dict to nlohmann::json may not be supported without explicit nanobind JSON binding support (the build includes no nanobind JSON converter headers).

Consider either:

  1. Caching the json module reference outside the lambda
  2. Verifying if nanobind supports direct nb::cast<nlohmann::json>() for Python dicts
  3. Using nlohmann::json's direct Python interop if available

@burgholzer
Copy link
Member

@denialhaag code rabbit also had an out-of-diff comment above, that probably makes sense to address.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @python/mqt/qcec/_compat/optional.py:
- Line 107: The message string assigned to msg (used by the OptionalRequirement
class) contains a trailing period which causes a double period when require_now
appends one; remove the trailing period from the msg value (so e.g. change
"Please install the `mqt.qcec[qiskit]` extra or a compatible version of Qiskit."
to not end with a dot) so that require_now()'s concatenation produces a single
period; update the msg constant referenced by require_now/self._msg accordingly.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c3db8b and dbd9db8.

📒 Files selected for processing (3)
  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
  • python/mqt/qcec/_compat/optional.py
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qcec PR: 817
File: pyproject.toml:81-82
Timestamp: 2026-01-09T17:58:05.212Z
Learning: In the Munich Quantum Toolkit projects using nanobind, setting `wheel.py-api = "cp312"` in `[tool.scikit-build]` enables Stable ABI wheels only for Python 3.12+ (where nanobind supports it), while automatically building regular non-ABI3 wheels for earlier Python versions (3.10, 3.11) and free-threading builds (3.14t). This allows a single configuration to appropriately handle both old and new Python versions without forcing incompatible ABI requirements.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.
📚 Learning: 2025-12-15T01:54:22.129Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.

Applied to files:

  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-19T00:05:54.428Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.

Applied to files:

  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-22T01:25:21.609Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.

Applied to files:

  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-07T01:21:27.544Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.

Applied to files:

  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-21T22:35:08.572Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:348-364
Timestamp: 2025-12-21T22:35:08.572Z
Learning: In the munich-quantum-toolkit/core repository's nanobind bindings, use `.sig("...")` on parameter arguments that have vector or container defaults (e.g., `"sites"_a.sig("...") = std::vector<fomac::Session::Device::Site>{}`) to prevent exposing mutable defaults in the Python API, which would be flagged as a code smell by Python linters. This pattern is preferred over removing `.sig("...")` even though it shows `...` in the stub signature.

Applied to files:

  • bindings/configuration.cpp
  • bindings/equivalence_checking_manager.cpp
📚 Learning: 2025-12-15T01:59:17.023Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: python/mqt/core/ir/operations.pyi:9-16
Timestamp: 2025-12-15T01:59:17.023Z
Learning: In the munich-quantum-toolkit/core repository, stub files (.pyi) are auto-generated by nanobind's stubgen tool and should not be manually modified for style preferences, as changes would be overwritten during regeneration.

Applied to files:

  • bindings/configuration.cpp
📚 Learning: 2025-11-04T14:26:25.420Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:11-19
Timestamp: 2025-11-04T14:26:25.420Z
Learning: In the munich-quantum-toolkit/core repository, Qiskit is always available as a dependency during testing, so import guards for qiskit-dependent imports in test files (e.g., test/python/qdmi/qiskit/*.py) are not necessary.

Applied to files:

  • python/mqt/qcec/_compat/optional.py
📚 Learning: 2025-11-24T10:19:41.147Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1326
File: python/mqt/core/__init__.py:22-22
Timestamp: 2025-11-24T10:19:41.147Z
Learning: In the munich-quantum-toolkit/core repository, Ruff is configured with 'ALL' rules enabled by default, and only specific rules are selectively disabled. When reviewing changes that enable previously-disabled rules (like PLC0415), noqa directives for those rules become necessary and should be retained.

Applied to files:

  • bindings/equivalence_checking_manager.cpp
🧬 Code graph analysis (1)
bindings/configuration.cpp (1)
src/Configuration.cpp (4)
  • json (58-107)
  • json (58-58)
  • toString (109-112)
  • toString (109-109)
🪛 Cppcheck (2.19.0)
bindings/configuration.cpp

[information] 13-13: Include file

(missingInclude)


[information] 14-14: Include file

(missingInclude)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingInclude)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[information] 15-15: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 13-13: Include file

(missingIncludeSystem)


[information] 14-14: Include file

(missingIncludeSystem)


[style] 22-22: The function 'registerConfiguration' is never used.

(unusedFunction)


[style] 39-39: The function 'reset' is never used.

(unusedFunction)


[style] 48-48: The function 'getInternalState' is never used.

(unusedFunction)


[style] 51-51: The function 'setInternalState' is never used.

(unusedFunction)


[style] 52-52: The function 'flipDirection' is never used.

(unusedFunction)


[style] 71-71: The function 'getIterator' is never used.

(unusedFunction)


[style] 75-75: The function 'advanceIterator' is never used.

(unusedFunction)

bindings/equivalence_checking_manager.cpp

[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 17-17: Include file

(missingInclude)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[information] 20-20: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingInclude)


[information] 19-19: Include file

(missingInclude)


[information] 20-20: Include file

(missingInclude)


[information] 22-22: Include file

(missingIncludeSystem)


[information] 23-23: Include file

(missingIncludeSystem)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingInclude)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 21-21: Include file

(missingInclude)


[information] 22-22: Include file

(missingInclude)


[information] 24-24: Include file

(missingIncludeSystem)


[information] 25-25: Include file

(missingIncludeSystem)


[information] 26-26: Include file

(missingIncludeSystem)


[information] 27-27: Include file

(missingIncludeSystem)


[information] 28-28: Include file

(missingIncludeSystem)


[information] 29-29: Include file

(missingIncludeSystem)


[information] 30-30: Include file

(missingIncludeSystem)


[information] 31-31: Include file

(missingIncludeSystem)


[information] 32-32: Include file

(missingIncludeSystem)


[information] 33-33: Include file

(missingIncludeSystem)


[information] 34-34: Include file

(missingIncludeSystem)


[information] 16-16: Include file

(missingIncludeSystem)


[information] 17-17: Include file

(missingIncludeSystem)


[information] 18-18: Include file

(missingIncludeSystem)


[information] 19-19: Include file

(missingIncludeSystem)


[style] 27-27: The function 'registerEquivalenceCheckingManager' is never used.

(unusedFunction)


[style] 27-27: The function 'waitAndPop' is never used.

(unusedFunction)


[style] 34-34: The function 'waitAndPopUntil' is never used.

(unusedFunction)


[style] 37-37: The function 'getEquivalence' is never used.

(unusedFunction)


[style] 40-40: The function 'getRuntime' is never used.

(unusedFunction)


[style] 45-45: The function 'isDone' is never used.

(unusedFunction)


[style] 37-37: The function 'getInitialState' is never used.

(unusedFunction)


[style] 41-41: The function 'getInternalState1' is never used.

(unusedFunction)


[style] 46-46: The function 'getInternalState2' is never used.

(unusedFunction)


[style] 51-51: The function 'setInternalState' is never used.

(unusedFunction)


[style] 52-52: The function 'flipDirection' is never used.

(unusedFunction)


[style] 80-80: The function 'reset' is never used.

(unusedFunction)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: 🐍 Test (ubuntu-24.04) / 🐍 ubuntu-24.04
  • GitHub Check: 🐍 Test (ubuntu-24.04-arm) / 🐍 ubuntu-24.04-arm
  • GitHub Check: 🇨‌ Test 🍎 (macos-15-intel, clang, Release) / 🍎 macos-15-intel clang Release
  • GitHub Check: 🐍 Test (windows-2022) / 🐍 windows-2022
  • GitHub Check: 🐍 Test (macos-14) / 🐍 macos-14
  • GitHub Check: 🐍 Test (macos-15-intel) / 🐍 macos-15-intel
  • GitHub Check: 🇨‌ Test 🏁 (windows-2022, msvc, Release) / 🏁 windows-2022 msvc Release
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Debug) / 🐧 ubuntu-24.04 gcc Debug
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Release) / 🐧 ubuntu-24.04 gcc Release
  • GitHub Check: 🇨‌ Test 🏁 (windows-2022, msvc, Debug) / 🏁 windows-2022 msvc Debug
  • GitHub Check: 🇨‌ Test 🍎 (macos-14, clang, Release) / 🍎 macos-14 clang Release
  • GitHub Check: 🇨‌ Test 🍎 (macos-14, clang, Debug) / 🍎 macos-14 clang Debug
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04-arm, gcc, Release) / 🐧 ubuntu-24.04-arm gcc Release
  • GitHub Check: 🇨‌ Coverage / 📈 Coverage
  • GitHub Check: 🇨‌ Test 🏁 (windows-11-arm, msvc, Release) / 🏁 windows-11-arm msvc Release
  • GitHub Check: 🇨‌ Lint / 🚨 Lint
🔇 Additional comments (8)
bindings/configuration.cpp (4)

13-19: LGTM!

The nanobind includes and namespace setup are correct. The NOLINT(misc-include-cleaner) annotation is appropriate for the STL binding header which is needed for implicit string conversions but not directly referenced.


22-36: LGTM!

The function signature and class definitions are correctly migrated to nanobind. Using nb::module_& (with trailing underscore) is the correct nanobind convention for module references.


39-52: LGTM!

The Configuration binding is correctly migrated:

  • def_rw replaces def_readwrite for member access.
  • The json method lambda correctly converts the C++ nlohmann::json to a Python dict via json.loads(), which is the appropriate approach after removing pybind11_json.

55-117: LGTM!

All nested class bindings (Execution, Optimizations, Application, Functionality, Simulation, Parameterized) are correctly migrated to nanobind with nb::init<>() constructors and def_rw for member bindings.

bindings/equivalence_checking_manager.cpp (4)

16-24: LGTM!

The nanobind includes and namespace setup are correctly configured. Including <string> explicitly is good practice for the nb::cast<std::string> call used later in the file.


40-51: LGTM!

The property bindings correctly use nb::rv_policy::reference_internal for qc1, qc2, and configuration. This is the correct nanobind pattern for returning references to internal state, ensuring the parent object stays alive while these references exist. Based on learnings, this replaces pybind11's keep_alive mechanism.


91-104: LGTM!

The checker_results property correctly implements bidirectional JSON conversion between C++ nlohmann::json and Python dict using the Python json module. The getter uses json.loads() on the dumped string, and the setter uses json.dumps() followed by nlohmann::json::parse().


77-117: LGTM!

The Results class bindings are correctly migrated:

  • def_rw for simple member bindings.
  • def_prop_rw with lambdas for the JSON-based checker_results.
  • The json method lambda follows the same pattern as in configuration.cpp for consistency.

@denialhaag
Copy link
Member Author

@denialhaag code rabbit also had an out-of-diff comment above, that probably makes sense to address.

Done!

@denialhaag denialhaag merged commit e9ad020 into main Jan 9, 2026
31 of 32 checks passed
@denialhaag denialhaag deleted the nanobind branch January 9, 2026 18:59
@github-project-automation github-project-automation bot moved this from In Progress to Done in MQT Verification Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Anything related to C++ code minor Part of a minor release packaging Anything related to Python packaging python Anything related to Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants