Skip to content

Commit e76b22d

Browse files
authored
♻️ Auto-generate stub files (#916)
## Description After we have switched from `pybind11` to `nanobind` in #911, we can now auto-generate the stub files. This PR defines a corresponding `nox` session and copies over all existing docstrings to the bindings code. ## Checklist: - [x] The pull request only contains commits that are focused and relevant to this change. - [x] ~I have added appropriate tests that cover the new/changed functionality.~ - [x] ~I have updated the documentation to reflect these changes.~ - [x] I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals. - [x] ~I have added migration instructions to the upgrade guide (if needed).~ - [x] The changes follow the project's style guidelines and introduce no new warnings. - [x] The changes are fully tested and pass the CI checks. - [x] I have reviewed my own code changes.
1 parent 8720e0d commit e76b22d

29 files changed

Lines changed: 1702 additions & 844 deletions

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,10 @@ jobs:
209209
if: fromJSON(needs.change-detection.outputs.run-python-tests)
210210
uses: munich-quantum-toolkit/workflows/.github/workflows/reusable-python-linter.yml@d6314c45667c131055a0389afc110e8dedc6da3f # v1.17.11
211211
with:
212-
setup-z3: true
213-
enable-ty: true
212+
check-stubs: true
214213
enable-mypy: false
214+
enable-ty: true
215+
setup-z3: true
215216

216217
build-sdist:
217218
name: 🚀 CD

.license-tools-config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
".*\\.profile",
3838
"uv\\.lock",
3939
"py\\.typed",
40-
".*build.*"
40+
".*build.*",
41+
"qmap_patterns.txt"
4142
]
4243
}

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ _If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md#unreleased)._
1818
### Changed
1919

