Skip to content

Commit

Permalink
Avoid exporting incorrect PyInit_* symbols (#12889)
Browse files Browse the repository at this point in the history
Using the `#[pymodule]` derive macro in PyO3 0.21 always causes a
`PyInit_*` symbol with a matching name to be exported in the output
`cdylib`.  This is required for the top-level module, in order for
Python to import it---it needs to know which symbol in a shared library
file it should call---but submodules must be manually initialised, so do
not need it.  Including it is typically harmless (and something we've
been doing for a long time), but it is technically against the coding
rules for CPython extensions[^1].

Recent versions of `abi3audit` (0.0.11+) have tightened their symbol
checkers to better match the CPython guidelines, which causes our wheels
to be rejected by their audits.  This is, in theory, not a break of abi3
because CPython could never introduce an API-elvel `PyInit_*` function
themselves without causing problems, so there ought to be no problems
for our users, even with future Python versions. That said, we still
want to pass the audit, because the coding guidelines are useful.

This commit is not the cleanest way of doing things.  PyO3 0.22 includes
a `#[pymodule(submodule)]` option on the attribute macro, which lets us
use all the standard code generation while suppressing the unnecessary
`PyInit_*` symbol.  When we are ready to move to PyO3 0.22, we probably
want to revert this commit to switch to that form.

[^1]: https://docs.python.org/3/c-api/intro.html

(cherry picked from commit 120b73d)

# Conflicts:
#	crates/accelerate/src/target_transpiler/mod.rs
#	crates/pyext/src/lib.rs
  • Loading branch information
jakelishman authored and mergify[bot] committed Aug 2, 2024
1 parent ded5957 commit 818c785
Show file tree
Hide file tree
Showing 27 changed files with 1,313 additions and 31 deletions.
1 change: 0 additions & 1 deletion crates/accelerate/src/convert_2q_block_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ pub fn collect_2q_blocks_filter(node: &Bound<PyAny>) -> Option<bool> {
}
}

#[pymodule]
pub fn convert_2q_block_matrix(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(blocks_to_matrix))?;
m.add_wrapped(wrap_pyfunction!(collect_2q_blocks_filter))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/dense_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ pub fn best_subset_inner(
[rows, cols, best_map]
}

#[pymodule]
pub fn dense_layout(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(best_subset))?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/error_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ impl ErrorMap {
}
}

#[pymodule]
pub fn error_map(m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<ErrorMap>()?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/euler_one_qubit_decomposer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,6 @@ pub fn collect_1q_runs_filter(node: &Bound<PyAny>) -> bool {
}
}

#[pymodule]
pub fn euler_one_qubit_decomposer(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(params_zyz))?;
m.add_wrapped(wrap_pyfunction!(params_xyx))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/isometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ fn b(k: usize, s: usize) -> usize {
k - (a(k, s) * 2_usize.pow(s as u32))
}

#[pymodule]
pub fn isometry(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(diag_is_identity_up_to_global_phase))?;
m.add_wrapped(wrap_pyfunction!(find_squs_for_disentangling))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/nlayout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ impl NLayout {
}
}

#[pymodule]
pub fn nlayout(m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<NLayout>()?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/optimize_1q_gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ pub fn compose_u3_rust(
out_angles
}

#[pymodule]
pub fn optimize_1q_gates(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(compose_u3_rust))?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/pauli_exp_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ pub fn density_expval_pauli_with_x(
}
}

#[pymodule]
pub fn pauli_expval(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(expval_pauli_no_x))?;
m.add_wrapped(wrap_pyfunction!(expval_pauli_with_x))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/results/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub mod marginalization;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pymodule]
pub fn results(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(marginalization::marginal_counts))?;
m.add_wrapped(wrap_pyfunction!(marginalization::marginal_distribution))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/sabre/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ impl BlockResult {
}
}

#[pymodule]
pub fn sabre(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(route::sabre_routing))?;
m.add_wrapped(wrap_pyfunction!(layout::sabre_layout_and_routing))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/sampled_exp_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ pub fn sampled_expval_complex(
Ok(out.re)
}

#[pymodule]
pub fn sampled_exp_val(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sampled_expval_float))?;
m.add_wrapped(wrap_pyfunction!(sampled_expval_complex))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/sparse_pauli_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,6 @@ impl_to_matrix_sparse!(
u64
);

#[pymodule]
pub fn sparse_pauli_op(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(unordered_unique))?;
m.add_wrapped(wrap_pyfunction!(decompose_dense))?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/star_prerouting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ fn apply_swap(
}
}

#[pymodule]
pub fn star_prerouting(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(star_preroute))?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/stochastic_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ pub fn swap_trials(
Ok((best_edges, best_layout, best_depth))
}

#[pymodule]
pub fn stochastic_swap(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(swap_trials))?;
m.add_class::<EdgeCollection>()?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/synthesis/clifford/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ fn synth_clifford_bm(py: Python, clifford: PyReadonlyArray2<bool>) -> PyResult<C
CircuitData::from_standard_gates(py, num_qubits as u32, clifford_gates, Param::Float(0.0))
}

#[pymodule]
pub fn clifford(m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(synth_clifford_greedy, m)?)?;
m.add_function(wrap_pyfunction!(synth_clifford_bm, m)?)?;
Expand Down
1 change: 0 additions & 1 deletion crates/accelerate/src/synthesis/linear/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ fn check_invertible_binary_matrix(py: Python, mat: PyReadonlyArray2<bool>) -> Py
Ok(out.to_object(py))
}

#[pymodule]
pub fn linear(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(gauss_elimination_with_perm))?;
m.add_wrapped(wrap_pyfunction!(gauss_elimination))?;
Expand Down
17 changes: 12 additions & 5 deletions crates/accelerate/src/synthesis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@ pub mod linear;
mod permutation;

use pyo3::prelude::*;
use pyo3::wrap_pymodule;

#[pymodule]
pub fn synthesis(m: &Bound<PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(linear::linear))?;
m.add_wrapped(wrap_pymodule!(permutation::permutation))?;
m.add_wrapped(wrap_pymodule!(clifford::clifford))?;
let linear_mod = PyModule::new_bound(m.py(), "linear")?;
linear::linear(&linear_mod)?;
m.add_submodule(&linear_mod)?;

let permutation_mod = PyModule::new_bound(m.py(), "permutation")?;
permutation::permutation(&permutation_mod)?;
m.add_submodule(&permutation_mod)?;

let clifford_mod = PyModule::new_bound(m.py(), "clifford")?;
clifford::clifford(&clifford_mod)?;
m.add_submodule(&clifford_mod)?;

Ok(())
}
1 change: 0 additions & 1 deletion crates/accelerate/src/synthesis/permutation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ pub fn _synth_permutation_depth_lnn_kms(
)
}

#[pymodule]
pub fn permutation(m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(_validate_permutation, m)?)?;
m.add_function(wrap_pyfunction!(_inverse_pattern, m)?)?;
Expand Down
Loading

0 comments on commit 818c785

Please sign in to comment.