2020
- 🔧 Replace `mypy` with `ty` ([#912]) ([**@denialhaag**])
21-
- ♻️ Migrate Python bindings from `pybind11` to `nanobind` ([#911]) ([**@denialhaag**])
21+
- ♻️ Migrate Python bindings from `pybind11` to `nanobind` ([#911], [#916]) ([**@denialhaag**])
2222
- 📦️ Provide Stable ABI wheels for Python 3.12+ ([#911]) ([**@denialhaag**])
2323

2424
## [3.5.0] - 2025-12-16
@@ -188,6 +188,7 @@ _📚 Refer to the [GitHub Release Notes] for previous changelogs._
188188

189189
<!-- PR links -->
190190

191+
[#916]: https://github.com/munich-quantum-toolkit/qmap/pull/916
191192
[#912]: https://github.com/munich-quantum-toolkit/qmap/pull/912
192193
[#911]: https://github.com/munich-quantum-toolkit/qmap/pull/911
193194
[#902]: https://github.com/munich-quantum-toolkit/qmap/pull/902

UPGRADING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ This document describes breaking changes and how to upgrade. For a complete list
44

55
## [Unreleased]
66

7+
### Renamings
8+
9+
To comply with established guidelines for function and attribute names, this release includes the following renamings:
10+
11+
- `mqt.qmap.plugins.qiskit.sc.compile` has been renamed to `compile_`.
12+
- `mqt.qmap.sc.map` has been renamed to `map_`.
13+
- `mqt.qmap.sc.Configuration.include_WCNF` has been renamed to `include_wcnf`.
14+
- `mqt.qmap.sc.MappingResult.input` has been renamed to `input_`.
15+
716
### Stable ABI wheels
817

918
We are now providing Stable ABI wheels instead of separate version-specific wheels for Python 3.12+.

bindings/clifford_synthesis/clifford_synthesis.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
5050
.value("verbose", plog::Severity::verbose, "Show all information.");
5151

5252
// Configuration for the synthesis
53-
nb::class_<cs::Configuration>(
54-
m, "SynthesisConfiguration",
55-
"Configuration options for the MQT QMAP Clifford synthesis tool.")
53+
nb::class_<cs::Configuration>(m, "SynthesisConfiguration",
54+
"Class representing the configuration for the "
55+
"Clifford synthesis techniques.")
5656
.def(nb::init<>())
5757
.def_rw("initial_timestep_limit",
5858
&cs::Configuration::initialTimestepLimit,
@@ -68,20 +68,20 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
6868
"is known.")
6969
.def_rw(
7070
"use_maxsat", &cs::Configuration::useMaxSAT,
71-
"Use MaxSAT to solve the synthesis problem or to really on the "
72-
"binary search scheme for finding the optimum. Defaults to `false`.")
71+
"Use MaxSAT to solve the synthesis problem or to rely on the "
72+
"binary search scheme for finding the optimum. Defaults to `False`.")
7373
.def_rw("linear_search", &cs::Configuration::linearSearch,
74-
"Use liner search instead of binary search "
75-
"scheme for finding the optimum. Defaults to `false`.")
74+
"Use linear search instead of binary search "
75+
"scheme for finding the optimum. Defaults to `False`.")
7676
.def_rw("target_metric", &cs::Configuration::target,
7777
"Target metric for the Clifford synthesis. Defaults to `gates`.")
7878
.def_rw("use_symmetry_breaking", &cs::Configuration::useSymmetryBreaking,
7979
"Use symmetry breaking clauses to speed up the synthesis "
80-
"process. Defaults to `true`.")
80+
"process. Defaults to `True`.")
8181
.def_rw("dump_intermediate_results",
8282
&cs::Configuration::dumpIntermediateResults,
8383
"Dump intermediate results of the synthesis process. "
84-
"Defaults to `false`.")
84+
"Defaults to `False`.")
8585
.def_rw("intermediate_results_path",
8686
&cs::Configuration::intermediateResultsPath,
8787
"Path to the directory where intermediate results should "
@@ -98,15 +98,15 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
9898
&cs::Configuration::minimizeGatesAfterDepthOptimization,
9999
"Depth optimization might produce a circuit with more gates than "
100100
"necessary. This option enables an additional run of the synthesizer "
101-
"to minimize the overall number of gates. Defaults to `false`.")
101+
"to minimize the overall number of gates. Defaults to `False`.")
102102
.def_rw(
103103
"try_higher_gate_limit_for_two_qubit_gate_optimization",
104104
&cs::Configuration::tryHigherGateLimitForTwoQubitGateOptimization,
105105
"When optimizing two-qubit gates, the synthesizer might fail "
106106
"to find an optimal solution for a certain timestep limit, but there "
107107
"might be a better solution for some higher timestep limit. This "
108108
"option enables an additional run of the synthesizer with a higher "
109-
"gate limit. Defaults to `false`.")
109+
"gate limit. Defaults to `False`.")
110110
.def_rw("gate_limit_factor", &cs::Configuration::gateLimitFactor,
111111
"Factor by which the gate limit is increased when "
112112
"trying to find a better solution for the two-qubit "
@@ -116,11 +116,11 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
116116
"Two-qubit gate optimization might produce a circuit "
117117
"with more gates than necessary. This option enables "
118118
"an additional run of the synthesizer to minimize the "
119-
"overall number of gates. Defaults to `false`.")
119+
"overall number of gates. Defaults to `False`.")
120120
.def_rw("heuristic", &cs::Configuration::heuristic,
121121
"Use heuristic to synthesize the circuit. "
122122
"This method synthesizes shallow intermediate circuits "
123-
"and combines them. Defaults to `false`.")
123+
"and combines them. Defaults to `False`.")
124124
.def_rw("split_size", &cs::Configuration::splitSize,
125125
"Size of subcircuits used in heuristic. "
126126
"Defaults to `5`.")
@@ -130,9 +130,10 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
130130
.def(
131131
"json",
132132
[](const cs::Configuration& config) {
133-
const nb::module_ json = nb::module_::import_("json");
134-
const nb::object loads = json.attr("loads");
135-
return loads(config.json().dump());
133+
const auto json = nb::module_::import_("json");
134+
const auto loads = json.attr("loads");
135+
const auto dict = loads(config.json().dump());
136+
return nb::cast<nb::typed<nb::dict, nb::str, nb::any>>(dict);
136137
},
137138
"Returns a JSON-style dictionary of all the information present in "
138139
"the :class:`.Configuration`")
@@ -143,8 +144,9 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
143144
"present in the :class:`.Configuration`");
144145

145146
// Results of the synthesis
146-
nb::class_<cs::Results>(m, "SynthesisResults",
147-
"Results of the MQT QMAP Clifford synthesis tool.")
147+
nb::class_<cs::Results>(
148+
m, "SynthesisResults",
149+
"Class representing the results of the Clifford synthesis techniques.")
148150
.def(nb::init<>())
149151
.def_prop_ro("gates", &cs::Results::getGates,
150152
"Returns the number of gates in the circuit.")
@@ -166,12 +168,12 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
166168
"Returns a string representation of the "
167169
"synthesized circuit's tableau.")
168170
.def("sat", &cs::Results::sat,
169-
"Returns `true` if the synthesis was successful.")
171+
"Returns `True` if the synthesis was successful.")
170172
.def("unsat", &cs::Results::unsat,
171-
"Returns `true` if the synthesis was unsuccessful.");
173+
"Returns `True` if the synthesis was unsuccessful.");
172174

173175
auto tableau = nb::class_<cs::Tableau>(
174-
m, "Tableau", "A class for representing stabilizer tableaus.");
176+
m, "Tableau", "Class representing a Clifford tableau.");
175177
tableau.def(nb::init<std::size_t, bool>(), "n"_a,
176178
"include_destabilizers"_a = false,
177179
"Creates a tableau for an n-qubit Clifford.");
@@ -182,11 +184,12 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
182184
tableau.def(
183185
nb::init<const std::string&, const std::string&>(), "stabilizers"_a,
184186
"destabilizers"_a,
185-
"Constructs a tableau from two lists of Pauli strings, the Stabilizers"
186-
"and Destabilizers.");
187+
"Constructs a tableau from two lists of Pauli strings, the stabilizers "
188+
"and destabilizers.");
187189

188190
auto synthesizer = nb::class_<cs::CliffordSynthesizer>(
189-
m, "CliffordSynthesizer", "A class for synthesizing Clifford circuits.");
191+
m, "CliffordSynthesizer",
192+
"The main class for the Clifford synthesis techniques.");
190193

191194
synthesizer.def(nb::init<cs::Tableau, cs::Tableau>(), "initial_tableau"_a,
192195
"target_tableau"_a,
@@ -210,7 +213,11 @@ NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
210213
synthesizer.def_prop_ro("results", &cs::CliffordSynthesizer::getResults,
211214
nb::rv_policy::reference_internal,
212215
"Returns the results of the synthesis.");
213-
synthesizer.def_prop_ro("result_circuit", [](cs::CliffordSynthesizer& self) {
214-
return qasm3::Importer::imports(self.getResults().getResultCircuit());
215-
});
216+
synthesizer.def_prop_ro(
217+
"result_circuit",
218+
[](cs::CliffordSynthesizer& self) {
219+
return qasm3::Importer::imports(self.getResults().getResultCircuit());
220+
},
221+
"Returns the synthesized circuit as a "
222+
":class:`~mqt.core.ir.QuantumComputation` object.");
216223
}

bindings/na/CMakeLists.txt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,20 @@
66
#
77
# Licensed under the MIT License
88

9-
add_subdirectory(nasp)
10-
add_subdirectory(zoned)
9+
file(GLOB_RECURSE NA_SOURCES **.cpp)
10+
11+
add_mqt_python_binding_nanobind(
12+
QMAP
13+
${MQT_QMAP_TARGET_NAME}-na-bindings
14+
${NA_SOURCES}
15+
MODULE_NAME
16+
na
17+
INSTALL_DIR
18+
.
19+
LINK_LIBS
20+
MQT::NASP
21+
MQT::QMapNAZoned
22+
MQT::CoreQASM)
1123

1224
# Install the Python stub files in editable mode for better IDE support
1325
if(SKBUILD_STATE STREQUAL "editable")

bindings/na/na.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
3+
* Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH
4+
* All rights reserved.
5+
*
6+
* SPDX-License-Identifier: MIT
7+
*
8+
* Licensed under the MIT License
9+
*/
10+
11+
#include <nanobind/nanobind.h>
12+
13+
namespace nb = nanobind;
14+
15+
// forward declarations
16+
void registerStatePreparation(nb::module_& m);
17+
void registerZoned(nb::module_& m);
18+
19+
NB_MODULE(MQT_QMAP_MODULE_NAME, m) {
20+
auto statePreparation = m.def_submodule("state_preparation");
21+
registerStatePreparation(statePreparation);
22+
23+
auto zoned = m.def_submodule("zoned");
24+
registerZoned(zoned);
25+
}

bindings/na/nasp/CMakeLists.txt

Lines changed: 0 additions & 19 deletions
This file was deleted.

bindings/na/nasp/nasp.cpp

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)